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

如何使用ffmpeg将RTSP流仅音频部分输出到stdout,或直接读取音频帧?

解决方案汇总

一、FFmpeg命令修改方案(输出原始音频流到stdout)

你原命令的问题是保留了视频流且输出到本地HLS文件,修改后命令如下:

ffmpeg -i rtsp://你的RTSP地址 -vn -c:a pcm_s16le -f s16le -ar 44100 -ac 1 -

参数解释:

  • -vn:丢弃所有视频流,仅保留音频处理
  • -c:a pcm_s16le:指定音频编码为16位小端整数PCM,属于无压缩的原始音频数据,可直接读取做响度计算
  • -f s16le:强制输出格式为16位小端PCM
  • -ar 44100:指定采样率为44100Hz,可根据你的摄像头实际参数调整
  • -ac 1:指定输出为单声道,减少数据处理量
  • 末尾的-:指定输出目标为stdout,而非本地文件

你可以在Python/Go中创建子进程调用该命令,持续读取stdout的二进制流,每2个字节对应一个16位整数音频采样点,直接转为数组即可做分贝分析。
以Python为例的调用逻辑:

import subprocess
import numpy as np

# 启动ffmpeg子进程
cmd = [
    "ffmpeg", "-i", "rtsp://你的RTSP地址",
    "-vn", "-c:a", "pcm_s16le", "-f", "s16le",
    "-ar", "44100", "-ac", "1", "-"
]
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, bufsize=10**8)

# 每次读取1秒的音频数据(44100采样点 * 2字节/采样点 = 88200字节)
while True:
    audio_bytes = proc.stdout.read(88200)
    if not audio_bytes:
        break
    # 转为16位整数数组
    audio_array = np.frombuffer(audio_bytes, dtype=np.int16)
    # 此处执行分贝计算逻辑

二、直接读取RTSP音频帧的编程方案

如果你不想依赖FFmpeg子进程调用,可以直接用对应语言的RTSP处理库实现你需要的API逻辑:

Python方案

使用PyAV库(FFmpeg的Python绑定),示例代码如下:

import av
import numpy as np

# 打开RTSP流
container = av.open("rtsp://你的RTSP地址")
# 查找音频流
audio_stream = next(s for s in container.streams if s.type == 'audio')

# 持续读取音频帧
for frame in container.decode(audio_stream):
    # 转为numpy数组,格式为(声道数, 采样点数量),如果是单声道可以直接flatten
    signal_array = frame.to_ndarray()
    # 执行响度分析逻辑

Go方案

使用gortsplib库结合ffmpeg-go绑定,核心逻辑如下:

package main

import (
    "gortsplib/v2"
    "gortsplib/v2/pkg/format"
    "gortsplib/v2/pkg/formatdecenc/rtppcmalaw"
)

func main() {
    // 初始化RTSP客户端
    client := gortsplib.Client{}
    // 连接RTSP地址
    conn, _, err := client.Dial("rtsp://你的RTSP地址")
    if err != nil {
        panic(err)
    }
    defer conn.Close()

    // 查找音频格式
    var audioFormat *format.PCMALaw
    for _, forma := range conn.Setup {
        if f, ok := forma.Format.(*format.PCMALaw); ok {
            audioFormat = f
            break
        }
    }

    // 读取RTP包并解码为音频帧
    conn.OnPacketRTP(audioFormat, func(pkt *rtppcmalaw.Packet) {
        signalArray := pkt.Payload
        // 执行响度分析逻辑
    })

    // 开始播放
    conn.Play(nil)
    select {}
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 05:36:03