基于移动平台的多媒体框架——使用live555接收流媒体方法简介
更多关于live555的详细信息请参考官网:http://www.live555.com
为什么要用live555?因为mplayer和vlc这两个著名的项目都用了,由此也能反映出live555这个库的重要价值。
关于流媒体的基本知识就不赘述了。本文着重介绍如何使用live555这个库使得播放器支持播放流媒体格式的文件。
简述一下live555的主要目录结构。
UsageEnvironment
groupsock
liveMedia
BasicUsageEnvironment
testProgs
主要有这5个目录,其他关于live555分析的文章里介绍过很多里,具体的介绍还是可以看官网的描述。这里着重介绍两个目录:
1. mediaServer 该目录不在上述5个主要目录中列出,其中有个小程序,名叫live555MediaServer。这是个使用live555库写出的一个流媒体服务器,功能就是将本地的视频文件变成媒体流。使用方法也很简单,只要运行这个文件,就可以将当前目录下所有的支持流化格式的多媒体文件进行流化。如图所示:
这里就可以看到对应的rtsp的地址,以及其所支持的文件类型。
根据我的简单测试,发现这个服务器还不是很稳定,有时候会崩溃。如果你需要一个比较稳定的流服务器,还是建议参考前面的一篇
2. 第二个会用到的目录是testProgs。编译好后会看到里面有许多测试程序。这里提到一个叫做openRTSP的程序,这是live555做的一个比较完整的接收rtsp流的工程。运行./openRTSP rtsp://IP:PORT/FILENAME之后,就会在当前目录下看到一个以video-MPV-开头的文件,这就是openRTSP接受到流后然后保存在本地的文件。
虽然这个openRTSP已经做的比较稳定,功能也很完整,但是如果要用live555开发自己的RTSP应用程序,不建议基于这个程序,而比较建议基于一个叫做testRTSPClient的小而简单的测试程序。可以打开openRTSP看到作者在注释中写到的:
// NOTE: If you want to develop your own RTSP client application (or embed RTSP client functionality into your own application), // then we don't recommend using this code as a model, because it is too complex (with many options). // Instead, we recommend using the "testRTSPClient" application code as a model.
相反,testRTSPClient中的注释写的是:
// NOTE: This code - although it builds a running application - is intended only to illustrate how to develop your own RTSP // client application. For a full-featured RTSP client application - with much more functionality, and many options - see // "openRTSP": http://www.live555.com/openRTSP/
所以,我们就可以参考testRTSPClient的程序写我们自己的流媒体播放器。
关于RTSP协议,这张图可以比较简单的描述:
需要收发的包有:OPTIONS DESCRIBE SETUP SET_PARAMETER PLAY TEARDOWN 这几种。在testRTSPClient中,我们只用到DESCRIBE SETUP PLAY TEARDOWN这四种进行顺序发送。对前三种包的发送分别定义回调函数进行接受,接收到之后相应的事务在回调函数中处理。
// RTSP 'response handlers': void continueAfterDESCRIBE(RTSPClient* rtspClient, int resultCode, char* resultString); void continueAfterSETUP(RTSPClient* rtspClient, int resultCode, char* resultString); void continueAfterPLAY(RTSPClient* rtspClient, int resultCode, char* resultString);在收到PLAY reply之后,将收到的数据传入一个sink中就可以用sink进行播放了。在testRTSPClient中,我们实现了一个非常简单的sink,只负责打印收到的每一帧的时间戳。
// Define a data sink (a subclass of "MediaSink") to receive the data for each subsession (i.e., each audio or video 'substream'). // In practice, this might be a class (or a chain of classes) that decodes and then renders the incoming audio or video. // Or it might be a "FileSink", for outputting the received data into a file (as is done by the "openRTSP" application). // In this example code, however, we define a simple 'dummy' sink that receives incoming data, but does nothing with it. class DummySink: public MediaSink
用我们需要进行解码播放的函数实现一个sink,就可以得到一个完整的从接受rtsp流到播放出画面的流媒体播放器了。