有没有一种方法可以使用ffmpeg将RTSP音频流仅流式传输到标准输出(stdout)?

huangapple go评论106阅读模式
英文:

Is there a way to stream RTSP audio stream only to stdout with ffmpeg

问题

我有一个通过rtsp流传输视频/音频的网络摄像头。我希望制作一个小程序,只检测音频流并进行房间音量检测。

我的计划是使用ffmpeg将音频流作为整数/浮点数流输出到stdout。这样我就可以在Python或Go中以回调方式读取流并分析分贝。

我找到了一个示例:

ffmpeg -i rtsp://some_url -c:a aac -c:v copy -hls_list_size 65535 -hls_time 2 "./live.m3u8"

但是这个示例将整个视频写入文件。有没有什么建议可以改变这种情况?

我也可以接受其他语言中的任何其他解决方案/包,以便我可以做类似以下的操作:

connection = RTSP('rtsp://url')
signal_array = connection.read_audio_frame()

请给予建议。

英文:

I have a webcam that stream the video/audio via rtsp. I wish to make a small program that only detect the audio stream and make a room loudness detection.

My plan is to use ffmpeg to get the audio stream only as a stream of integer/float to stdout. So that I can read the stream in Python or Go as callback and analyse and decibles.

I found an example:

ffmpeg -i rtsp://some_url -c:a aac -c:v copy -hls_list_size 65535 -hls_time 2 "./live.m3u8"

But this write the whole video to files. Any suggestion how to change that?

I am also open to any other solution/packages in other languages that I can do something like

connection = RTSP('rtsp://url')
signal_array = connection.read_audio_frame()

Please advice

答案1

得分: 1

ffmpeg可以通过添加pipe:来输出到stdout。根据文档:

接受的语法是:

pipe:[number]

number是与管道的文件描述符对应的数字(例如,0表示stdin,1表示stdout,2表示stderr)。如果未指定number,默认情况下将使用stdout文件描述符进行写入,stdin进行读取。

http://ffmpeg.org/ffmpeg-all.html#pipe

个人建议与命名管道(FIFO)一起使用:

mkfifo /tmp/videofifo
ffmpeg -i myfile.mp4 -f avi pipe: > /tmp/videofifo
with open("/tmp/videofifo", "rb") as f:
    ...

当然,对于你的用例,你使用自己的ffmpeg命令,并以"r"而不是"rb"模式打开fifo。

在你的情况下,使用fifo而不仅仅是捕获stdout(直接使用subprocess.PIPE)可能优势不大(ascii数据按行处理),但在处理二进制数据时似乎更清晰。无论如何,我更喜欢将数据与获取数据的方式分开。如果你只想直接处理stdout,使用p = subprocess.Popen(cmd, stdout=subprocess.PIPE),然后处理p.stdout,它是一个类似文件的对象。

毫无疑问,Go语言肯定有等效的启动子进程的方法,但是我非常抱歉,目前我对Go一无所知。

英文:

ffmpeg can be made to output to stdout by adding pipe:. Per the docs:

> The accepted syntax is:
>
> pipe:[number]
>

> number is the number corresponding to the file descriptor of the pipe (e.g. 0 for stdin, 1 for stdout, 2 for stderr). If number is not specified, by default the stdout file descriptor will be used for writing, stdin for reading.

http://ffmpeg.org/ffmpeg-all.html#pipe

Personally I would use this in conjunction with a named pipe (FIFO):

mkfifo /tmp/videofifo
ffmpeg -i myfile.mp4 -f avi pipe: > /tmp/videofifo
with open("/tmp/videofifo", "rb") as f:
    ...

Of course, for your use case, you use your ffmpeg command, and you open the fifo in "r" not "rb" mode.

The advantage of using a fifo over just capturing stdout (with subprocess.PIPE directly is probably minimal in your case (ascii data linewise) but seems cleaner in the case of binary data. In any case I prefer to keep the data separate from how I got it. If you do just want to handle stdout directly, use p = subprocess.Popen(cmd, stdout=subprocess.PIPE) and then work on p.stdout, which is a file-like object.

Doubtless there are equivalent ways to launch subprocesses in Go, but to my shame I don't actually know Go at all at the moment.

huangapple
  • 本文由 发表于 2021年10月29日 16:57:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/69766148.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定