You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用python-ffmpeg提取多视频流MOV文件的帧?

解决ffmpeg-python指定输入视频流的问题

你遇到的问题是因为stream_index并非ffmpeg.input()的有效参数——这个参数是ffmpeg用于输出流索引指定的选项,不能用来选择输入流。要读取MOV文件中指定的视频流,需要用map选项来定位目标流。

修正后的代码示例

import numpy as np
from PIL import Image
import ffmpeg
from pathlib import Path

# 替换为你的文件路径和保存目录
file = "your_input.mov"
video_streams_dir = Path("./output_frames")
video_streams_dir.mkdir(exist_ok=True)

# 探测文件中的流信息
probe = ffmpeg.probe(file)
video_streams = [stream for stream in probe['streams'] if stream['codec_type'] == 'video']

for stream in video_streams:
    stream_idx = stream["index"]
    # 获取当前流的分辨率(不同流可能分辨率不同)
    width = stream['width']
    height = stream['height']
    
    # 构建ffmpeg命令:选择指定视频流,输出为rgb24原始帧
    out, _ = (
        ffmpeg
        .input(file)
        .map(f'0:v:{stream_idx}')  # 0代表第一个输入文件,v代表视频流,stream_idx为目标流索引
        .output('pipe:', format='rawvideo', pix_fmt='rgb24')
        .run(capture_stdout=True, quiet=True)  # quiet=True避免打印ffmpeg日志
    )
    
    # 将原始字节转为numpy数组
    video = np.frombuffer(out, np.uint8).reshape([-1, height, width, 3])
    
    # 创建当前流的保存目录
    stream_dir = video_streams_dir / str(stream_idx)
    stream_dir.mkdir(exist_ok=True)
    
    # 逐帧保存为JPEG
    for i in range(video.shape[0]):
        frame = Image.fromarray(video[i,...])
        frame.save(stream_dir / f"frame_{i:04d}.jpeg")

关键说明

  • 使用.map(f'0:v:{stream_idx}')来选择输入文件中的指定视频流:
    • 0表示第一个输入文件(如果只有一个输入源就用0)
    • v表示筛选视频流
    • stream_idx是从probe中获取的流索引值
  • 每个视频流的分辨率可能不同,必须单独从stream信息中读取width和height,否则会导致reshape失败
  • 加入quiet=True可以避免ffmpeg在运行时输出冗余日志,保持控制台整洁

内容的提问来源于stack exchange,提问作者Dolev Shapira

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 14:52:26