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

使用Python+OpenCV录制Twitch直播时cv2.VideoWriter报错排查

问题:Python+OpenCV录制Twitch HLS流时的写入错误处理

我想通过streamlink.streams(url)获取Twitch直播的.m3u8直链,用Python结合OpenCV实现录制。目前读取流并保存单帧图像正常,但写入视频时出错。注:我知道Streamlink和yt-dlp等工具,但只想用Python代码实现,不用CLI命令。

现有两种代码写法及对应错误:


第一种代码及错误

if streamlink.streams(url):
    stream = streamlink.streams(url)['best']
    stream = str(stream).split(', ')
    stream = stream[1].strip("'")
    cap = cv2.VideoCapture(stream)
    gst_out = "appsrc ! video/x-raw, format=BGR ! queue ! nvvidconv ! omxh264enc ! h264parse ! qtmux ! filesink location=stream "
    out = cv2.VideoWriter(gst_out, cv2.VideoWriter_fourcc(*'mp4v'), 30, (1920, 1080))
    while True:
        _, frame = cap.read()
        out.write(frame)

对应错误:

[tls @ 0x1278a74f0] Error in the pull function.

第二种代码及错误

if streamlink.streams(url):
    stream = streamlink.streams(url)['best']
    stream = str(stream).split(', ')
    stream = stream[1].strip("'")
    while True:
        cap = cv2.VideoCapture(stream)
        _, frame = cap.read()
        out = cv2.VideoWriter(stream, cv2.VideoWriter_fourcc(*'mp4v'), 30, (1920, 1080))
        out.write(frame)

对应错误:

OpenCV: FFMPEG: tag 0x7634706d/'mp4v' is not supported with codec id 12 and format 'hls / Apple HTTP Live Streaming'

忽略的关键点及修复方案

1. 错误的Stream URL提取方式

你通过str(stream).split(', ')提取URL的方式完全不可靠,Streamlink的Stream对象自带url属性,直接用stream.url获取即可,避免因对象字符串格式变化导致提取失败。

2. 第一种代码的GStreamer管道问题

  • GStreamer管道的filesink location未指定文件后缀,需改为location=stream.mp4,否则系统无法识别输出格式。
  • omxh264enc是NVIDIA硬件专用编码器,若无对应硬件支持会直接失败,建议替换为通用的x264enc(需确保OpenCV编译时包含x264支持),或者放弃GStreamer,改用OpenCV默认的FFmpeg后端。
  • 循环内未判断cap.read()的返回值,当流中断时frame会为None,写入操作会触发错误,必须增加判断:
    ret, frame = cap.read()
    if not ret:
        break
    

3. 第二种代码的致命逻辑错误

  • 将cv2.VideoCapture和cv2.VideoWriter放入循环是完全错误的:每次循环都会重新打开HLS流(从头加载),并反复覆盖输出文件,根本无法实现连续录制。
  • cv2.VideoWriter的第一个参数需要本地文件路径或输出管道,你传入HLS流URL,FFmpeg会尝试往直播流里写入,逻辑完全错误,这也是编码格式不兼容报错的核心原因。

修复后的示例代码

import streamlink
import cv2

url = "你的Twitch直播URL"
streams = streamlink.streams(url)
if not streams:
    exit("未找到可用直播流")

# 正确获取流URL
stream_url = streams['best'].url

# 打开直播流
cap = cv2.VideoCapture(stream_url)
if not cap.isOpened():
    exit("无法打开直播流")

# 获取流的实际参数,避免硬编码
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = cap.get(cv2.CAP_PROP_FPS)
# 若FPS获取失败, fallback到30
fps = fps if fps > 0 else 30

# 使用H264编码写入MP4(兼容性更好)
fourcc = cv2.VideoWriter_fourcc(*'avc1')
out = cv2.VideoWriter("output.mp4", fourcc, fps, (width, height))

if not out.isOpened():
    exit("无法创建视频写入器")

try:
    while True:
        ret, frame = cap.read()
        if not ret:
            print("流读取结束或出错")
            break
        out.write(frame)
        # 按q键可手动退出
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
finally:
    # 释放资源
    cap.release()
    out.release()
    cv2.destroyAllWindows()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 04:39:25