-2

我有两个目录的媒体服务器:电影和电视节目。在每个目录中,每个条目都存在于包含视频文件和字幕文件的子目录中。

我在网上搜索并找到了来自 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;

该脚本可以完美运行 - 只要它是从包含媒体的目录中运行的。

我的问题:可以修改此脚本以从根目录递归运行吗?如何?

提前致谢。

(米歇尔的剧本可以在这里看到: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 回答