Advertisement
roman_gemini

homefs.biz lores video maker

Jul 7th, 2014
196
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 7.60 KB | None | 0 0
  1. #!/usr/bin/perl
  2.  
  3. use FindBin qw($Bin);
  4. use DBI;
  5. use Term::ANSIColor;
  6. use threads;
  7. use threads::shared;
  8. use Digest::MD5 qw( md5_hex );
  9. use Time::HiRes qw( usleep );
  10. use JSON;
  11. use Date::Format;
  12.  
  13. use Data::Dumper;
  14.  
  15. chdir($Bin);
  16.  
  17. my $threads = 2;
  18.  
  19. select(STDERR);
  20. $| = 1;
  21. select(STDOUT); # default
  22. $| = 1;
  23.  
  24.  
  25. my @job_queue:shared = ();
  26. my $job_proc:shared = 0;
  27. my @status:shared = ();
  28.  
  29. my @bad:shared = ();
  30. my @processing:shared = ();
  31.  
  32. require "$Bin/Mediainfo.pm";
  33.  
  34. my $cache_locate = '/medib/JC/FLV';
  35. my $flvtool_string = '/usr/local/bin/flvtool++ -nodump';
  36. my $logfile = 'log/encoder.log';
  37.  
  38. my $encode_string_1 = "/usr/local/bin/ffmpeg -i <INFILE> <ID> -threads 1 -pass 1 -vcodec libx264 -preset fast -passlogfile log/log_<THREAD> -async 1 -b 320k -s <SIZE> -ab 128k -ar 44100 -ac 2 -keyint_min 240 -y -acodec libmp3lame -f flv /dev/null 2>&1 | awk '1;{fflush()}' RS='\r'";
  39. my $encode_string_2 = "/usr/local/bin/ffmpeg -i <INFILE> <ID> -threads 1 -pass 2 -vcodec libx264 -preset fast -passlogfile log/log_<THREAD> -async 1 -b 320k -s <SIZE> -ab 128k -ar 44100 -ac 2 -keyint_min 240 -y -acodec libmp3lame -f flv <OUTFILE> 2>&1 | awk '1;{fflush()}' RS='\r'";
  40.  
  41. for $y (1...$threads) {
  42.     push @threads, threads->create( \&proc_thread );
  43. }
  44.  
  45. push @threads, threads->create( \&status_thread );
  46. push @threads, threads->create( \&init_job );
  47.  
  48. foreach $thread(@threads) { $thread->join(); }
  49.  
  50. sub init_job {
  51.     while(1) {
  52.         $dbh = DBI->connect("dbi:mysql:search:localhost", "root", "");
  53.         $dbh->do("set names 'utf8'");
  54.         $qr = $dbh->prepare(
  55.            "SELECT a.* FROM search_files a
  56.             WHERE
  57.                 a.`filegroup` = 'video' AND
  58.                 a.`filetype` != 'flv' AND
  59.                 a.`encoded` != '1' AND
  60.                 NOT EXISTS(SELECT NULL FROM `jfs_lores_ban` b WHERE b.`md5` = a.`md5`)
  61.             GROUP BY `md5`
  62.             ORDER BY `filepath` ASC"
  63.         );
  64.         $qr->execute();
  65.         while($row = $qr->fetchrow_hashref) {
  66.             $filename = $row->{filepath} . '/' . $row->{filename};
  67.             $filehash = $row->{md5};
  68.             push(@job_queue, "${filehash};${filename}") unless(is_do($filehash));
  69.         }
  70.         $dbh->disconnect();
  71.         sleep(60);
  72.         wait_jobs();
  73.     }
  74. }
  75.  
  76. sub wait_jobs {
  77.     while(left() > 0) {
  78.         sleep 5;
  79.     }
  80. }
  81.  
  82. sub left {
  83.     return ($#job_queue+1);
  84. }
  85.  
  86. sub status_thread {
  87.     while(1) {
  88.         print "\xC";
  89.         printf("Encoder slots: (updated %s)\n\n", time2str('%d/%m/%y %T', time));
  90.         for $n(1...$#status) {
  91.             print " Slot $n: ", @status[$n], "\n";
  92.         }
  93.         print "\nJobs left: " . left() . "\n";
  94.         sleep(1);
  95.     }
  96. }
  97.  
  98. sub proc_thread {
  99.  
  100.     my $tid = threads->tid();
  101.  
  102.     while(1) {
  103.         unless($a = shift @job_queue) {
  104.             @status[$tid] = '[idle]';
  105.             sleep 5;
  106.             next;
  107.         }
  108.         my ($filehash, $filename) = split(";", $a, 2);
  109.  
  110.         @status[$tid] = (split("/", $filename))[-1];
  111.         @processing[$tid] = $filehash;
  112.  
  113.         $video = video_size($filename);
  114.         $aid = audio_index($filename);
  115.  
  116.         if($aid > -1) {
  117.             $map = "-map 0:v:0 -map 0:a:$aid";
  118.         } else {
  119.             $map = "";
  120.         }
  121.  
  122.         if ($video == 0) {
  123.             ban_it($filehash);
  124.             $job_proc --;
  125.             next;
  126.         };
  127.  
  128.         $esc_flvpath = esc_chars(flv_path($filehash));
  129.         $esc_flv = esc_chars(flv_path($filehash) . '/' . $filehash . '_tmp.flv');
  130.         $esc_flv2 = esc_chars(flv_path($filehash) . '/' . $filehash . '.flv');
  131.         $esc_file = esc_chars($filename);
  132.  
  133.         system("mkdir -p $esc_flvpath");
  134.  
  135.         %replacement = (
  136.                 '<INFILE>'  => $esc_file,
  137.                 '<OUTFILE>' => $esc_flv,
  138.                 '<SIZE>'    => $video,
  139.                 '<THREAD>'  => $tid,
  140.                 '<ID>'      => $map
  141.         );
  142.        
  143.         $runstring_1 = sub_replace( \%replacement, $encode_string_1 );
  144.         $runstring_2 = sub_replace( \%replacement, $encode_string_2 );
  145.        
  146.         # First pass
  147.         my $cent = "0.0";
  148.         my $dur = 0;
  149.         my $pos = 0;
  150.         open(FH, "${runstring_1}|");
  151.         while($line = <FH>) {
  152.             $line =~ s/\x0a//gm;
  153.             $dur = sub_time2sec($1) if($line =~ m/Duration: (.*?), start:/);
  154.             $pos = sub_time2sec($1) if($line =~ m/time=(.*?) bitrate/);
  155.             $cent = sprintf("%1.1f", (50 / $dur * $pos)) if($dur > 0);
  156.             @status[$tid] = (split("/", $filename))[-1] . " ($cent%)";
  157.         }
  158.         $ecode = close(FH);
  159.         unless($ecode) {
  160.             ban_it($filehash);
  161.             $job_proc --;
  162.             next;
  163.         }
  164.  
  165.         # Second pass
  166.         my $cent = "50.0";
  167.         open(FH, "${runstring_2}|");
  168.         while($line = <FH>) {
  169.             $line =~ s/\x0a//gm;
  170.             $dur = sub_time2sec($1) if($line =~ m/Duration: (.*?), start:/);
  171.             $pos = sub_time2sec($1) if($line =~ m/time=(.*?) bitrate/);
  172.             $cent = sprintf("%1.1f", 50 + (50 / $dur * $pos)) if($dur > 0);
  173.             @status[$tid] = (split("/", $filename))[-1] . " ($cent%)";
  174.         }
  175.         unless(close(FH)) {
  176.             ban_it($filehash);
  177.             $job_proc --;
  178.             next;
  179.         }
  180.  
  181.         $cent = "100";
  182.         system("$flvtool_string ${esc_flv} ${esc_flv2} >/dev/null && rm ${esc_flv}") ;
  183.  
  184.         @status[$tid] = (split("/", $filename))[-1] . " ($cent%)";
  185.         done_it($filehash, $filename);
  186.         log_encoder("DONE: file:$filename, audio:$aid, size:$video");
  187.  
  188.        
  189.         @processing[$tid] = '';
  190.         $job_proc --;
  191.     }
  192. }
  193.  
  194. sub logger {
  195.     open LG, ">>", "/tmp/encoder.log";
  196.     print LG shift;
  197.     close LG;
  198. }
  199.  
  200. sub ban_it {
  201.     my $md5 = shift;
  202.     $dbh = DBI->connect("dbi:mysql:search:localhost", "root", "") || die("Couldn't establish connection to mysql!");
  203.     $dbh->do(sprintf("INSERT IGNORE INTO `jfs_lores_ban` VALUES ('${md5}')"));
  204.     $dbh->disconnect();
  205. }
  206.  
  207. sub done_it {
  208.     my $filehash = shift;
  209.     my $filename = shift;
  210.     $dbh = DBI->connect("dbi:mysql:search:localhost", "root", "") || die("Couldn't establish connection to mysql!");
  211.     $dbh->do("set names 'utf8'");
  212.     $dbh->do("UPDATE search_files SET `encoded` = '1' WHERE `md5` = '$filehash'");
  213.     $dbh->do(sprintf("INSERT INTO `jfs_lores_log` (`filename`,`md5`) VALUES (%s,%s)",
  214.                 $dbh->quote((split('/',$filename))[-1]), $dbh->quote($filehash)));
  215.     $dbh->disconnect();
  216. }
  217.  
  218. sub is_bad {
  219.     my $test = shift;
  220.     foreach $hash ( @bad ) {
  221.         return 1 if($hash eq $test);
  222.     }
  223.     return 0;
  224. }
  225.  
  226. sub is_do {
  227.     my $test = shift;
  228.     foreach $hash ( @processing ) {
  229.         return 1 if($hash eq $test);
  230.     }
  231.     return 0;
  232. }
  233.  
  234.  
  235.  
  236. sub flv_path {
  237.     my $hash = shift;
  238.     return "$cache_locate/" . substr($hash, 0, 1) . "/" . substr($hash, 0, 2);
  239. }
  240.  
  241. sub video_size {
  242.     my $filename = shift;
  243.         my $media = new Mediainfo("filename" => $filename);
  244.  
  245.     if($media->{width} == 0 || $media->{height} == 0) { return 0; }
  246.  
  247.     my $asp = $media->{height} / $media->{width};
  248.         if($media->{width} > 512) {
  249.             return '512x' . (int(512 * $asp / 2) * 2);
  250.     } else {
  251.             return $media->{width} . 'x' . $media->{height};
  252.         }
  253. }
  254.  
  255. sub esc_chars {
  256.     my $file = shift;
  257.     $file =~ s/([\x22])/\\$1/g;
  258.     return "\"$file\"";
  259. }
  260.  
  261. sub audio_index {
  262.     my $file = esc_chars(shift);
  263.     my @langs = ('uk', 'ru', 'en');
  264.     my @media = `mediainfo -f $file`;
  265.     my $curr_id = -1;
  266.     my $lang = '';
  267.     foreach $line(@media) {
  268.         chomp $line;
  269.         if($line =~ /^Audio\s\#(\d+)$/) {
  270.             $curr_id = $1;
  271.         }
  272.         if($line =~ /^Audio$/) {
  273.             return -1;
  274.         }
  275.         if($line =~ /^Language/) {
  276.             $lang = (split(" : ", $line))[1];
  277.             foreach $l (@langs) {
  278.                 return $curr_id if($lang eq $l);
  279.             }
  280.         }
  281.     }
  282.     return -1;
  283. }
  284.  
  285. sub log_encoder {
  286.     my $str = shift;
  287.     open(LOG, ">>", $logfile);
  288.     print LOG timez();
  289.     print LOG ' ';
  290.     print LOG $str;
  291.     print LOG "\n";
  292.     close(LOG);
  293. }
  294.  
  295. sub timez {
  296.         ($sec, $min, $hour) = (localtime(time))[0..2];
  297.         return sprintf("%02d:%02d:%02d", $hour, $min, $sec);
  298. }
  299.  
  300. sub sub_replace {
  301.     my $replace = shift;
  302.     my $subject = shift;
  303.     foreach $key (keys %$replace) {
  304.         $meta = quotemeta($key);
  305.         $subject =~ s/$key/$replace->{$key}/g;
  306.     }
  307.     return $subject;
  308. }
  309.  
  310. sub sub_time2sec {
  311.     my @digs = split(':', shift());
  312.     if($#digs == 2) {
  313.         return abs($digs[0]) * 3600 + abs($digs[1]) * 60 + abs($digs[2]);
  314.     } else {
  315.         return 0;
  316.     }
  317. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement