torchvision.io.read_video 最轻量、最 pytorch 原生,但仅默认支持 mp4(h.264)和 avi(未压缩/mjpeg),需显式设 audio_frames="all" 才读音频,否则静默返回空音频张量;不支持 url,路径须绝对,依赖系统 ffmpeg,且整段解码易爆内存——训练推荐改用流式 videoreader。

直接说结论:用 torchvision.io.read_video 读视频最轻量、最 PyTorch 原生,但默认只支持 MP4(H.264)和 AVI(未压缩或 MJPEG),且不自动解码音频流;想读帧+音频+元信息,得手动组合参数,否则容易卡在 silent failure(比如返回空音频张量却无报错)。
为什么不用 OpenCV 或 imageio?
OpenCV 的 cv2.VideoCapture 返回的是 NumPy 数组,要转成 torch.Tensor 还得调 torch.from_numpy(),中间有内存拷贝;imageio 默认不带硬件加速,大视频加载慢。而 torchvision.io.read_video 输出就是 GPU-ready 的 torch.Tensor(可选),且底层调用 FFmpeg,兼容性更可控。
常见错误现象:RuntimeError: No video stream found —— 多半是视频编码不被 FFmpeg 支持(比如 HEVC/H.265),或文件路径含中文/空格没做 os.path.abspath() 处理。
- 确保 FFmpeg 已安装并被 torchvision 找到(运行
ffmpeg -version验证) - 路径必须是绝对路径,或用
pathlib.Path().resolve()显式归一化 - 不支持网络 URL,必须先下载到本地文件
怎么读帧 + 音频 + 元信息?
torchvision.io.read_video 默认只读视频流;要同时读音频,必须显式传 audio_frames="all"(不是布尔值!),且视频本身得含音频轨。否则 audio 返回空张量 torch.Size([0]),不会报错。
video, audio, info = torchvision.io.read_video(
"sample.mp4",
start_pts=0.0,
end_pts=10.0,
pts_unit="sec",
output_format="TCHW", # 注意:不是 CHW!T 是帧数维度
audio_frames="all" # 关键!字符串,不是 True
)
使用场景:
-
output_format="TCHW":适合后续送入 3D CNN(如torchvision.models.video.r3d_18) -
output_format="THWC":适合可视化(用matplotlib.imshow(video[0])) -
pts_unit="sec"比"pts"更直观,但要求视频时间戳连续;断帧多的监控视频建议用"pts"+info["video_fps"]反推
性能瓶颈在哪?怎么绕过?
单次 read_video 调用会解码整段视频到内存,1 分钟 1080p 视频轻松吃掉 2GB RAM。真正训练时不该这么干。
推荐做法是:用 torchvision.io.VideoReader(PyTorch 1.12+)做流式读取,按需 decode 帧:
reader = torchvision.io.VideoReader("sample.mp4", "video")
for i, frame_dict in enumerate(reader):
if i >= 100: break
frame = frame_dict["data"] # torch.Tensor, shape (C, H, W)
pts = frame_dict["pts"] # float, timestamp in seconds
注意点:
-
VideoReader不支持音频流,要音视频对齐得自己维护 PTS 映射 - 不能随机跳帧(seek),只能顺序读;想抽关键帧需配合
reader.seek()+ try/except 捕获RuntimeError - Windows 上若提示 “DLL load failed”,大概率是 FFmpeg 的
avcodec.dll版本和 torchvision 编译时链接的不一致
最容易被忽略的是:所有 torchvision.io 函数都依赖系统级 FFmpeg,而不是 Python 包里的静态二进制。conda 安装的 pytorch 和 torchvision 通常自带 FFmpeg,但 pip 安装的不会——这时候必须手动装系统 FFmpeg,并确保 os.environ["PATH"] 包含其 bin 目录。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











