目前,我运行这个命令...
# Script designed to convert webm files to m4a for easy listening
for i in *.m4a ; do
echo ffmpeg -i "\""$PWD/$i"\"" -c:a copy "\""$PWD/${i%.m4a}.mkv"\"" >> ~/bulk.command.txt
done
为自己创建一个脚本文件,稍后运行它来批量重新打包媒体文件。遗憾的是,这个过程要求我进入每个需要重新打包的目录并输入脚本名称。
有时这些项目有相当多的目录和子目录。而且当这些项目变大时,需要我非常小心项目根目录的大小。
我仍在学习如何用 bash 编写代码,我花了相当多的时间来完善这个简单的脚本,以确保几乎考虑到了所有可能的文件名。
我接下来要做的是对其进行修改,这样我就可以简单地进入我的主文件夹音乐文件夹,运行此命令一次,并让它保存目录布局,同时将 ffmpeg 创建的文件放入不同的目录中。有没有哪位高手能提供一些代码示例、术语或想法,告诉我如何完成这项任务?
答案1
启用递归通配符以递归到子目录:
shopt -s globstar
然后你可以这样做:
for f in **/*.m4a
do
printf 'ffmpeg -i %q -c:a copy %q\n' "$PWD/$f" "$PWD/${f%.m4a}.mkv"
done > bulk.command.txt
printf
的%q
引号字符串,以便它们可以安全地用作 shell 输入,所以您不必在那里弄乱引号:
%q quote the argument in a way that can be reused as shell input
如果您将其制作成脚本,那么您可以使用参数来决定是否对输出文件使用不同的目录:
#! /bin/bash
shopt -s globstar
for f in **/*.m4a
do
printf 'ffmpeg -i %q -c:a copy %q\n' "$PWD/$f" "${1:-$PWD}/${f%.m4a}.mkv"
done > bulk.command.txt
${foo:-bar}
foo
如果变量不为空,则使用其值bar
,否则,在本例中,如果变量不为空,则使用第一个参数$PWD
。
在这种情况下,您需要重新创建目录结构,方法如下mkdir -p
:
#! /bin/bash
shopt -s globstar
for f in **/*.m4a
do
printf 'mkdir -p %q\n' "${1:-$PWD}/${f%/*}"
printf 'ffmpeg -i %q -c:a copy %q\n' "$PWD/$f" "${1:-$PWD}/${f%.m4a}.mkv"
done > bulk.command.txt
如果您确实需要创建脚本以供以后使用,那就这样吧。就我个人而言,我不明白这一点 - 您可以在真正需要运行循环时直接运行它:
#! /bin/bash
shopt -s globstar
for f in **/*.m4a
do
mkdir -p "${1:-$PWD}/${f%/*}"
ffmpeg -i "$PWD/$f" -c:a copy "${1:-$PWD}/${f%.m4a}.mkv"
done > bulk.command.txt
答案2
这不太通用,专门针对那些希望将硬件加速与其他过滤器混合并需要与上面概述的类似设置的人。
从一个包含 4k 文件夹的给定目录中,包含我们要转换的所有媒体,此脚本将找到所有相关内容、转码、色调映射并将其缩小到 1920无论原始宽高比是多少,重新编码为 20Mb/s HEVC 文件,将第一个嵌入音轨转换为立体声,并将每个文件输出到 2k 文件夹下自己的子目录中 - 这样可以更轻松地分离出原生 2k 内容(对于网络内容,这往往是 19201080)。此外,它使用与硬件无关的 VAAPI 接口 - 因此只要硬件支持 HEVC,它就可以工作。
为了组织起见,这也保留了 4k 文件夹中的原始目录结构。
如果您不维护 2k 库,这将创建一个相同的存储库并创建所需的文件夹,以便轻松创建 Plex 样式库。
前面的答案已经相当不错了,可以解决 95% 的问题,不过确实需要一段时间才能让一切正常工作。为了搜索引擎索引,我的最终命令是这样的:
对于 4k/**/ 中的 f.mkv;执行 mkdir -p ./2k/transcodes/output/"${f%/}"; ffmpeg -hide_banner -loglevel warning -hwaccel'vaapi'-hwaccel_output_format vaapi -i"$PWD/$f"-vf"scale_vaapi=w=1920:h=-1,hwdownload,format=p010le,zscale=transfer=linear,tonemap=clip,zscale=transfer=bt709,format=yuv420p,format=nv12,hwupload"-ac'2'-c:v'hevc_vaapi'-b:v'20M'-ss 10-t 20./2k/transcodes/output/"${f%}".mp4; 完成
for f in 4k/**/*.mkv; do mkdir -p ./2k/transcodes/output/"${f%/*}"; ffmpeg -hide_banner -loglevel warning -hwaccel 'vaapi' -hwaccel_output_format vaapi -i "$PWD/$f" -vf "scale_vaapi=w=1920:h=-1,hwdownload,format=p010le,zscale=transfer=linear,tonemap=clip,zscale=transfer=bt709,format=yuv420p,format=nv12,hwupload" -ac '2' -c:v 'hevc_vaapi' -b:v '20M' -ss 10 -t 20 ./2k/transcodes/output/"${f%}".mp4 ; done