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

跨平台下能否通过FFmpeg与PyAudio创建RTMP连接?

跨平台下用FFmpeg + PyAudio实现RTMP推流

完全可以在Windows/macOS/Linux等跨平台环境中,基于FFmpeg和PyAudio实现RTMP推流。核心是配置正确的FFmpeg命令行参数,同时处理音视频同步和跨平台兼容性细节。下面是补全并优化后的完整方案:

核心问题修复与配置

你的代码中最关键的缺失是FFmpeg命令的正确构造,以及音视频写入的同步逻辑问题。以下是分步解决的方案:

1. 跨平台FFmpeg命令构造

FFmpeg需要明确接收从stdin传入的原始视频和音频流,同时指定编码格式以适配RTMP的FLV容器。命令需兼顾跨平台,自动适配FFmpeg可执行文件名称:

import sys

# 跨平台FFmpeg可执行文件名
ffmpeg_path = "ffmpeg.exe" if sys.platform == "win32" else "ffmpeg"

command = [
    ffmpeg_path,
    # 视频输入配置
    "-y",
    "-f", "rawvideo",
    "-vcodec", "rawvideo",
    "-pix_fmt", "bgr24",  # OpenCV读取的帧是BGR格式
    "-s", f"{width}x{height}",
    "-r", str(fps),
    "-i", "-",  # 从stdin读取视频流
    # 音频输入配置
    "-f", "s16le",  # PyAudio输出的是16位小端PCM
    "-ac", str(CHANNELS),
    "-ar", str(RATE),
    "-i", "-",  # 从stdin读取音频流
    # 输出编码配置(适配RTMP)
    "-c:v", "libx264",
    "-preset", "ultrafast",  # 推流优先低延迟
    "-tune", "zerolatency",
    "-c:a", "aac",
    "-b:a", "128k",
    "-f", "flv",  # RTMP要求FLV格式输出
    rtmp_url
]

2. 音视频同步优化

原代码中交替写入视频帧和音频chunk会导致时序混乱,建议用多线程分别处理视频捕获/写入和音频捕获/写入,避免互相阻塞:

完整优化代码

import sys
import pyaudio
import subprocess
import cv2
import threading

rtmp_url = "rtmp://MYURL"

# 摄像头初始化
cap = cv2.VideoCapture(0)
fps = int(cap.get(cv2.CAP_PROP_FPS)) or 30  # 兼容部分摄像头无法获取FPS的情况
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

# 跨平台FFmpeg命令构造
ffmpeg_path = "ffmpeg.exe" if sys.platform == "win32" else "ffmpeg"
command = [
    ffmpeg_path,
    "-y",
    "-f", "rawvideo",
    "-vcodec", "rawvideo",
    "-pix_fmt", "bgr24",
    "-s", f"{width}x{height}",
    "-r", str(fps),
    "-i", "-",
    "-f", "s16le",
    "-ac", "1" if sys.platform == "darwin" else "2",
    "-ar", "44100",
    "-i", "-",
    "-c:v", "libx264",
    "-preset", "ultrafast",
    "-tune", "zerolatency",
    "-c:a", "aac",
    "-b:a", "128k",
    "-f", "flv",
    rtmp_url
]

# 启动FFmpeg子进程
subProcess = subprocess.Popen(
    command,
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
    bufsize=10**8  # 增大缓冲区避免阻塞
)

# 音频配置
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1 if sys.platform == 'darwin' else 2
RATE = 44100
PyA = pyaudio.PyAudio()
stream = PyA.open(
    format=FORMAT,
    channels=CHANNELS,
    rate=RATE,
    input=True,
    frames_per_buffer=CHUNK
)

def video_thread():
    """视频捕获与写入线程"""
    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            print("读取视频帧失败")
            break
        try:
            subProcess.stdin.write(frame.tobytes())
        except BrokenPipeError:
            print("FFmpeg进程已终止")
            break
    cap.release()

def audio_thread():
    """音频捕获与写入线程"""
    while stream.is_active():
        try:
            audio_data = stream.read(CHUNK)
            subProcess.stdin.write(audio_data)
        except (BrokenPipeError, IOError):
            print("FFmpeg进程已终止或音频读取失败")
            break
    stream.close()
    PyA.terminate()

# 启动线程
video_t = threading.Thread(target=video_thread)
audio_t = threading.Thread(target=audio_thread)
video_t.start()
audio_t.start()

# 等待线程结束
video_t.join()
audio_t.join()

# 清理FFmpeg进程
subProcess.stdin.close()
subProcess.wait()

跨平台注意事项

  • FFmpeg安装:确保FFmpeg已安装并添加到系统PATH,若未添加,可在ffmpeg_path中指定完整路径(例如C:\\ffmpeg\\bin\\ffmpeg.exe)
  • PyAudio安装:
    • Windows:直接执行pip install pyaudio
    • macOS:先安装PortAudio依赖brew install portaudio,再执行pip install pyaudio
    • Linux:先安装依赖sudo apt-get install portaudio19-dev(Debian/Ubuntu),再执行pip install pyaudio
  • 设备兼容性:部分平台可能需要调整摄像头设备编号(cv2.VideoCapture(0)中的0),或通过PyAudio枚举音频输入设备指定特定麦克风

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 14:40:24