3

我一直在使用 Moviepy 将几个较短的视频文件组合成一小时长的文件。一些小文件“损坏”,它们包含视频但未正确完成(即它们使用 VLC 播放,但没有持续时间,您不能在视频中跳过)。

当我尝试使用 VideoFileClip(file) 函数创建剪辑时,我注意到了这个问题。出现的错误是:

MoviePy 错误:无法读取文件的持续时间

有没有办法仍然从这个视频文件中读取“好”帧,然后将它们添加到更长的视频中?

更新

澄清一下,我的问题具体在于以下函数调用:

clip = mp.VideoFileClip("/home/test/"+file)

在检查ffmpeg_reader.py中文件的持续时间时,单步执行代码似乎是一个问题,它在视频文件中查找持续时间参数。但是,由于文件从未正确完成记录,因此缺少此信息。我对视频文件的结构方式不是很熟悉,所以我不确定如何从这里开始。

4

4 回答 4

0

我以更简单的方式解决了它,在 VLC 的帮助下,我将文件转换为 MPEG4 xxx TV/device 格式,您现在可以在 python 中使用新文件而没有任何问题

xxx = 720p 或 xxx = 1080p

一切都取决于您对输出格式的选择

我已经在博客上回答了这个问题:https ://github.com/Zulko/moviepy/issues/116

于 2019-11-07T22:37:35.693 回答
0

你是对的。当文件中缺少视频时长信息时,通常会出现此问题。这是关于这个问题的一个线程:GitHub moviepy issue 116

一位用户使用本指南提出了使用 MP4Box 转换视频的解决方案:RASPIVID 教程

对我有用的最终解决方案涉及将 ImageMagick 二进制文件的路径指定为本文中提到的 WDBell。

我在环境变量中正确设置了路径,但直到我在 config_defaults.py 中明确定义它才开始工作: 来自 GitHub 讨论的解决方案

于 2018-02-24T21:43:31.017 回答
0

当来自moviepy的 VideoFileClip(file) 函数在视频文件中查找持续时间参数并且它丢失时,会出现此问题。为避免这种情况(在那些文件损坏的情况下),您应该确保在拍摄函数之前总帧参数不为空:clip = mp.VideoFileClip("/home/test/"+file)

因此,我使用 cv2 以更简单的方式处理它。

想法:

  1. 找出总帧数

  2. 如果 frames 为空,则调用 cv2 的编写者并生成视频剪辑的临时副本。

  3. 将原始视频中的音频与副本混合。

  4. 替换原始视频并删除副本。

  5. 然后调用函数clip = mp.VideoFileClip("/home/test/"+file)

澄清:由于 OpenCV VideoWriter 不编码音频,新副本将不包含音频,因此有必要从原始视频中提取音频,然后将其与副本混合,然后再将其替换为原始视频。

您必须导入 cv2

import cv2

然后在评估之前在您的代码中添加类似这样的内容:

cap = cv2.VideoCapture("/home/test/"+file)
frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
fps = int(cap.get(cv2.CAP_PROP_FPS))
print(f'Checking Video {count} Frames {frames} fps: {fps}')

这肯定会返回 0 帧,但应该至少返回帧率 (fps)。现在我们可以设置评估以避免错误并处理它制作临时视频:

if frames == 0:
    print(f'No frames data in video {file}, trying to convert this video..')
    writer = cv2.VideoWriter("/home/test/fixVideo.avi", cv2.VideoWriter_fourcc(*'DIVX'), int(cap.get(cv2.CAP_PROP_FPS)),(int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))))                  
    while True:
      ret, frame = cap.read()
      if ret is True:
        writer.write(frame)
      else:
        cap.release()
        print("Stopping video writer")
        writer.release()
        writer = None
        break

将原始视频中的音频与副本混合。我为此创建了一个函数:

def mix_audio_to_video(pathVideoInput, pathVideoNonAudio, pathVideoOutput):
  videoclip = VideoFileClip(pathVideoInput)
  audioclip = videoclip.audio
  new_audioclip = CompositeAudioClip([audioclip])
  videoclipNew = VideoFileClip(pathVideoNonAudio)
  videoclipNew.audio = new_audioclip
  videoclipNew.write_videofile(pathVideoOutput)

mix_audio_to_video("/home/test/"+file, "/home/test/fixVideo.avi", "/home/test/fixVideo.mp4")

替换原始视频并删除副本:

os.replace("/home/test/fixVideo.mp4", "/home/test/"+file)
os.remove("/home/test/fixVideo.avi")
于 2022-02-24T20:14:21.630 回答
-3

clip1=VideoFileClip('路径')

c=clip1.duration

打印(c)

于 2017-02-09T11:48:37.630 回答