为什么 FFmpeg 会给我的文件添加第二个字幕,即使我明确只添加了一个?

为什么 FFmpeg 会给我的文件添加第二个字幕,即使我明确只添加了一个?

我在一个文件夹中有一堆 MP4 文件和字幕文件,每个文件都遵循episode[num].mp4和的模式episode[num].ass

我编写了一个小型 shell 脚本来自动将它们合并为 MKV 文件:

for i in *.mp4; do 
  name=`echo $i | cut -d'.' -f1`;
  mp4name="$name.mp4";
  subname="$name.ass";
  mkvname="$name.mkv";
  ffmpeg -i "$mp4name" -i "$subname" -map 0:v -map 0:a -map 1:s -metadata:s:a language=jpn -metadata:s:s:0 language=eng -c copy -y "$mkvname"
done

echo "Done";

打开其中一个生成的 MKV 文件后,VLC 会显示两个字幕轨道:

VLC 字幕菜单显示两个字幕轨道,一个标记为“轨道 1 - 英语”,另一个标记为“轨道 2”

这该怪谁?是 FFmpeg、VLC 还是我的草草编写的脚本?我该如何解决这个问题?

答案1

VLC 和你应该受到指责,但这取决于你的最终目标。

FFmpeg 不会重复添加字幕,但 VLC 会自动检测.ass目录中的文件并将其添加到可用字幕列表中。VLC 会查找与视频文件名称完全相同的资产(例如字幕文件),并将其加载到播放器窗口中进行播放。

因此,如果你正在播放目录中的文件并播放它,VLC 将显示 MKV 文件中嵌入的GreatMovie.mkv字幕GreatMovie.assGreatMovie.ass位于该目录中的 MKV 文件旁边。

现在我说这取决于你的最终目标。如果你的最终目标只是一个包含所有资产的组合 MKV 文件,那么你需要.ass在完成后删除该文件。所以我会修改你的脚本——在命令rm -f "$subname";后添加一个ffmpeg——如下所示:

for i in *.mp4; do 
  name=`echo $i | cut -d'.' -f1`;
  mp4name="$name.mp4";
  subname="$name.ass";
  mkvname="$name.mkv";
  ffmpeg -i "$mp4name" -i "$subname" -map 0:v -map 0:a -map 1:s -metadata:s:a language=jpn -metadata:s:s:0 language=eng -c copy -y "$mkvname"
  rm -f "$subname";
done

echo "Done";

或者创建一个completed_subs/目录,完成后将字幕移动到该目录。

for i in *.mp4; do 
  name=`echo $i | cut -d'.' -f1`;
  mp4name="$name.mp4";
  subname="$name.ass";
  mkvname="$name.mkv";
  ffmpeg -i "$mp4name" -i "$subname" -map 0:v -map 0:a -map 1:s -metadata:s:a language=jpn -metadata:s:s:0 language=eng -c copy -y "$mkvname"
  mkdir -p "completed_sub";
  mv $subname "completed_sub/$subname";
done

echo "Done";

这样,您便可以从处理目录中删除字幕,因此查看 MKV 文件时只会显示嵌入在 MKV 文件中的字幕资产,而独立字幕.ass文件现在位于 中completed_sub/。因此,您不仅可以看到已完成的内容,还可以保留独立字幕文件,以备将来需要。

答案2

这都是你的错。

.ass从视频目录中删除现有文件。

VLC 同时显示嵌入的字幕和视频目录中的字幕。

相关内容