英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论