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

FFmpeg+Python多摄像头录制时Cam3间歇性无帧输出问题排查

多摄像头FFmpeg录制间歇性空文件问题排查求助

问题背景

通过Python多线程调用FFmpeg同时录制3台摄像头,每段视频时长5秒,录制间隔约25秒。整体流程正常,但摄像头3的录制文件会间歇性生成0时长空文件(无视频帧)。已做排查:

  • 排除硬件问题:更换摄像头后问题仍存在
  • 调整线程调用顺序、更新FFmpeg至最新静态版均无效
  • 录制时CPU、内存占用处于合理范围

核心代码

import os
import datetime
import subprocess
from threading import Thread

def take_vid1(path1, video_length, sampleN):  
    dt = datetime.datetime.now().strftime("%Y_%m_%d_%H_%M_%S")
    save1 = os.path.join(path1, dt+'_1'+sampleN+'.mp4')
    command = [ffmpeg_path, '-hide_banner', '-y', '-f', 'dshow', '-thread_queue_size', '4096', '-rtbufsize', '500M', '-c:v', 'mjpeg', '-video_size', '1600x896', '-framerate', '30', '-i', 'video='+dev1, '-map', '0', '-t', video_length, save1]
    sp = subprocess.run(command, capture_output=True, text=True) 
    print(dt + ' vid1 returncode: ' + str(sp.returncode)) 

def take_vid2(path2, video_length, sampleN):  
    dt = datetime.datetime.now().strftime("%Y_%m_%d_%H_%M_%S")
    save2 = os.path.join(path2, dt+'_2'+sampleN+'.mp4')
    command = [ffmpeg_path, '-hide_banner', '-y', '-f', 'dshow', '-thread_queue_size', '4096', '-rtbufsize', '500M', '-c:v', 'mjpeg', '-video_size', '1600x896', '-framerate', '30', '-i', 'video='+dev2, '-map', '0', '-t', video_length, save2]
    sp = subprocess.run(command, capture_output=True, text=True) 
    print(dt + ' vid2 returncode: ' + str(sp.returncode))  

def take_vid3(path3, video_length, sampleN):  
    dt = datetime.datetime.now().strftime("%Y_%m_%d_%H_%M_%S")
    save3 = os.path.join(path3, dt+'_3'+sampleN+'.mp4')
    command = [ffmpeg_path, '-hide_banner', '-y', '-f', 'dshow', '-thread_queue_size', '4096', '-rtbufsize', '500M', '-c:v', 'mjpeg', '-video_size', '1600x896', '-framerate', '30', '-i', 'video='+dev3, '-report', '-map', '0', '-t', video_length, save3]
    sp = subprocess.run(command, capture_output=True, text=True) 
    print(dt + ' vid3 returncode: ' + str(sp.returncode))  

# 线程初始化与启动
t1 = Thread(target=take_vid1, args=[cam1Path, video_length,sampleN])
t2 = Thread(target=take_vid2, args=[cam2Path, video_length,sampleN])
t3 = Thread(target=take_vid3, args=[cam3Path, video_length,sampleN])
threads = [t1,t2,t3]

if __name__ == '__main__':
    for t in threads:
        t.start()
    for t in threads:
        t.join()

排查方向与解决建议

  • 检查设备初始化延迟:摄像头3可能启动时未及时输出帧,FFmpeg在-t指定的5秒内未捕获到帧,导致生成空文件。可尝试:
    • 添加-stimeout 5000000参数(设置5秒超时,超时未收到帧则报错,避免生成空文件)
    • 给摄像头3的线程增加启动延迟,比如t3.start()前执行time.sleep(0.3),避开多设备同时初始化的资源竞争
  • 调整FFmpeg输入参数:
    • 增大-thread_queue_size至8192,避免队列溢出导致丢帧
    • 移除-c:v mjpeg参数,让FFmpeg自动协商输入格式,部分摄像头在强制mjpeg模式下启动较慢
    • 添加-fflags +genpts,强制生成时间戳,避免无有效帧时文件结构异常
  • 捕获错误输出:修改摄像头3的代码,打印FFmpeg的stderr内容,定位具体错误:
    print(dt + ' vid3 stderr: ' + sp.stderr)
    
  • 单线程测试:单独用线程录制摄像头3,测试是否仍会生成空文件,排除多线程资源竞争的影响
  • 检查系统层面问题:尝试更换摄像头3的USB端口,更新摄像头驱动,排查Windows设备权限或USB供电不足的问题
  • 分析失败日志:查看FFmpeg报告中是否存在dshow: No video frames captured等关键错误,确认是设备未输出帧还是FFmpeg处理逻辑问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 13:43:21