-2

映画とテレビ番組の 2 つのディレクトリを持つメディア サーバーがあります。これらの各ディレクトリ内で、各エントリはビデオ ファイルと字幕ファイルを含むサブディレクトリに存在します。

私は Web を精査し、Michelle Sullivan による優れた 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;

スクリプトは、メディアを含むディレクトリ内から実行される限り、完全に実行されます。

私の質問: このスクリプトを変更して、ルート ディレクトリから再帰的に実行することはできますか? どのように?

前もって感謝します。

(Michelle のスクリプトはここで見ることができます: http://www.michellesullivan.org/blog/1636 )

4

1 に答える 1

1

なぜ再帰的に実行したいのですか?特定のディレクトリの下にあるすべてのファイルに対して実行したいということですか?

この問題では、処理するファイルのリストを生成する部分を処理から分離したいと思います。ファイルのリストが長い場合は、代わりに標準入力から行を取得することがあります。

while( <> ) {
    ...
    }

リストをスクリプトにパイプします。

$ find ... | script

または、ファイルから取得します。

$ script list_of_files.txt

短いリストでは、お気に入りの xargs トリックを使用できます。

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

その場合、コマンドライン引数を調べます。

 foreach ( @ARGV ) {
    ...
    }

これらすべてをプログラムで実行したい場合は、File::Find を使用できます。

それを超えて、あなたは誰かにあなたのために仕事をするように頼んでいるように聞こえます.

于 2016-04-08T20:28:56.390 に答える