MoviePy 较小的剪辑拆分在连接文件、不匹配的音频、编码时导致故障

MoviePy smaller clip splitting causing glitches when concatenating files, mismatched audio, encoding

我的代码如下。 断路器文件:

from moviepy.video.io.ffmpeg_tools import ffmpeg_extract_subclip

splits = [[1, 2], [5, 6], [7, 10]]

for i, split in enumerate(splits):
  start, end = split
  ffmpeg_extract_subclip("video.m4v", start, end, targetname="clips/{0}.mp4".format(i))

此断路器代码有效并成功将剪辑分解为适当的长度。打开它们时,出现如下错误:

  1. 在 VLC 中打开子剪辑时出现撕裂问题 (example)
  2. 与正在观看的实际长度相比,视频长度不正确
  3. 例如在拉斯维加斯,每个子剪辑的音频都比视频短
  4. 当尝试将这些视频连接成一个更大的视频(下面的代码)时,当剪辑合并时,“t运行sition”会在播放前重复上一个视频的最后几分钟几秒钟新剪辑

串联代码:

from moviepy.editor import *

clips = []
for i in range(1, 3):
  clips.append(VideoFileClip("{0}.mp4".format(i)))

concat = concatenate_videoclips(clips)
concat.write_videofile("output.mp4")

这也有效,但在打开时我收到上面第 (4) 点中写的错误。

补充信息:

这是Vegas单独查看这些文件的截图(我没有剪切它们,这是我直接将它们粘贴到Vegas中):

更新:我已经尝试下载 FFMPEG 的 exe 并直接调用它进行拆分(不使用 Python 下载的版本 // moviepy link 到 FFMPEG)而且这个问题仍然存在。我的想法来自

更新:我已经尝试了很多方法来排除原始文件被拆分的问题,但我开始相信这个问题在串联文件上得到了强调。将尝试寻找此功能的旧版本。

更新:对于我更改 MoviePy 的每个版本,某些 offputting 更改。在 2.0.0 中,子剪辑的结尾被冻结,没有音频播放。在 1.0.0 剪辑的开头出现故障。在 1.0.1-2 中,剪辑的结尾在移入新剪辑时出现故障。极度困惑。

更新:我实在想不出从什么角度来解决这个问题。例如:我尝试了一个不同的视频,在第一个 运行 上它是半可行的(扔到维加斯,四处移动以获得正确的时间,将其渲染为一个可以通过的视频)但是一旦我做出改变(就像尝试在剪辑时添加一两秒)它好像一切都只是不同步并放弃。一旦我 return 到之前的正常剪辑(这是可行的)剪辑根本不可预测,并且完全不同步。我现在正在寻找的是要卸载并重新安装的东西,或者替代品。

故障是因为您可能没有指定时间戳的关键帧。因为 non-keyframes 编码与最近关键帧的差异,它们只显示与前一个关键帧的差异,这就是为什么它们非常有效的内存,但不一致。类似的理论也适用于音频,取决于 codec/format ofc!

核心 moviePY 也使用 ffmpeg 工具,这里是 API 参考的官方页面,以及底层细节, https://zulko.github.io/moviepy/_modules/moviepy/video/io/ffmpeg_tools.html

使用 mp4 容器,可以使用编辑列表 (Problem about edit list) 在 non-keyframe 处剪切,而无需 re-encoding。换句话说,如果 3 秒之前最接近的关键帧在 0 秒,那么它将从 0 秒开始复制视频,并使用编辑列表告诉播放器不是在 3 秒而是在 0 秒开始播放,因为它最近的关键帧休息帧被丢弃.这就是为什么有时音频播放和视频图像挂起,但时间线保持 运行.

的原因

你所做的,不是 RE-ENCODE 原创的东西!它只是在最近的关键帧处拆分到您指定的 start/end 次,并且它们的间距不相等,因此最终结果的长度不等。

不要这样做: 尽管它是最快最好的 ffmpeg-way 我已经弄清楚了,这就是我认为你的方法正在做的事情:

ffmpeg -ss 00:01:00 -i input.mp4 -to 00:02:00 -c copy output.mp4

但下面的内容会被剪切并重新编码:

ffmpeg -i movie.mp4 -ss 00:00:03 -t 00:00:08 -async 1 cut.mp4

当 re-encoding 您可能还希望包含其他编解码器选项时,请使用此::

ffmpeg -ss 00:03:00 -t 00:00:05 -i test.wmv -acodec libmp3lame -vcodec libx264 1.mp4

But swami Whats the difference?

We are not using the -c copy parameter. hence not just dumping the raw I/O stream. but re encoding it again, more cpu work required!

此外,-t 选项指定持续时间,而不是结束时间。上面的命令(第二个代码片段)将从 3 秒开始对 8 秒的视频进行编码。要从 3 秒开始到 8 秒结束,请使用 -t 5(第 3 个代码片段)。

注意:如果您使用的是当前版本的 ffmpeg(我猜是 2015 年以上),您还可以将上述命令中的 -t 替换为 -to 以在指定时间结束。