为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

陪伴而非守候 2023-03-22 16:23:34
我的代码如下。断路器文件:from moviepy.video.io.ffmpeg_tools import ffmpeg_extract_subclipsplits = [[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))此断路器代码有效并成功地将剪辑分成适当的长度。打开它们时,出现如下错误:在 VLC 中打开子剪辑时出现撕裂问题(示例)与正在观看的实际长度相比,视频长度不正确例如在维加斯,每个子剪辑的音频都比视频短当试图将这些视频连接成一个更大的视频(下面的代码)时,当剪辑被加入时,“过渡”会在播放新剪辑之前重复上一个视频的最后几分钟几秒钟串联代码: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) 点中写的错误。额外的信息:我使用了同一视频的两个原始版本,一个是原始视频 (2.42gb),另一个是我运行 Handbrake 编码以确保这不是问题所在的版本。我也对输出进行了编码,以防出现问题(再次使用 Handbrake)并且问题保持不变。昨天运行这两个代码时这不是问题,从那以后我所做的唯一操作是尝试重新安装 MoviePy( - pip uninstall moviepy> pip install moviepy==1.0.1,我目前使用的是版本1.0.3- 如果默认设置中缺少某些东西安装 Python,请告诉我)这个问题与语法错误无关,我已经解释了代码以使其更易于阅读这是 Vegas 单独查看这些文件的屏幕截图(我没有剪切它们,这只是我将它们直接粘贴到 Vegas 中):
查看完整描述

1 回答

?
一只甜甜圈

TA贡献1836条经验 获得超5个赞

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

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

使用 mp4 容器可以在非关键帧处剪切而无需使用编辑列表重新编码(关于编辑列表的问题)。换句话说,如果 3 秒之前最接近的关键帧在 0 秒,那么它将从 0 秒开始复制视频,并使用编辑列表告诉播放器不是在 3 秒而是在 0 秒开始播放,因为它最近的关键帧休息帧被丢弃. 这就是有时音频播放和视频图像挂起但时间线继续运行的原因。

你做了什么,它不会重新编码原始的东西!它只是在最近的关键帧处拆分到您指定的开始/结束时间,并且它们的间隔不相等,因此最终结果的长度不等。

不要这样做: 尽管这是最快和最好的 ffmpeg 方式,但我已经弄明白了,这就是我假设你的方法正在做的事情:

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

重新编码时,您可能还希望包含其他编解码器选项,然后使用此 ::

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

但是斯瓦米有什么区别呢?

我们没有使用 -c 复制参数。因此不只是转储原始 I/O 流。但再次重新编码,需要更多的 CPU 工作!

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

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


查看完整回答
反对 回复 2023-03-22
  • 1 回答
  • 0 关注
  • 174 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信