龙空技术网

详解RTSP推流实战(1)

antonio 3502

前言:

此刻看官们对“c语言rtsp推流”可能比较关注,兄弟们都需要知道一些“c语言rtsp推流”的相关文章。那么小编在网摘上汇集了一些有关“c语言rtsp推流””的相关知识,希望朋友们能喜欢,大家快快来学习一下吧!

0.引言

本篇文章主要讲解RTSP推流实战,整体推流流程与RTMP推流流程类似。如果对于RTSP协议不了解,还可以参考前面的文章。文章参考列表如下:

RTSP协议交互流程之推流分析

手把手搭建RTSP流媒体服务器

详细解析RTSP框架和数据包分析(1)

RTSP协议交互流程之拉流分析

流媒体推拉流实战之RTMP协议分析(BAT面试官推荐)

超详细RTMP协议详解(资深流媒体架构师推荐)

音频编码实战(1)

聊聊视频直播延迟的几点优化

流媒体之推流拉流实战之关键点优化分析(2)

1.项目环境准备和演示

先准备好环境,准备好YUV文件和PCM文件。

执行如下命令:

(1)从文件提取pcm数据

ffmpeg -i a.mp3 -ar 48000 -ac 2 -f s16le 48000_2_s16le.pcm

(2)从文件提取yuv数据

ffmpeg -i b.mp4 -an -c:v rawvideo -pix_fmt yuv420p 720x480_25fps_420p.yuv

(3)将文件拷贝到如下目录:

(4)服务器使用EasyDarwin,仅仅当做测试使用。服务器上推流的打印,推流的过程描述。

(5)ffplay拉流测试命令:

ffplay -i rtsp://192.168.129.48/live/livestream

本地预览与拉流显示对比。

2.整体框架分析

音视频采集模块,经过采集后有数据就使用回调函数去调用音视频编码模块,音视频编码后首先就要放到队列,可以放到同一个队列或不同的队列。rtsp推流模块从队列里面去取数据。其框图和数据结构如下:

AudioCapture---->PcmCallback----->AACEncoder

------->post到队列------->RTSP_Pusher

VideoCapture----->YuvCallback------->H264Encoder

3.音视频采集

音视频采集都是独立的线程。CommonLooper实现一个线程的Looper。AudioCaptuer和VideoCapturer都会去继承CommonLooper。

(1).模拟的采集,是实时,按照播放速度去读取yuv/pcm数据。

(2).每帧数据都需要打上时间戳。重新封装了一个类,专门去打时间戳。

PushWork是一个开放个用户的类,由用户去设置参数等操作。参数类,使用key-value的方式去做。

(3)读取pcm数据,音频采集完数据后,通过回调函数callback_get_pcm_(pcm_buf_, nb_samples *4)发送出去。如下代码:

4.重采样

如果麦克风采集的声音的输出格式和编码音频的输入参数不一致(音频解码和音频播放不一致,也需要做重采样),那就需要做重采样。

(1)音频编码参数设置,如下代码:

(2)视频参数设置,如下代码:

(3)初始化视频编码器参数设置,如下代码:

这里的rtsp_debug设置为1,表示可以开启预览。

properties.SetProperty("rtsp_debug", 1)

(4)使用SDL开启预览,如下代码:

(5)读取用户设置的音视频参数,如下代码:

5.视频编码类H264Encoder

如果视频间隔不匀称,波动比较大,这里就做了一个帧间隔的校正算法,让帧间隔匀称。

(1)启动rtsp推流模块,并做初始化,如下代码:

(2)rtsp推流的时候,需要设置对应的音视频编码参数。如下:

为了防止连接时堵塞,开启连接超时机制。假如服务器卡死或断开,这个时候推流模块去连接就会堵住。所以要使用超时断开重连机制。

注意:在前面专门讲优化的文章分析过,为了节省时间,在初始化顺序,一定是首先初始化推流模块开启网络连接,因为网络比较比较耗时,可能会导致数据帧的缓存。具体原因可以看看前面讲优化的文章。音视频的捕获是放在最后面。如下顺序:

(3)设置和开启音频捕获,并设置回调,把捕获的数据发送给音频编码器。如下图:

(4)在音频采集的回调函数中开启开启编码。如下代码:

注意:ffmpeg 内置的aac编码器,需要的格式都是float的 planar的格式。

(5)设置和开启视频捕获,并设置回调,把捕获的数据发送给视频编码器。如下代码:

(6)在视频采集的回调函数中开启开启编码。如下代码:

注意:音视频采集回来就一定要去读取时间戳。

(7)编码后的音视频放到同一个队列,需要标记是音频包还是视频包。如下:

这里的推流模块rtsp_pusher,就会开一个线程,循环去推送。

(8)调用RTSPPusher::sendPacket(AVPacket *packet, RTSPMediaType_T mediatype)去发送数据。如下:

(9)关闭推流的流程,一般都是与初始化相反。关闭流程如下:

音频的capture->音频reseample->音频encoder->音频pusher。

视频的capture->视频reseample->视频encoder->视频pusher。

6.总结

本篇文章主要讲解了RTSP推流的主要流程和重要源码实战分析,理解完后,能够有一个整体分析。欢迎关注,收藏,转发,分享。

后期关于项目知识,也会更新在微信公众号“记录世界 from antonio”,欢迎关注

标签: #c语言rtsp推流