GStreamer appsrc 等插件实现视频音频混流,录制和推流

本文介绍了如何利用GStreamer的appsrc等插件,在线直播教室场景下,将老师屏幕、声音及学生声音混合并录制为视频文件,同时满足推流至腾讯视频服务的需求。通过命令行演示了具体流程,涉及的关键技术包括音频混流、编码、组装和推流等。

参考

使用 GStreamer appsrc 等插件实现视频音频混流,录制和推流
http://t.zoukankan.com/luckbird-p-GStreamer_appsrc.html

目前在做的在线直播教室,需要将老师分享的屏幕和老师的声音、学生的声音录制为一个视频文件,以便学生上课后还可以再看回放。

直播服务我们采用的是腾讯的视频服务,有现成的 SDK 可以用。但 SDK 自带的录制接口满足不了我们的需求,考察了 ffmpeg 和 GStreamer 后,决定在项目中使用 GStreamer 来实现。

在开始编写代码以前,先用命令行进行测试,命令行如下:

gst-launch-1.0.exe -v --gst-debug-level=4 flvmux name=mux ! tee name=t ! queue ! filesink name=file location=test.flv
t. ! queue ! rtmpsink location=“rtmp://live.abc.com/live/…”
adder name=mix ! queue ! audiorate ! audioconvert ! voaacenc ! mux.audio
videotestsrc name=screen_src ! queue ! videorate ! x264enc ! mux.video
audiotestsrc name=send_audio_src ! queue ! audiorate ! mix.
audiotestsrc wave=5 name=receive_audio_src ! queue ! audiorate ! mix.

命令看起来有点复杂,但其实逻辑挺简单的,看下面这个逻辑图就比较容易理解了(点击查看大图)
上面的命令中的推流地址需要替换为你的推流地址,如果没有,可以先把下面这部分内容去掉不推流

t. ! queue ! rtmpsink location=“rtmp://live.abc.com/live/…”
另外这个命令是在 Windows 中的 MINGW64 的 bash 环境里面运行的, 如果在 Windows 的 cmd 环境中运行,把每行最后的 和换行去掉就可以了。

上面命令中用到了几个关键的插件,分别解释一下:

adder: 音频混流,将两路音频混为一路

voaacenc:音频编码,将原始的音频流编码为 aac 格式

x264enc:视频编码,将原始的视频流编码为 h264 格式

flvmux:flv 组装,将视频和音频组装在一起

tee:分流器,将一路输入变为两路输出,以分别进行后续的处理。一路保存为文件,一路进行推流

filesink:文件存储,将输入数据存储到指定的文件中

rtmpsink:推流,将输入数据推流到指定的视频服务器

在这里插入图片描述

GStreamer实现音频视频的同步,通常采用以音频时钟作为参考时钟的方法。参考时钟上的时间需线性递增,在生成数据时,依据参考时钟的时间给每个数据块都打上时间戳,一般包含开始时间结束时间。在播放时,读取数据上的时间戳,同时参考当前参考时钟上的时间来安排播放。若数据块上的时间大于参考时钟的时间,则不急于播放,直到参考时钟达到数据块的开始时间;若数据块上的时间小于参考时钟的时间,则应“尽快”播放或者干脆“丢弃”该数据块,以使得播放赶上播放进度[^1]。 默认情况下,由 AudioSink 提供参考时钟。以下是关于时钟相关的代码示例,展示了时钟的创建时间获取等操作: ```c /* gst-plugins-base-0.10.32/gst-libs/gst/audio/gstbaseaudiosink.c */ /*默认的情况下是由这个element来提供clock的。*/ #define DEFAULT_PROVIDE_CLOCK TRUE static void gst_base_audio_sink_init (GstBaseAudioSink * baseaudiosink, GstBaseAudioSinkClass * g_class) { baseaudiosink->provide_clock = DEFAULT_PROVIDE_CLOCK; /* 这里在clock类里面新建了一个时钟 */ baseaudiosink->provided_clock = gst_audio_clock_new ("GstAudioSinkClock", (GstAudioClockGetTimeFunc) gst_base_audio_sink_get_time, baseaudiosink); } /* * 查询是否 @sink 将提供 clock */ gboolean gst_base_audio_sink_get_provide_clock (GstBaseAudioSink * sink) { gboolean result; result = sink->provide_clock; return result; } /* 查询clock的时间 * 如果将这里的返回结果变慢,那么视频播放就会变慢。当然视频音频就不同步了。 */ static GstClockTime gst_base_audio_sink_get_time (GstClock * clock, GstBaseAudioSink * sink) { result = gst_util_uint64_scale_int (samples, GST_SECOND, sink->ringbuffer->spec.rate); return result; } ``` 在使用 GStreamer 进行时,也可以使用 `appsrc` 等插件实现视频音频混流录制。以下是一个使用 `gst-launch-1.0` 命令的示例: ```bash gst-launch-1.0.exe -v --gst-debug-level=4 flvmux name=mux ! tee name=t ! queue ! filesink name=file location=test.flv t. ! queue ! rtmpsink location="rtmp://live.abc.com/live/..." adder name=mix ! queue ! audiorate ! audioconvert ! voaacenc ! mux.audio videotestsrc name=screen_src ! queue ! videorate ! x264enc ! mux.video audiotestsrc name=send_audio_src ! queue ! audiorate ! mix. audiotestsrc wave=5 name=receive_audio_src ! queue ! audiorate ! mix. ``` 此命令通过 `flvmux` 进行音视频的混合,将一路视频两路音频混合后,一部分保存为本地文件,一部分送到 RTMP 服务器,在这个过程中可以通过时间戳等机制保证音视频同步[^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值