我有175个mp4视频文件和扩展名为.ass的字幕文件。不幸的是,我的智能电视看不懂那些字幕。我计划在视频中刻录(硬编码)字幕。
我使用以下命令:
ffmpeg -i orgvideo.mp4 -vf subtitles="subtitle.ass" newvideo.mp4 <br>它起作用了。因此,我计划使用一个bash脚本来自动化这个过程。
脚本中的所有内容都正常工作,但是ffmpeg命令行无法检索字幕变量。
搜索完后,我发现我的文件名具有特殊的字符和空间,这会导致我的脚本失败。如果视频文件名和字幕文件很简单,那么脚本就没有问题。
这是我的剧本:
for f in *.mp4
do
new="${f%%.mp4} (CHT).mp4"
subtitle="${f%%.mp4}.chi.ass"
< /dev/null ffmpeg -i "$f" -vf subtitles="$subtitle" "$new"
doneffmpeg行在读取字幕文件变量时遇到问题。有人能帮忙吗?
发布于 2017-06-20 12:55:16
试着改变:
new="${f%%.mp4} (CHT).mp4"
subtitle="${f%%.mp4}.chi.ass"
< /dev/null ffmpeg -i "$f" -vf subtitles="$subtitle" "$new"至:
new="${f%%.mp4}.CHT.mp4"
subtitle="${f%%.mp4}.chi.ass"
# make a temp hardlink to evade `ffmpeg`'s
# onerous quoting requirements.
x=`mktemp -u -p . --suffix=.ass`
ln "$subtitle" $x
< /dev/null ffmpeg -i "$f" -vf subtitles=$x "${new}"
rm $x它是如何工作的。由于ffmpeg使使用带有转义的字幕文件变得困难,所以只需将字幕文件链接到没有转义的名称$x,让ffmpeg仔细研究,然后删除链接。
一个更简洁的方法是使用一个名为ffescape的工具来转换$subtitle变量;不幸的是,该工具目前还没有打包在ffmpeg的源代码树之外。
发布于 2017-06-20 14:53:06
我用这个脚本设法解决了这个问题。如果你能帮助缩短它,它将是完美的。
for f in *.mp4
do
new="${f%%.mp4} (CHT).mp4"
subtitle="${f%%.mp4}.chi.ass"
newsubtitle="${subtitle// /\\ }"
echo $newsubtitle
secsubtitle="${newsubtitle//[/\\[}"
echo $secsubtitle
thirdtitle="${secsubtitle//]/\\]}"
echo $thirdtitle
fourthtitle="${thirdtitle//(/\\(}"
echo $fourthtitle
fifthtitle="${fourthtitle//)/\\)}"
echo $fifthtitle
ffmpeg -i "$f" -vf subtitles="$fifthtitle" "$new"
done谢谢
发布于 2017-06-20 12:30:37
也许,以下几点可能有助于阐明这一问题:
反映命令行参数传递方式的小型测试程序:
$ cat >print-arg.c <<EOF
#include <stdio.h>
int main(int argc, char **argv)
{
for (int i = 0; i < argc; ++i) printf("argv[%d]: '%s'\n", i, argv[i]);
return 0;
}
EOF
$ gcc -o print-arg print-arg.c
$这可以用来反映论点:
$ ./print-arg Hello\ World "Hello World"
argv[0]: './print-arg'
argv[1]: 'Hello World'
argv[2]: 'Hello World'
$为了确保终端机不会欺骗我们,我们甚至可以这样做:
$ ./print-arg Hello\ World "Hello World" | hexdump -C
00000000 61 72 67 76 5b 30 5d 3a 20 27 2e 2f 70 72 69 6e |argv[0]: './prin|
00000010 74 2d 61 72 67 27 0a 61 72 67 76 5b 31 5d 3a 20 |t-arg'.argv[1]: |
00000020 27 48 65 6c 6c 6f 20 57 6f 72 6c 64 27 0a 61 72 |'Hello World'.ar|
00000030 67 76 5b 32 5d 3a 20 27 48 65 6c 6c 6f 20 57 6f |gv[2]: 'Hello Wo|
00000040 72 6c 64 27 0a |rld'.|
00000045
$现在,这个print-arg工具可以用来调试bash脚本test-subtitle.sh。
#/bin/bash
for f in *.mp4
do
new="${f%%.mp4} (CHT).mp4"
subtitle="${f%%.mp4}.chi.ass"
./print-arg < /dev/null ffmpeg -i "$f" -vf subtitles="$subtitle" "$new"
done执行测试:
$ touch file1.mp4 file\ 2.mp4 "file 3.mp4"
$ ./test-subtitle.sh
argv[0]: './print-arg'
argv[1]: 'ffmpeg'
argv[2]: '-i'
argv[3]: 'file 2.mp4'
argv[4]: '-vf'
argv[5]: 'subtitles=file 2.chi.ass'
argv[6]: 'file 2 (CHT).mp4'
argv[0]: './print-arg'
argv[1]: 'ffmpeg'
argv[2]: '-i'
argv[3]: 'file 3.mp4'
argv[4]: '-vf'
argv[5]: 'subtitles=file 3.chi.ass'
argv[6]: 'file 3 (CHT).mp4'
argv[0]: './print-arg'
argv[1]: 'ffmpeg'
argv[2]: '-i'
argv[3]: 'file1.mp4'
argv[4]: '-vf'
argv[5]: 'subtitles=file1.chi.ass'
argv[6]: 'file1 (CHT).mp4'
$这个测试应该清楚地说明ffmpeg将如何得到命令行参数。
更新
请在命令行上试试这个:
$ < /dev/null ffmpeg -i '[アニメ] FAIRY TAIL 第001話「妖精の尻尾(ようせいのしっぽ)」(1280x720 x264 AAC).mp4' -vf 'subtitles=[アニメ] FAIRY TAIL 第001話「妖精の尻尾(ようせいのしっぽ)」(1280x720 x264 AAC).chi.ass' '[アニメ] FAIRY TAIL 第001話「妖精の尻尾(ようせいのしっぽ)」(1280x720 x264 AAC) (CHT).mp4'在阅读了你的答案后,我相信副标题真的必须提供反斜杠逃脱。我很想知道引用是否有效。
所以,请在命令行上做最后一次测试:
$ < /dev/null ffmpeg -i '[アニメ] FAIRY TAIL 第001話「妖精の尻尾(ようせいのしっぽ)」(1280x720 x264 AAC).mp4' -vf 'subtitles="[アニメ] FAIRY TAIL 第001話「妖精の尻尾(ようせいのしっぽ)」(1280x720 x264 AAC).chi.ass"' '[アニメ] FAIRY TAIL 第001話「妖精の尻尾(ようせいのしっぽ)」(1280x720 x264 AAC) (CHT).mp4'根据您的评论,反斜杠转义似乎是传递字幕文件的唯一方法。实际上,我在Stackoverflow中找到了一个更短(也可能更健壮)的解决方案:Escape FileNames Using The Same Way Bash Do It。
应用于您的脚本:
#/bin/bash
for f in *.mp4
do
new="${f%%.mp4} (CHT).mp4"
subtitle=$(printf '%q' "${f%%.mp4}.chi.ass")
< /dev/null ffmpeg -i "$f" -vf subtitles="$subtitle" "$new"
done我分别更改了基本脚本test-subtitle.sh:
#/bin/bash
for f in *.mp4
do
new="${f%%.mp4} (CHT).mp4"
subtitle=$(printf '%q' "${f%%.mp4}.chi.ass")
./print-arg < /dev/null ffmpeg -i "$f" -vf subtitles="$subtitle" "$new"
done并得到:
$ touch file1.mp4 file\ 2.mp4 "file 3.mp4" 'file[4].mp4'
$ ./test-subtitle.sh
argv[0]: './print-arg'
argv[1]: 'ffmpeg'
argv[2]: '-i'
argv[3]: 'file 2.mp4'
argv[4]: '-vf'
argv[5]: 'subtitles=file\ 2.chi.ass'
argv[6]: 'file 2 (CHT).mp4'
argv[0]: './print-arg'
argv[1]: 'ffmpeg'
argv[2]: '-i'
argv[3]: 'file 3.mp4'
argv[4]: '-vf'
argv[5]: 'subtitles=file\ 3.chi.ass'
argv[6]: 'file 3 (CHT).mp4'
argv[0]: './print-arg'
argv[1]: 'ffmpeg'
argv[2]: '-i'
argv[3]: 'file1.mp4'
argv[4]: '-vf'
argv[5]: 'subtitles=file1.chi.ass'
argv[6]: 'file1 (CHT).mp4'
argv[0]: './print-arg'
argv[1]: 'ffmpeg'
argv[2]: '-i'
argv[3]: 'file[4].mp4'
argv[4]: '-vf'
argv[5]: 'subtitles=file\[4\].chi.ass'
argv[6]: 'file[4] (CHT).mp4'
$https://stackoverflow.com/questions/44644890
复制相似问题