Gstreamer 将 RTP 流的多个片段记录到文件中

发布于 2025-01-14 08:35:56 字数 1155 浏览 1 评论 0原文

我正在使用 gstreamer 编写一个 C++ 应用程序,并试图实现以下目标:连接到 rtp 音频流(opus),将整个流的一份副本写入音频文件,然后另外基于用户触发的事件,创建由 rtp 流片段组成的一系列单独的音频文件(想象一下开始/停止录制切换按钮)。

目前使用udpsrc -> rtpbin-> rtpopusdepay->队列-> tee(此处管道分割)

tee_stream_1 ->队列-> webmmux->文件接收器

tee_stream_2 ->队列-> webmmux->文件接收器

tee_stream_1 应在管道的整个持续时间内处于活动状态。 tee_stream_2 应该根据用户切换事件生成多个文件。

示例场景:

  1. 管道接收 rtp 音频流,tee_stream_1 开始将音频写入 full_stream.webm
  2. 2 秒到 rtp 音频流中,用户切换“开始录制”。 tee_stream_2开始将音频写入stream_segment_1.webm
  3. 5秒到rtp音频流中,用户切换“停止录制”。 tee_stream_2 完成将音频写入stream_segment_1.webm 并关闭文件。
  4. 进入 rtp 音频流 8 秒后,用户切换“开始录制”。 tee_stream_2开始将音频写入stream_segment_2.webm
  5. 9秒到rtp音频流中,用户切换“停止录制”。 tee_stream_2 完成将音频写入stream_segment_2.webm 并关闭文件。
  6. 进入 rtp 音频流 10 秒后,流结束,full_stream.webm 完成音频写入并关闭。

最终结果是 3 个音频文件,full_stream.webm 包含 10 秒的音频,stream_segment_1.webm 包含 3 秒的音频,stream_segment_2.webm 包含 1 秒的音频。

到目前为止,尝试执行此操作遇到了困难,因为复用器似乎需要 EOS 事件才能正确完成stream_segment 文件的写入,但是此 EOS 会传播到管道的其他元素,这会产生结束所有流的不良影响。录音。关于如何最好地实现这一目标有什么想法吗?如果有帮助的话我可以提供代码。

感谢您提供的所有帮助!

I'm writing a c++ application with gstreamer and am trying to achieve the following: connect to an rtp audio stream (opus), write one copy of the entire stream to an audio file, and then additionally, based on events triggered by the user, create a separate series of audio files consisting of segments of the rtp stream (think a start/stop record toggle button).

Currently using udpsrc -> rtpbin -> rtpopusdepay -> queue -> tee (pipeline splits here)

tee_stream_1 -> queue -> webmmux -> filesink

tee_stream_2 -> queue -> webmmux -> filesink

tee_stream_1 should be active during the entire duration of the pipeline. tee_stream_2 is what should generate multiple files based on user toggle events.

An example scenario:

  1. pipeline receive rtp audio stream, tee_stream_1 begins writing audio to full_stream.webm
  2. 2 seconds into rtp audio stream, user toggles "start recording". tee_stream_2 begins writing audio to stream_segment_1.webm
  3. 5 seconds into rtp audio stream, user toggles "stop recording". tee_stream_2 finishes writing audio to stream_segment_1.webm and closes file.
  4. 8 seconds into rtp audio stream, user toggles "start recording". tee_stream_2 begins writing audio to stream_segment_2.webm
  5. 9 seconds into rtp audio stream, user toggles "stop recording". tee_stream_2 finishes writing audio to stream_segment_2.webm and closes file.
  6. 10 seconds into rtp audio stream, stream ends, full_stream.webm finishes writing audio and closes.

End result being 3 audio files, full_stream.webm with 10 seconds of audio, stream_segment_1.webm with 3 seconds of audio, and stream_segment_2.webm with 1 second of audio.

Attempts to do this so far have been met with difficulty since the muxers seem to require an EOS event to finish properly writing the stream_segment files, however this EOS is propogated to the other elements of the pipeline which has the undesired effect of ending all of the recordings. Any ideas on how to best accomplish this? I can provide code if it would be helpful.

Thank you for any and all assistance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

够运 2025-01-21 08:35:56

对于这种情况,我建议尝试 RidgeRun 的开源gstd 和 interpipe 插件,提供动态管道的高级控制。

您可以安装类似的东西:

# Some required packages to be installed, not exhaustive...
# If not enough you would see errors and figure out any other missing package
sudo apt install libsoup2.4-dev libjson-glib-dev libdaemon-dev libjansson-dev libreadline-dev gtk-doc-tools python3-pip

# Get gstd sources from github
git clone --recursive https://github.com/RidgeRun/gstd-1.x.git

# Configure, build and install (meson may be better, but here using autogen/configure
cd gstd-1.x
./autogen.sh 
./configure 
make -j $(nproc)
sudo make install
cd ..


# Get gst-interpipe sources from github
git clone --recursive https://github.com/RidgeRun/gst-interpipe.git

# Configure, build and install (meson may be better, but here using autogen/configure
cd gst-interpipe
./autogen.sh 
./configure 
make -j $(nproc)
sudo make install
cd ..

# Tell gstreamer about the new plugins interpipesink and interpipesrc
# First clear gstreamer cache (here using arm64, you would adapt for your arch)
rm ~/.cache/gstreamer-1.0/registry.aarch64.bin

# add new plugins path
export GST_PLUGIN_PATH=/usr/local/lib/gstreamer-1.0

# now any gstreamer command would rebuild the cache, so if ok this should work
gst-inspect-1.0 interpipesink

interpipes 需要一个管理守护进程,因此在第一个终端中您只需启动它即可。它将显示一些操作和错误(如果有):

gstd

现在在第二个终端中,您将尝试此脚本(此处记录到目录 /home/user/tmp/tmp2...根据您的情况进行调整):

#!/bin/sh

gstd-client pipeline_create rtpopussrc udpsrc port=5004 ! application/x-rtp,media=audio,encoding-name=OPUS,clock-rate=48000 ! queue ! rtpbin ! rtpopusdepay ! opusparse ! audio/x-opus ! interpipesink name=opussrc

gstd-client pipeline_create audio_record_full interpipesrc name=audiofull listen-to=opussrc is-live=true allow-renegotiation=true stream-sync=compensate-ts ! queue ! audio/x-opus ! opusparse ! webmmux ! filesink location=/home/user/tmp/tmp2/full_stream.webm


gstd-client pipeline_play rtpopussrc
gstd-client pipeline_play audio_record_full

sleep 2

gstd-client pipeline_create audio_record_1 interpipesrc name=audio_rec1 listen-to=opussrc is-live=true allow-renegotiation=true stream-sync=compensate-ts ! queue ! audio/x-opus ! opusparse ! webmmux ! filesink location=/home/user/tmp/tmp2/stream_segment_1.webm
gstd-client pipeline_play audio_record_1

sleep 3

gstd-client pipeline_stop audio_record_1
gstd-client pipeline_delete audio_record_1

sleep 3

gstd-client pipeline_create audio_record_2 interpipesrc name=audio_rec2 listen-to=opussrc is-live=true allow-renegotiation=true stream-sync=compensate-ts ! queue ! audio/x-opus ! opusparse ! webmmux ! filesink location=/home/user/tmp/tmp2/stream_segment_2.webm
gstd-client pipeline_play audio_record_2

sleep 1

gstd-client pipeline_stop audio_record_2
gstd-client pipeline_delete audio_record_2

sleep 1

gstd-client pipeline_stop audio_record_full
gstd-client pipeline_delete audio_record_full
gstd-client pipeline_stop rtpopussrc
gstd-client pipeline_delete rtpopussrc

echo 'Done'

并检查生成的文件。

For such case, I'd suggest to give a try to RidgeRun's open source gstd and interpipe plugins that provide high level control of dynamic pipelines.

You may install with something like:

# Some required packages to be installed, not exhaustive...
# If not enough you would see errors and figure out any other missing package
sudo apt install libsoup2.4-dev libjson-glib-dev libdaemon-dev libjansson-dev libreadline-dev gtk-doc-tools python3-pip

# Get gstd sources from github
git clone --recursive https://github.com/RidgeRun/gstd-1.x.git

# Configure, build and install (meson may be better, but here using autogen/configure
cd gstd-1.x
./autogen.sh 
./configure 
make -j $(nproc)
sudo make install
cd ..


# Get gst-interpipe sources from github
git clone --recursive https://github.com/RidgeRun/gst-interpipe.git

# Configure, build and install (meson may be better, but here using autogen/configure
cd gst-interpipe
./autogen.sh 
./configure 
make -j $(nproc)
sudo make install
cd ..

# Tell gstreamer about the new plugins interpipesink and interpipesrc
# First clear gstreamer cache (here using arm64, you would adapt for your arch)
rm ~/.cache/gstreamer-1.0/registry.aarch64.bin

# add new plugins path
export GST_PLUGIN_PATH=/usr/local/lib/gstreamer-1.0

# now any gstreamer command would rebuild the cache, so if ok this should work
gst-inspect-1.0 interpipesink

interpipes need a daemon that manages, so in a first terminal you would just start it. It will display some operations and errors if any:

gstd

Now in a second terminal you would try this script (here recording into directory /home/user/tmp/tmp2...adjust for your case):

#!/bin/sh

gstd-client pipeline_create rtpopussrc udpsrc port=5004 ! application/x-rtp,media=audio,encoding-name=OPUS,clock-rate=48000 ! queue ! rtpbin ! rtpopusdepay ! opusparse ! audio/x-opus ! interpipesink name=opussrc

gstd-client pipeline_create audio_record_full interpipesrc name=audiofull listen-to=opussrc is-live=true allow-renegotiation=true stream-sync=compensate-ts ! queue ! audio/x-opus ! opusparse ! webmmux ! filesink location=/home/user/tmp/tmp2/full_stream.webm


gstd-client pipeline_play rtpopussrc
gstd-client pipeline_play audio_record_full

sleep 2

gstd-client pipeline_create audio_record_1 interpipesrc name=audio_rec1 listen-to=opussrc is-live=true allow-renegotiation=true stream-sync=compensate-ts ! queue ! audio/x-opus ! opusparse ! webmmux ! filesink location=/home/user/tmp/tmp2/stream_segment_1.webm
gstd-client pipeline_play audio_record_1

sleep 3

gstd-client pipeline_stop audio_record_1
gstd-client pipeline_delete audio_record_1

sleep 3

gstd-client pipeline_create audio_record_2 interpipesrc name=audio_rec2 listen-to=opussrc is-live=true allow-renegotiation=true stream-sync=compensate-ts ! queue ! audio/x-opus ! opusparse ! webmmux ! filesink location=/home/user/tmp/tmp2/stream_segment_2.webm
gstd-client pipeline_play audio_record_2

sleep 1

gstd-client pipeline_stop audio_record_2
gstd-client pipeline_delete audio_record_2

sleep 1

gstd-client pipeline_stop audio_record_full
gstd-client pipeline_delete audio_record_full
gstd-client pipeline_stop rtpopussrc
gstd-client pipeline_delete rtpopussrc

echo 'Done'

and check resulting files.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文