1.Miracast技术详解(四):Sink源码解析
2.每日开源:一个巨硬的产品级嵌入式流媒体库
3.音视频开源项目ZLMediaKit 的安装及使用介绍
Miracast技术详解(四):Sink源码解析
Miracast Sink端源码最早出现在Android 4.2.2版本中,可通过android.googlesource.com查看。然而,在Android 4.3版本之后,Google移除了这部分源码,详细移除记录可在android.googlesource.com上查阅。hla与DdS源码尽管Sink端代码被移除,但Source端源码依然存在。通过使用Android手机的投射功能,仍可实现Miracast投屏发送端的功能。
为了查看源码,推荐使用Android Studio,以便利用IDE的代码提示和类/方法跳转功能。首先新建一个Native Project,将libstagefright相关源码拷贝至cpp目录,并导入必要的include头文件。在CMakeLists.txt中添加这部分源码后,同步环境,以此引用相关类与头文件,提升查看源码的效率。
Sink端核心类主要包括:WifiDisplaySink.cpp、RTPSink.cpp、TunnelRenderer.cpp。通过分析可得知,初始化操作主要在wfd.cpp中的glm源码main()方法内完成,重点关注sink->start()方法启动WifiDisplaySink,进而使用ip和端口参数执行相关操作。
RTSP通讯涉及关键步骤,包括创建RTSP TCP连接、处理连接状态与数据异步通知。当连接建立后,开始进行RTSP协商与会话建立,处理RTSP M1-M7指令。请求与响应流程需参考前面的RTSP协议分析文章,这里不详细展开。
处理RTSP消息时,首先判断消息类型,是Request还是Response。对于Request,主要处理Source端M1请求,并响应M2确认。对于Source端M3请求,处理相关属性及能力,如RTP端口号、支持的音频和视频编解码格式等。M4与M5请求则分别进行常规的响应处理。
在发送完Setup M6请求后,注册onReceiveSetupResponse()回调,用于完成RTSP最后一步,865源码即发送PLAY M7请求。此时,Source端会按照Sink指定的UDP端口发送RTP数据包,包含音视频数据。
RTSP协商与会话建立完成后,数据流通过RTPSink处理,建立UDP连接并解析RTP数据包。在TunnelRenderer中接收并播放音视频流。流程包括消息处理、环境初始化、TS包解析、音视频裸流解码与播放等。
源码解析过程中,关键步骤包括初始化RTPSink、建立UDP连接、处理RTP与RTCP数据、解析TS包并获取音视频裸流等。移植Native Sink端难点在于隔离与处理Native相关依赖,如异步消息机制、网络连接实现等。建议在应用层实现RTSP连接、音视频解码与渲染功能,然后移植底层解析代码,以减少依赖,slick源码提高移植效率。
每日开源:一个巨硬的产品级嵌入式流媒体库
哈喽,我是老吴。
今天分享一个比较复杂的开源项目:live 是一个开源的流媒体库,用于实现实时流媒体的传输和处理。它提供了一套跨平台的 C++ 类库,帮助快速构建高效、可靠的流媒体服务器和客户端应用程序。
live的代码量庞大,约9w行代码。如果专注于核心逻辑,代码量缩减到约8K行。使用live,你可以收获高效可靠的流媒体库,了解产品级的C++项目设计,掌握音视频基础知识,甚至获得基于select()的C++事件循环库。live在媒体播放器、流媒体服务器、视频监控系统等领域应用广泛,如VLC、FFmpeg、GStreamer均使用live实现流媒体的接收和播放。
live基于C++,源码pom语法相对简单,适合专注于学习C++类设计和编写专业的C++软件。为了理解源码,需要补充多媒体、流媒体的理论知识。通过阅读和运行相关应用,加深对理论知识的理解。
编译live库后,会生成4个静态库:libBasicUsageEnvironment.a和libUsageEnvironment.a用于实现事件循环、上下文管理、任务管理等;libliveMedia.a负责多媒体流化,包括音视频编解码、流媒体协议实现;libgroupsock.a负责网络IO功能,核心是TCP、UDP的读写。简单示例是RTP传输MP3音频,涉及server和client两个程序。
server程序的核心逻辑包括准备运行环境、设置数据来源、设置数据目的地。TaskScheduler用于任务管理,基于select()实现事件循环。BasicUsageEnvironment用于上下文管理。数据流化本质是网络传输,Source和Sink分别表示数据源和目的地,本例中Source是MP3FileSource,Sink是MPEG1or2AudioRTPSink。client端程序同样初始化Source和Sink。
RTP协议简介,RTP(Real-time Transport Protocol)是一种用于实时传输音频和视频数据的网络传输协议,基于UDP,用于在IP网络上传输实时媒体数据。RTP协议设计目标是提供低延迟、高效率的传输,以满足实时应用需求。主要特点包括时间戳、序列号、负载类型、NACK反馈和RTCP(Real-time Transport Control Protocol)等。
关键问题是如何实现数据一帧帧流化?关注点不是具体音视频格式解析或特定协议实现,而是live对音视频流化的整体框架。通过示例分析,live本质上将音视频数据逐帧解码,通过RTP协议经网络发送。live封装了多种数据Source和Sink,但无需详细了解每个概念。仍以RTP传输MP3数据为例,分析live的工作流程。
首先,需要对相关类的关系有大概概念:MediaSource是所有Source的父类,各种具体音视频Source基于其派生;MediaSink是所有Sink的父类,派生出FileSink、RTPSink等众多Sink类。Sink类最关键的成员函数是startPlaying(),用于使用Source对象获取帧数据,然后发送至网络。
RTP传输MP3的主要逻辑包括准备就绪后调用MediaSink::startPlaying()启动数据流化,在packFrame()调用Source对象的getNextFrame()。getNextFrame()最终调用MP3FileSource的doGetNextFrame(),负责MP3音频解码,解码完成后,回调afterGettingFrame(),正常时调用sendPacketIfNecessary()发送数据,并添加至事件循环调度器中。一段时间后,MultiFramedRTPSink的sendNext()被调用,推动新一帧数据传输,直到Source中的所有帧数据被消费。
live如何创建RTSP服务器?通常RTP协议与RTSP协议结合使用,对外提供RTSP服务器服务。RTSP提供控制实时流媒体传输和播放的标准化方式,可以控制播放、暂停、停止、快进、后退等功能。添加几行代码即可创建RTSP服务器。RTSP服务器封装实现RTSP服务,类似HTTP协议,是文本协议。服务器包括接受客户端连接、读取客户端数据、解析和处理数据的操作。
总结,live是一个开源的多媒体流媒体库,支持常见流媒体协议,提供高效可靠的流媒体传输功能,适用于构建流媒体服务器和客户端应用程序。使用live需要熟悉C++编程和网络编程知识,官方提供丰富示例代码,帮助快速熟悉库的使用方法。
音视频开源项目ZLMediaKit 的安装及使用介绍
ZLMediaKit是一个功能强大的开源流媒体服务器,特别适合实时音视频传输和处理应用,如直播、视频会议和监控。它支持RTSP、RTMP、HLS和HTTP-FLV等协议,具有低延迟和高并发处理能力,且能动态转码,并跨平台运行。 要开始使用,首先从GitHub地址github.com/xia-chu/ZLMe...下载源代码。编译安装步骤适用于Linux环境,运行时可通过其HTTP API进行管理。API接口包括控制流媒体播放、获取状态信息、统计信息,以及配置服务器参数等,如:启动/停止流媒体:通过发送HTTP请求来控制。
查看状态和统计:获取服务器连接数、流状态和带宽使用情况等。
配置参数:如设置网络端口、转码设置和录制选项。
录制与截图:支持控制服务器的录制和截图功能。
实时监控:通过HTTP API监控服务器运行和日志。
此外,HTTP API还支持通过UDP或TCP进行推流,例如循环播放视频,对于点播,ZLMediaKit支持通过mp4文件实现,例如rtsp://.../record/test.mp4,通过HTTP访问文件进行点播。 在Linux下,音频设备的管理也很关键,可以使用aplay、pactl等命令查看和配置音频设备。而服务的推拉流,包括设备向服务器推流和从服务器拉流,也是通过API和相应的命令来操作的。 最后,当遇到端口占用问题时,可以使用lsof和netstat命令在Linux中查找占用情况,以便进行相应的操作。ZLMediaKit的详细文档和更多视频教程可以在mirrors/xia-chu/zlmediakit/GitCode中找到。