使用 FFmpeg 删除导出视频字幕文件

Posted 小工具代码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用 FFmpeg 删除导出视频字幕文件相关的知识,希望对你有一定的参考价值。

大家好,我是青空。

前些天看到一个群里有人在问,有没有办法把视频中的字幕删除掉。我想了想,可以使用FFmpeg 这个软件来处理。该方法适用于视频中的软字幕,就是平常我们做视频在剪映类似软件上自己加上去的字幕。

下载FFmpeg for Windows

步骤

  1. 下载 FFmpeg https://www.ffmpeg.org/download.html
  2. 解压缩并保存到C盘(选择任何位置)。
  3. 设置环境变量 – 复制解压文件中 bin 文件夹的位置,并在系统路径变量中设置该位置。

删除软字幕

假设你有一个名为 demo.mkv 的视频文件,内置的字幕是你不需要的, 那我们可以使用 ffmpeg 框架简单地删除字幕。我们说的是内置字幕,而不是.srt文件。步骤如下

  • 转到你的文件位置,在那里打开命令提示符或终端。
  • 之后,运行以下命令
ffmpeg -i video.mkv -vcodec copy -acodec copy -sn video-no-subs.mkv

整合软字幕

现在,如果你想在视频上整合一个srt文件。步骤如下

  • 从网上下载想要的字幕。
  • 我们假设Demo.mkv和下载的文件名为sub.srt
  • 把这两个文件放在一个地方,然后从这个地方打开终端,运行以下命令
    • 首先将字幕转换成.ass格式: ffmpeg -i sub.srt subs.ass
    • 要将字幕混入视频文件,运行
ffmpeg -i demo.mkv -i sub.ass -codec copy -map 0 -map 1 output.mkv

为视频文件提取字幕

在这种情况下,一个视频文件中嵌入了字幕,你想把它变成srt文件或其他工作的软字幕文件。我们可以通过以下命令来做

ffmpeg -i demo.mkv -map 0:s:0 sub.srt

总结

该方法适用于软字幕,下次直接做个软件来执行这个命令行,有需求的可以留言或者加我微信,空了可以做一个。

如何映射用ffmpeg和视频字幕提取的帧? (帧精度问题)

【中文标题】如何映射用ffmpeg和视频字幕提取的帧? (帧精度问题)【英文标题】:How to map frame extracted with ffmpeg and subtitle of a video? (frame accuracy problem) 【发布时间】:2019-11-12 15:12:09 【问题描述】:

想为使用 ffmpeg 提取的帧生成文本文件,如果有的话,包含帧的字幕,在我也使用 ffmpeg 刻录字幕的视频上。

我使用带有pysrt 的python 脚本来打开subrip 文件并生成文本文件。 我正在做的是每个帧都由 ffmpeg 用帧号命名,然后由于它们以恒定速率提取,我可以使用公式 t1 = fnum/fps 轻松检索帧的时间位置,其中fnum 是使用文件名检索的帧数,fps 是传递给 ffmpeg 以进行帧提取的频率。

即使我使用相同的字幕文件来检索时间轴中的文本位置,也就是视频中使用的那个,我仍然会遇到准确性错误。大多数我有一些文本文件丢失或一些不应该存在。

因为在谈论帧时时间并不是真正连续的,所以我尝试使用带有硬编码字幕的视频的 fps 重新校准 t,让我们将 fps vfps 称为视频 fps(我已确保视频 fps字幕刻录前后相同)。我得到公式:t2 = int(t1*vfps)/vfps。 它仍然不是 100% 准确。

例如,我的视频是 30fps (vfps=30),我以 4fps (fps=4) 提取帧。 提取的第 166 帧 (fnum=166) 没有显示字幕。在 subrip 文件中,前一个字幕以t_prev=41.330 结尾,下一个字幕从t_next=41.400 开始,这意味着t_sub 应该满足:t_prev < t_sub and t_sub < t_next,但我无法做到这一点。

我试过的公式:

t1 = fnum/fps  # 41.5 > t_next
t2 = int(fnum*vfps/fps)/vfps  # 41.5 > t_next
# is it because of a indexing problem? No:
t3 = (fnum-1)/fps  # 41.25 < t_prev
t4 = int((fnum-1)*vfps/fps)/vfps  # 41.23333333 < t_prev
t5 = int(fnum*vfps/fps - 1)/vfps  # 41.466666 > t_next
t6 = int((fnum-1)*vfps/fps + 1)/vfps  # 41.26666 < t_prev

使用的命令:

# burning subtitles
# (previously)
# ffmpeg -r 25 -i nosub.mp4 -vf subtitles=sub.srt withsub.mp4
# now:
ffmpeg -i nosub.mp4 -vf subtitles=sub.srt withsub.mp4
# frames extraction
ffmpeg -i withsub.mp4 -vf fps=4 extracted/%05.bmp -hide_banner

为什么会发生这种情况,我该如何解决?

我注意到的一件事是,如果我提取原始视频和字幕的帧,对帧进行差异处理,结果不仅是字幕,背景也有变化(这不应该发生)。如果我两次使用相同的视频做相同的体验,差异为null,这意味着帧提取是一致的。

区别代码:

ffmpeg -i withsub.mp4 -vf fps=4 extracted/%05.bmp -hide_banner
ffmpeg -i no_sub.mp4 -vf fps=4 extracted_no_sub/%05.bmp -hide_banner
for img in no_sub/*.bmp; do
    convert extracted/$img##*/ $img -compose minus -composite diff/$img##*/
done

谢谢。

【问题讨论】:

ffmpeg -r 25 -i nosub.mp4 --> 这将重新定时帧并破坏原始时间戳。除非您知道自己在做什么,否则您不想这样做。 不是真的...我想在不改变帧率的情况下刻录字幕。所以我先试试这个:ffmpeg -i nosub.mp4 -vf subtitles=sub.srt withsub.mp4 但是它把帧率从25改成了30,所以我手动设置了帧率,好像不对。我不是 ffmpeg 的大用户。我在 Google 上搜索了如何使用 ffmpeg 保留帧率并找到了这个 superuser.com/questions/460332/…,但它没有被接受的答案。 分享您最初尝试的日志。 我的错,原来的 fps 是 30,所以我第一次尝试刻录字幕并没有改变帧速率。然而问题依然存在。并且在字幕刻录前后进行帧减法显示出比字幕更多的差异。请让我提醒一下,这不是我要解决的问题,但可能是我的问题的原因。你想看什么日志? 还值得注意的是,在示例中,区间的边界乘以帧提取得到:t_prev*fps=165.32t_next*fps=165.6,这意味着,如果 ffmpeg 提取的帧是1/fps 的因素,那么我不应该让第 166 帧位于两个字幕之间,而是显示第二个字幕(或者前一个字幕)。如果通过视频 fps 进行校正也是一样的:int(t_next*vfps)*fps/vfps=165.2, int(t_next*vfps)*fps/vfps=165.6 【参考方案1】:

您可以提取具有准确时间戳的帧,因此

ffmpeg -i nosub.mp4 -vf subtitles=sub.srt,settb=AVTB,select='if(eq(n\,0)\,1\,floor(4*t)-floor(4*prev_t))' -vsync 0 -r 1000 -frame_pts true extracted/%08d.bmp

这将从每四分之一秒中提取第一帧。输出文件名长度为 8 个字符,其中前 5 位是秒,后三位是毫秒。您可以根据最大文件持续时间更改字段大小。

【讨论】:

您能否详细介绍一下参数?我也收到一个错误:Missing ')' or too many args in 'if(eq(n,0)' settb 过滤器用于将时基设置为 1 微秒,选择过滤器表达式将选择第一帧,然后选择最接近上一季度秒的每一帧。 -r 1000 将时间戳转换为毫秒精度(否则文件名会变得更长)。 vsync 确保 ffmpeg 不会改变时间戳。 frame_pts 将时间戳打印到文件名中。 编辑 cmd 以转义所有逗号

以上是关于使用 FFmpeg 删除导出视频字幕文件的主要内容,如果未能解决你的问题,请参考以下文章

android 中使用ffmpeg,将视频加入字幕,用ass文件,在PC上可以,但在Android上一直不行

android ffmpeg视频添加字幕和配音

ffmpeg 给视频添加字幕,在视频的某个时间段加入声音特效和动画

如何映射用ffmpeg和视频字幕提取的帧? (帧精度问题)

如何使用 ffmpeg 在视频中的任意位置显示大量字幕?

FFMPEG - 转换具有多个音频和字幕的视频