我正在尝试将视频分割成每 1000 帧的块(必须在帧级别完成)。我目前正在使用 openCV 库,但它非常慢。将 1 小时的视频分割成这些大小相等的块需要半个小时。

有没有其他更有效的方法(在 Python 中)我可以使用?我研究过 FFmpeg 库,但它似乎只处理按持续时间而不是按帧数分割。

在 openCV 中,这是我目前用来分割视频的函数:

def split_video(video_path, output_dir, frames_per_chunk=1000):
    cap = cv2.VideoCapture(video_path)
    fps = cap.get(cv2.CAP_PROP_FPS)
    frame_count = 0
    chunk_count = 0
    frames = []
    
    # Create output directory if it doesn't exist
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)
    
    frame_idx = 0
    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break

        frames.append(frame)
        frame_count += 1
        # Save chunk after every 'frames_per_chunk' frames
        if frame_count % frames_per_chunk == 0:
            chunk_filename = f'video_chunk_{chunk_count}.mp4'
            chunk_path = os.path.join(output_dir, chunk_filename)
            save_frames_to_video(frames, chunk_path, fps)
            frames = []
            chunk_count += 1
        frame_idx +=1

    # Save any remaining frames
    if frames:
        chunk_filename = f'video_chunk_{chunk_count}.mp4'
        chunk_path = os.path.join(output_dir, chunk_filename)
        save_frames_to_video(frames, chunk_path, fps)

    print(f'video split into {chunk_count + 1} chunks')
    cap.release()
    return

5

  • 1
    您是否明白此操作从根本上需要重新压缩/转码?


    – 


  • OpenCV 从根本上来说不是一个好的选择。您需要一个专门设计用于低级视频流的库/工具。


    – 

  • 1
    @ChristophRackwitz 我想你可以避免大部分问题(显然不是用 OpenCV)。第一个块主要是复制内容。分割后,只需生成一个新的关键帧并重新编码,直到下一个关键帧出现,然后像以前一样复制已经压缩的数据。但这将需要比目前显示的更多的研究和努力。说起来容易,我知道。:)


    – 


  • 由于这是在征求建议,我就不点名了。——某个名为 VirtualDub 的旧 GUI 程序确实将流复制到了剪切点,然后只对进入下一个剪辑的 GOP 的后半部分进行重新编码。它将对编码器和复用器进行特定的控制。我怀疑 ffmpeg 是否有针对此特定用例的示例代码。人们需要处理比特流本身。


    – 


  • @Fiori (1) “FFmpeg 似乎按持续时间而不是帧数来处理分割”是的,但无论如何duration都来自number of frames。只需检查 FPS 并计算输入视频需要多少秒(或毫秒)才能达到 1000 帧。例如: 1000 frames / FPS == time_duration_for_extract (2)下一个想法可能是手动提取 1000 帧的字节范围。您需要先将 MP4 转换为 H264(使用-codec copyFFmpeg 的快速选项)。H264 中的所有帧都以0,0,0,1字节序列开头。因此找到其中的 1000 个。如果不清楚,请再问


    – 


最佳答案
1

您可以使用 ffmpeg 来完成此操作。

ffmpeg -i input.mp4 -c copy -f segment -segment_frames 1000,2000,3000,4000,5000 output_d.mp4

上述命令将根据以下特定的帧号对视频进行分段:
1000、2000、3000、4000、5000 等。

请记住视频的 FPS 和 GOP。