2016-04-08 15 views
-2

私は、ムービーとテレビ番組の2つのディレクトリを持つメディアサーバーを持っています。これらのディレクトリのそれぞれの中で、各エントリは、ビデオファイルとサブタイトルファイルを含むサブディレクトリに存在します。ffmpegでHEVCのメディアディレクトリをh.264に再帰的に変換します

私は、Webを洗い上げてきたとミシェル・サリバンから優秀な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を使用することができます。

それを超えると、誰かにあなたのために仕事を依頼するように聞こえるようです。

関連する問題