#!/usr/bin/env php
<?php
require_once( 'Console/CommandLine.php' );
function 
get_console_parser() {
    
$parser = new Console_CommandLine(array(
        
'description' => 'This program downloads an flv from youtube and generates an mp3 from it.',
        
'version' => '0.0.1',
    ));
    
    
$parser->addOption(
        
'skip_curl',
        array(
            
'short_name'  => '-s',
            
'long_name'   => '--skip-curl',
            
'description' => 'More useful in testing. If you\'ve recently downloaded the youtube html page, this option will skip that and use the temp file from the last attempt.',
            
'action'      => 'StoreTrue',
        )
    );
    
    
$parser->addOption(
        
'output_file',
        array(
            
'short_name'  => '-o',
            
'long_name'   => '--output-file',
            
'description' => 'If you don\'t define an output file the script defaults to youtube\'s VIDEO_TITLE variable.  Do not add a file extension to this.',
            
'action'      => 'StoreString',
        )
    );
    
    
$parser->addOption(
        
'keep_flv',
        array(
            
'short_name'  => '-k',
            
'long_name'   => '--keep-flv',
            
'description' => 'Use this option if you want to keep the downloaded flv.',
            
'action'      => 'StoreTrue',
        )
    );
    
    
    
$parser->addArgument(
        
'youtube_url',
        array(
            
'description' => 'The youtube url, i.e. http://www.youtube.com/watch?v=R2dygXfmFIc',
            
'help_name' => 'URL',
        )
    );
    return 
$parser;
}

try {
    
$parser = get_console_parser();
    
$result = $parser->parse();
#    print_r( $result->options );
#    print_r( $result->args );
}
catch ( 
Exception $e ) {
    
$parser->displayError( $e->getMessage() );
    exit();
}
#exit(50);

#$GLOBALS['skip_curl'] = true;
#$GLOBALS['skip_curl'] = false;
$GLOBALS['skip_curl'] = $result->options['skip_curl'];

#$GLOBALS['url'] = 'http://www.youtube.com/watch?v=R2dygXfmFIc';
$GLOBALS['url'] = $result->args['youtube_url'];

$GLOBALS['cookie_file'] = dirname( __FILE__ ) . '/cookies.txt';
$GLOBALS['user_agent'] = 'Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.0.16) Gecko/2009121601 Ubuntu/9.04 (jaunty) Firefox/3.0.16';
$GLOBALS['tmp_file'] = dirname( __FILE__ ) . '/get-youtube.php.watch.html';

/*
http://v23.lscache6.c.youtube.com/videoplayback?ip=0.0.0.0&sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Calgorithm%2Cburst%2Cfactor%2Coc%3AU0dVTVRRUV9FSkNNNV9MS1VH&fexp=903913%2C906800&algorithm=throttle-factor&itag=34&ipbits=0&burst=40&sver=3&expire=1268463600&key=yt1&signature=B34245381748159860D82E93FA79D25D01223E42.8E545ED44903A7B1477E3D77BA6552945C458F97&factor=1.25&id=4767728177e61487&#/Caspa___The_Terminator_video.flv

http://v23.lscache6.c.youtube.com/videoplayback?ip=0.0.0.0&sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Calgorithm%2Cburst%2Cfactor%2Coc%3AU0dVTVRTT19FSkNNNV9MTVNH&fexp=900147&algorithm=throttle-factor&itag=34&ipbits=0&burst=40&sver=3&expire=1268481600&key=yt1&signature=CA5FC726E76896BC21EB0C69797531A1B786B121.654396F2C2B5A855503EC20BF59DDD13C8B0D493&factor=1.25&id=4767728177e61487,5
*/

function getfile( $url, $referer = '', $file = '' ) {
    
$ch = curl_init();
    
    
curl_setopt( $ch, CURLOPT_URL, $url );
    
    if ( 
$file ) {
        
$f = fopen( $file, 'w' );
        
curl_setopt( $ch, CURLOPT_FILE, $f );
    }
    else {
        
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
    }
    
    if ( 
$referer ) {
        
curl_setopt( $ch, CURLOPT_REFERER, $referer );
    }
    
    
curl_setopt( $ch, CURLOPT_COOKIEFILE, $GLOBALS['cookie_file'] );
    
curl_setopt( $ch, CURLOPT_COOKIEJAR,  $GLOBALS['cookie_file'] );
    
    
curl_setopt( $ch, CURLOPT_USERAGENT,  $GLOBALS['user_agent'] );
    
curl_setopt( $ch, CURLOPT_FILETIME, true );
    
    
$out = curl_exec( $ch );
    
    if ( 
$file ) {
        
$GLOBALS['server_filetime'] = curl_getinfo( $ch, CURLINFO_FILETIME );
#        echo '$server_filetime = ', $server_filetime, PHP_EOL;
        
if ( !touch( $file, $GLOBALS['server_filetime'] ) ) {
            echo 
'touch -t ', date( 'YmdHi.s', $GLOBALS['server_filetime'] ), ' ', $file, PHP_EOL;
        }
    }
    
    
curl_close( $ch );
    return 
$out;
}

// ********************************************************************

$GLOBALS['fix_flv_url']['file_pattern'] = array(
#    '@[ -\.]@g',
    
'@[ -\.\&]@',
    
'@[\[\]]@',
);
$GLOBALS['fix_flv_url']['file_replace'] = array(
    
'_',
    
'',
);
$GLOBALS['fix_flv_url']['url_pattern'] = array(
    
'@,[0-9A-Za-z]+$@',
);
$GLOBALS['fix_flv_url']['url_replace'] = array(
    
'&#/',
);
function 
fix_flv_url( $url, $title ) {
    
$file = preg_replace(
        
$GLOBALS['fix_flv_url']['file_pattern']
        ,
$GLOBALS['fix_flv_url']['file_replace']
        ,
$title
    
);
    
$file .= '_video.flv';
    
    
$url = preg_replace(
        
$GLOBALS['fix_flv_url']['url_pattern']
        ,
$GLOBALS['fix_flv_url']['url_replace']
        ,
$url
    
);
    
$out['file'] = $file;
    
$out['url' ] = $url . $file;
    
    return 
$out;
}

// ********************************************************************

if ( $skip_curl ) {
    echo 
'Skipping curl, getting html from ', $tmp_file, PHP_EOL;
    
$url_page = file_get_contents( $tmp_file );
}
else {
    echo 
'Downloading from ', $GLOBALS['url'], PHP_EOL;
    
$url_page = getfile( $GLOBALS['url'] );
    
file_put_contents( $GLOBALS['tmp_file'], $url_page );
}

$url_page = explode( "\n", $url_page );

$lines = preg_grep( '/["\'](SWF_ARGS|VIDEO_TITLE)["\']/', $url_page );

//    'VIDEO_TITLE': 'Caspa - The Terminator',
$title_pattern = '@.*["\']VIDEO_TITLE["\']:\s*["\']([^"\']+)["\'].*@';
$title_replace = '$1';
$pattern = '@.*"fmt_url_map": "([^"]+)".*@';
$replace = '$1';
foreach ( 
$lines as $line ) {
    
$line = trim( $line );
    if ( 
false !== strpos( $line, 'VIDEO_TITLE' ) ) {
        
$line = preg_replace( $title_pattern, $title_replace, $line );
        echo 
'$line = ', $line, PHP_EOL;
        
$title = $line;
    }
    else {
        
$line = preg_replace( $pattern, $replace, $line );
        
$line = urldecode( $line );
        
$a = explode( '|', $line );
        
$url = $a[1];
        echo 
'$url = ', $url, PHP_EOL;
    }
}

$rs = fix_flv_url( $url, $title );
echo 
'$rs[\'url\'] = ', $rs['url'], PHP_EOL;

if ( 
$result->options['output_file'] ) {
    
$t = trim( $result->options['output_file'] );
}
else {
    
$t = trim( $title );
    
$t = strtr( $t, ' ', '_' );
}
$file_flv = $t . '.flv';
$file_mp3 = $t . '.mp3';
echo 
'Grabbing flv from youtube.';
$success = getfile( $rs['url'], $GLOBALS['url'], $file_flv );
if ( !
$success ) {
    echo 
'There was an error downloading the flv.  It\'s possible that you may need to increase the amount of time curl needs to download the file.', PHP_EOL;
    echo 
'Failed downloading from: ', $rs['url'], PHP_EOL;
    exit(
5);
}
else if ( !
filesize( $file_flv ) ) {
    echo 
'There was an error downloading the flv. It could be that the URL I generated was incorrect.', PHP_EOL;
    echo 
'Failed downloading from: ', $rs['url'], PHP_EOL;
    exit(
404);
}

#ffmpeg -i video.flv -acodec mp2 -ac 2 -ab 128k -vn -y 'Caspa - The Terminator.mp3'
#ffmpeg -i "%s.flv" -acodec mp2 -ac 2 -ab 128k -vn -y "%s.mp3"
# libmp3lame

echo 'Preparing to run ffmpeg to generate the mp3, this may take a while.', PHP_EOL;
$cmd = 'ffmpeg -i %s -acodec libmp3lame -ac 2 -ab 128k -vn -y %s';
$cmd = sprintf(
    
$cmd
    
,escapeshellarg( $file_flv )
    ,
escapeshellarg( $file_mp3 )
);
echo 
$cmd, PHP_EOL;
passthru( $cmd );

if ( !
touch( $file_mp3, $GLOBALS['server_filetime'] ) ) {
    echo 
'touch -t ', date( 'YmdHi.s', $GLOBALS['server_filetime'] ), ' ', $file_mp3, PHP_EOL;
}

if ( !
$result->options['keep_flv'] ) {
    
unlink( $file_flv );
}