Macos 使用ffmpeg将媒体目录从HEVC递归转换为h.264
我有两个目录的媒体服务器:电影和电视节目。在每个目录中,每个条目都存在于包含视频文件和字幕文件的子目录中 我在网上搜索了一下,发现了Michelle Sullivan的一个优秀perl脚本,发布在这里:Macos 使用ffmpeg将媒体目录从HEVC递归转换为h.264,macos,perl,recursion,ffmpeg,mkv,Macos,Perl,Recursion,Ffmpeg,Mkv,我有两个目录的媒体服务器:电影和电视节目。在每个目录中,每个条目都存在于包含视频文件和字幕文件的子目录中 我在网上搜索了一下,发现了Michelle Sullivan的一个优秀perl脚本,发布在这里: #!/usr/bin/perl use strict; use warnings; open DIR, "ls -1 |"; while (<DIR>) { chomp; next if ( -d "$_"); # skip directo
#!/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;
#/usr/bin/perl
严格使用;
使用警告;
开放目录,“ls-1 |”;
而()
{
咀嚼;
下一个if(-d“$)#跳过目录
下一步,除非(-r“$);#如果不可读,跳过它!
我的$file=$\uux;
打开PROBE,“ffprobe-显示csv“$file”2>/dev/null |”或die(“无法为$file!($!)启动ffmpeg”);
我的($v,$a,$s,@c)=(0,0,0);
而()
{
my@streaminfo=split(/,/,$);
推送(@c,$streaminfo[2]),如果($streaminfo[5]eq“视频”);
$a++if($streaminfo[5]eq“音频”);
$s++if($streaminfo[5]eq“subtitle”);
}
闭合探头;
$v=标量@c;
if(标量@c等式1和$c[0]等式“ansi”)
{
警告(“检测到文本文件,正在跳过…\n”);
下一个
}
警告($file:Video Streams:$v,Audio Streams:$a,Subtitle Streams:$s,Video Codec:”。加入(“,”,@c)。“\n”);
if(标量@c>1)
{
警告(“$file有多个视频流,bailing!\n”);
下一个
}
如果($c[0]相等于“hevc”)
{
警告(“检测到$file…转换为AVC…的HEVC…\n”);
系统(“mkdir-p h265”);
我的@params=(“-hide_banner”,“-threads 2”);
如果($a>1或$s>1或$v>1),则推送(@params,“-map 0”);
如果($a),则推送(@params,“-c:副本”);
如果($s),则推送(@params,“-c:s副本”);
推送(@params,“-c:v libx264-pix_fmt yuv420p”)如果($v);
if(系统(“mv'$file''h265/$file'')
{
警告(“移动$file->h265/$file\n时出错”);
下一个
}
if(系统(“ffmpeg-xerror-i'h265/$file'.join(“,@params)。“$file'2>/dev/null”))
{
警告(“FFMPEG错误。无法转换$file还原原始…\n”);
系统(“mv'h265/$file'$file'”;
下一个
}
}否则{
警告(“$文件似乎不需要转换…跳过…\n”);
}
}
关闭目录;
只要脚本在包含媒体的目录中运行,脚本就可以完美地执行
我的问题:这个脚本可以修改为从根目录递归运行吗?怎么做
提前谢谢
(此处可以看到Michelle的脚本:)为什么要递归运行?您的意思是要在特定目录下的所有文件上运行它吗 在这个问题中,我宁愿将生成要处理的文件列表的部分与处理部分分开。如果文件列表很长,我可能会从标准输入中选取以下行:
while( <> ) {
...
}
或者从文件中获取:
$ script list_of_files.txt
有了一个简短的列表,我可能会使用最喜欢的xargs技巧:
$ find ... -print0 | xargs -0 script
在这种情况下,我将遍历命令行参数:
foreach ( @ARGV ) {
...
}
如果您想在程序中完成所有这些,可以使用
除此之外,听起来你是在要求别人为你做这项工作。你将代码作为\&wanted prameter放在上面的循环中。我不确定你在要求什么,你所展示的只是其他人的代码。你说你已经“搜索了web”来找到这个Perl程序,现在你似乎又在搜索它来免费找到一些我猜你自己无法创建的东西。堆栈溢出是一个被特定问题阻止的程序员可以向他们的同事寻求帮助的地方。这并不意味着ignoramus可以在这里转储他们的需求并等待解决方案
foreach ( @ARGV ) {
...
}