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

如何通过Python subprocess配置FFmpeg向AWS Nginx RTMP推流音视频?

问题:推送RTMP流时仅能推视频无法推音频的解决办法

问题描述

我已在AWS上搭建好Nginx RTMP服务器,希望通过Python的subprocess模块调用FFmpeg命令,向该服务器推送包含音视频的流。目前使用以下代码仅能推送视频,无法推送音频,请问需在FFmpeg命令中添加哪些配置?

import subprocess 
import cv2 
rtmp_url = "rtmp://ip/route"

path = 0 
cap = cv2.VideoCapture(path)

# gather video info to ffmpeg 
fps = int(cap.get(cv2.CAP_PROP_FPS)) 
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) 
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

# command and params for ffmpeg 
command = ['ffmpeg',
           '-y',
           '-f', 'rawvideo',
           '-vcodec', 'rawvideo',
           '-pix_fmt', 'bgr24',
           '-s', "{}x{}".format(width, height),
           '-r', str(fps),
           '-i', '-',
           '-c:v', 'libx264',
           '-pix_fmt', 'yuv420p',
           '-preset', 'ultrafast',
           '-f', 'flv',
           rtmp_url]

# using subprocess and pipe to fetch frame data 
p = subprocess.Popen(command, stdin=subprocess.PIPE)

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        print("frame read failed")
        break

    p.stdin.write(frame.tobytes())

原因分析

当前代码存在两个核心问题:

  1. cv2.VideoCapture仅读取视频帧,不处理音频数据,没有音频输入源传递给FFmpeg;
  2. FFmpeg命令中完全没有配置音频相关的输入和编码参数,导致输出流只有视频轨道。

解决办法

1. 新增音频输入源

直接让FFmpeg从系统音频设备(比如麦克风)抓取音频,无需通过Python传递音频数据,这种方式更稳定高效。不同系统的音频设备格式不同,需要对应调整:

  • Windows:使用dshow设备,需指定麦克风名称
  • Linux:使用alsa设备,默认设备为default
  • macOS:使用avfoundation设备,默认音频设备为:0

2. 修改FFmpeg命令

在原有视频参数基础上,添加音频输入参数和编码配置,确保输出的FLV流包含音轨。

完整修改后的代码

以下以Windows系统为例(需替换麦克风名称为你的设备名称):

import subprocess 
import cv2 

rtmp_url = "rtmp://ip/route"
path = 0 
cap = cv2.VideoCapture(path)

# 获取视频信息
fps = int(cap.get(cv2.CAP_PROP_FPS)) 
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) 
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

# 查看Windows音频设备名称:执行命令 ffmpeg -list_devices true -f dshow -i dummy
audio_device = '音频输入设备 (Realtek(R) Audio)'  # 替换为你的麦克风名称

# 带音频的FFmpeg命令
command = [
    'ffmpeg',
    # 视频输入:从Python管道读取原始视频帧
    '-y',
    '-f', 'rawvideo',
    '-vcodec', 'rawvideo',
    '-pix_fmt', 'bgr24',
    '-s', f"{width}x{height}",
    '-r', str(fps),
    '-i', '-',
    # 音频输入:从系统麦克风抓取(Windows示例)
    '-f', 'dshow',
    '-i', f'audio="{audio_device}"',
    # 视频编码配置
    '-c:v', 'libx264',
    '-pix_fmt', 'yuv420p',
    '-preset', 'ultrafast',
    # 音频编码配置
    '-c:a', 'aac',  # RTMP推荐的音频编码格式
    '-b:a', '128k',  # 音频比特率,可根据需求调整
    '-ar', '44100',  # 采样率,匹配多数设备
    '-ac', '2',  # 双声道
    # 输出格式为FLV,适配RTMP
    '-f', 'flv',
    rtmp_url
]

# 启动FFmpeg子进程
p = subprocess.Popen(command, stdin=subprocess.PIPE)

try:
    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            print("frame read failed")
            break
        # 写入视频帧到FFmpeg管道
        p.stdin.write(frame.tobytes())
finally:
    # 清理资源
    cap.release()
    p.stdin.close()
    p.wait()

不同系统的音频输入参数替换

  • Linux:将音频输入部分替换为:
    '-f', 'alsa',
    '-i', 'default',
    
  • macOS:将音频输入部分替换为:
    '-f', 'avfoundation',
    '-i', ':0',
    

查看系统音频设备方法

  • Windows:在命令行执行 ffmpeg -list_devices true -f dshow -i dummy,找到对应的麦克风名称
  • Linux:执行 arecord -l 查看音频设备列表
  • macOS:执行 ffmpeg -f avfoundation -list_devices true -i "" 查看设备列表

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 00:45:30