2016-04-08 85 views
-2

我的媒體服務器有兩個目錄:電影和電視節目。在每個目錄中,每個條目都存在一個包含視頻文件和字幕文件的子目錄中。使用ffmpeg遞歸地將媒體目錄從HEVC轉換爲h.264

我已經沖刷網頁,發現從米歇爾沙利文一個優秀的Perl腳本,張貼在這裏:

#!/usr/bin/perl 

use strict; 
use warnings; 

open DIR, "ls -1 |"; 
while (<DIR>) 
{ 
     chomp; 
     next if (-d "$_"); # skip directories 
     next unless (-r "$_"); # if it's not readable skip it! 
     my $file = $_; 
     open PROBE, "ffprobe -show_streams -of csv '$file' 2>/dev/null|" or die ("Unable to launch ffmpeg for $file! ($!)"); 
     my ($v, $a, $s, @c) = (0,0,0); 
     while (<PROBE>) 
     { 
       my @streaminfo = split(/,/, $_); 
       push(@c, $streaminfo[2]) if ($streaminfo[5] eq "video"); 
       $a++ if ($streaminfo[5] eq "audio"); 
       $s++ if ($streaminfo[5] eq "subtitle"); 
     } 
     close PROBE; 
     $v = scalar @c; 
     if (scalar @c eq 1 and $c[0] eq "ansi") 
     { 
       warn("Text file detected, skipping...\n"); 
       next; 
     } 
     warn("$file: Video Streams: $v, Audio Streams: $a, Subtitle Streams: $s, Video Codec(s): " . join (", ", @c) . "\n"); 
     if (scalar @c > 1) 
     { 
       warn("$file has more than one video stream, bailing!\n"); 
       next; 
     } 
     if ($c[0] eq "hevc") 
     { 
       warn("HEVC detected for $file ...converting to AVC...\n"); 
       system("mkdir -p h265"); 
       my @params = ("-hide_banner", "-threads 2"); 
       push(@params, "-map 0") if ($a > 1 or $s > 1 or $v > 1); 
       push(@params, "-c:a copy") if ($a); 
       push(@params, "-c:s copy") if ($s); 
       push(@params, "-c:v libx264 -pix_fmt yuv420p") if ($v); 
       if (system("mv '$file' 'h265/$file'")) 
       { 
         warn("Error moving $file -> h265/$file\n"); 
         next; 
       } 
       if (system("ffmpeg -xerror -i 'h265/$file' " . join(" ", @params) . " '$file' 2>/dev/null")) 
       { 
         warn("FFMPEG ERROR. Cannot convert $file restoring original...\n"); 
         system("mv 'h265/$file' '$file'"); 
         next; 
       } 
     } else { 
       warn("$file doesn't appear to need converting... Skipping...\n"); 
     } 
} 
close DIR; 

腳本執行完美的 - 只要是來自包含媒體的目錄中運行。

我的問題:該腳本可以修改爲從根目錄遞歸運行嗎?怎麼樣?

在此先感謝。

(米歇爾的腳本可以在這裏看到:http://www.michellesullivan.org/blog/1636

+0

http://perldoc.perl.org/File/Find.html你會把代碼放在上面的循環中作爲\所需的參數。 – skarface

+3

我不確定你在問什麼,而你展示的只是別人的代碼。你說你已經*在網上搜索*來找到這個Perl程序,而你現在似乎又在努力尋找免費的東西,而這些東西我估計你無法爲自己創造。堆棧溢出是被程序員阻止*特定問題*的地方,可以向同伴尋求幫助。這並不是說無知可以將他們的要求轉移到這裏並等待解決方案 – Borodin

回答

1

你爲什麼要遞歸運行?你的意思是你想在特定目錄下的所有文件上運行它?

在這個問題中,我寧願將產生文件列表的部分從處理中分離出來。隨着文件的一個長長的清單,我可能會從,而不是標準輸入行:

while(<>) { 
    ... 
    } 

管列表到腳本:

$ find ... | script 

或者把它從一個文件:

$ script list_of_files.txt 

有了一個簡短的列表,我可能會使用一個喜歡的xargs技巧:

$ find ... -print0 | xargs -0 script 

在這種情況下,我去通過命令行參數:

foreach (@ARGV) { 
    ... 
    } 

如果你想要做的這一切在節目中,你可以使用File::Find

除此之外,這聽起來像你問某人爲你做的工作。