文獻標識碼: A
文章編號: 0258-7998(2014)09-0111-03
流媒體指視頻、音頻、文本字幕等不同格式的多媒體數(shù)據(jù)用實時網(wǎng)絡傳輸協(xié)議作為媒介承載,并以連續(xù)媒體流的形式從源發(fā)送端向目的接收端傳輸,在目的端接收到一定的緩存數(shù)據(jù)后,就可以將上述流播放出來的網(wǎng)絡多媒體內(nèi)容,是在網(wǎng)絡上按時間先后次序傳輸和播放的連續(xù)音/視頻數(shù)據(jù)流[1]。3G、4G的普及和移動終端日新月異的發(fā)展為移動直播系統(tǒng)提供了一定的技術保證,視頻拍攝和視頻數(shù)據(jù)傳輸是3G/4G手機的基本功能,隨著計算機處理能力的提升以及圖像處理能力和網(wǎng)絡通信的不斷成熟,每個手機用戶都有了進行視頻直播的可能,使得直播系統(tǒng)已經(jīng)進入高速發(fā)展的時期。
1 總體框架設計
移動直播系統(tǒng)主要包括移動設備端、服務器端和播放器三部分,基本流程包括移動終端現(xiàn)場視頻的拍攝、壓縮編碼、視頻數(shù)據(jù)格式封裝、RTP封裝和數(shù)據(jù)發(fā)送,及本地錄像數(shù)據(jù)的保存并在3G/Wi-Fi下進行上傳;接收端實現(xiàn)接收數(shù)據(jù)、解封裝、數(shù)據(jù)儲存、視頻信號發(fā)生,主要采用市場已有的支持rtsp協(xié)議的主流播放器,可進行二次開發(fā)擴展;流媒體服務器實現(xiàn)根據(jù)播放器的請求對移動設備端的視頻數(shù)據(jù)進行轉(zhuǎn)發(fā),以及采用RTCP控制協(xié)議優(yōu)化移動設備端的碼率,自適應網(wǎng)絡帶寬,以求最佳的用戶體驗;RTSP信令服務器負責系統(tǒng)中信令消息的傳輸、轉(zhuǎn)發(fā),是系統(tǒng)通信協(xié)議實現(xiàn)的關鍵部分,同時又要負責對系統(tǒng)中各個終端的管理,完成發(fā)送端、接收端和RTSP信令服務器的交互會話。這種平臺化的設計既方便了對移動設備端和播放器端的統(tǒng)一管理,又能增強系統(tǒng)整體的負載能力。移動直播系統(tǒng)的設計框架如圖1所示。
2 移動直播系統(tǒng)模塊設計
由于移動直播系統(tǒng)的播放器軟件采用VLC開源播放器為例,所以主要介紹流媒體服務器的模塊設計和iOS數(shù)據(jù)采集軟件的模塊設計。
2.1 流媒體服務器模塊設計
流媒體服務器主要包括如圖2所示的功能模塊。
圖2中各模塊功能:(1)VLC視頻請求模塊:主要負責當VLC播放器發(fā)生視頻請求時,根據(jù)視頻請求查找請求的設備是否在線,如果在線則通知視頻直播數(shù)據(jù)轉(zhuǎn)發(fā)模塊轉(zhuǎn)發(fā)所請求的視頻數(shù)據(jù);(2)直播數(shù)據(jù)轉(zhuǎn)發(fā)模塊:負責所有的視頻數(shù)據(jù)轉(zhuǎn)發(fā),主要實現(xiàn)同時直播多路時的負載均衡,最大程度地減輕服務器壓力;(3)視頻點播模塊:主要是采用蘋果公司所特有的HLS(HTTP Live Streaming)技術,實現(xiàn)對iOS直播軟件端保存的視頻文件進行隨時隨地的點播回放。
項目選擇以live555開源庫作為基礎庫,設計出符合功能和性能要求的流媒體轉(zhuǎn)發(fā)服務器。以下簡單介紹利用live555開源庫開發(fā)出一個實現(xiàn)流媒數(shù)據(jù)流轉(zhuǎn)發(fā)的服務器。
TaskScheduler* scheduler=BasicTaskScheduler::createNew();
UsageEnvironment* env=BasicUsageEnvironment::createNew(*scheduler);
這里創(chuàng)建兩個關鍵的對象用于事件調(diào)度,實現(xiàn)了對事件的異步讀取、對事件句柄的設置及對錯誤信息的輸出等,是整個事件驅(qū)動的核心。
RTSPServer* rtspServer=RTSPServer::createNew(*env,8554,authDB);//authDB為用戶驗證的用戶數(shù)據(jù)庫
ServerMediaSession* sms=ServerMediaSession::createNew(*env, streamName, streamName,descriptionString);
MPEG2TransportUDPServerMediaSubsession* mpeg2=MPEG2TransportUDPServerMediaSubsession::createNew(*env,inputAddressStr,inputPortNum, inputStreamIsRawUDP);
sms->addSubsession(mpeg2);
rtspServer->addServerMediaSession(sms);
這里是在端口8554上建立一個RTSP服務負責與VLC客戶端之間的會話,并新建一個MPEG2數(shù)據(jù)流轉(zhuǎn)發(fā)的MediaSession添加到RTSP服務中。MPEG2對應一個數(shù)據(jù)源,sms作為RTSP服務的數(shù)據(jù)源會話。當有VLC客戶端請求時,進行用戶驗證,如驗證通過則從數(shù)據(jù)源獲取數(shù)據(jù)進行數(shù)據(jù)轉(zhuǎn)發(fā)。這樣一個簡單的服務就建立起來了。
2.2 iOS數(shù)據(jù)采集軟件的模塊設計
iOS設備數(shù)據(jù)采集端主要包括如圖3所示的功能模塊。
圖3中各主要模塊的功能:(1)H.264編碼:將攝像頭采集到的原始圖像數(shù)據(jù)進行H.264壓縮編碼,便于在網(wǎng)絡中傳輸,減少發(fā)送到網(wǎng)絡中的碼率[2];(2)TS碼流封裝:基于MPEG-2標準(ISO13818-1)的視頻壓縮編碼,將H.264編碼出的ES流打包成PES流, PES流再按188 B的固定長度加上必要的節(jié)目專用信息PSI組成傳送TS碼流;(3)本地保存:設備在直播的同時對攝像頭采集編碼出的TS流數(shù)據(jù)進行保存,為了用戶能實現(xiàn)對歷史錄像進行觀看,主要包含兩個文件,一個是.M3U8文件,用于單碼率適配流的HLS技術,項目中只用到了一種CIF碼率,另一個是.ts文件,存儲視頻數(shù)據(jù)的切片媒體文件;(4)本地HLS和本地播放:建立本地HLS服務,本地回看錄像文件。
以下是軟件實現(xiàn)過程的簡單介紹。
do {
if (self.avCaptureSession!=nil) break;
[self vcrEncoderInit];
//對原始數(shù)據(jù)采集所需的一些變量進行初始化
[self cameraSetting]; //對攝像頭的參數(shù)進行設置
} while (0);
[self startVideoCapture]; //啟動攝像頭采集實時視頻幀
將采集的原始數(shù)據(jù)通ffmpeg庫進行H.264編碼,根據(jù)MPEG-2標準(ISO13818-1)的視頻壓縮編碼,將H.264編碼出的ES流打包成PES流,PES流再按188 B的固定長度加上必要的節(jié)目專用信息PSI組成傳送TS碼流[3-4],并進行本地保存。
av_register_all();//注冊編碼器
pCodec=avcodec_find_encoder(AV_CODEC_ID_H264);//查找H264編碼器
pcodecCtx=avcodec_alloc_context3(pCodec);//分配編碼器上下文內(nèi)存空間
avcodec_open2(pcodecCtx, pCodec, NULL);//打開H264編碼器
_m_yuvFrame=avcodec_alloc_frame();//分配yuv圖像幀內(nèi)存空間
m_rgbFrame=avcodec_alloc_frame();//分配rgb圖像格式的內(nèi)存空間
swsCtx=sws_getContext(pcodecCtx->width, pcodecCtx->height, PIX_FMT_BGRA, pcodecCtx->width, pcodecCtx->
height, PIX_FMT_YUV420P, SWS_FAST_BILINEAR, NULL, NULL, NULL);//rgb轉(zhuǎn)為yuv圖像轉(zhuǎn)換的上下文句柄
int nbytes=avpicture_get_size(PIX_FMT_YUV420P, pcodecCtx->width, pcodecCtx->height);
outbuffer=(uint8_t*)av_malloc(nbytes);
avpicture_fill((AVPicture*)_m_yuvFrame, outbuffer,
PIX_FMT_YUV420P, pcodecCtx->width, pcodecCtx->height);//設置outbuffer為yuv圖像幀buffer
ofmt = av_guess_format("mpegts", NULL, NULL);//輸出格式為mpegts
_oc = avformat_alloc_context();//分配輸出到文件的上下文內(nèi)存空間
_oc->oformat = ofmt;//設置輸出格式
avio_open(&_oc->pb, output, AVIO_FLAG_WRITE);//以寫格式打開文件
avformat_write_header(_oc, &pAVDictionary);//寫入ts的節(jié)目專用信息頭
上面都是為接下來的編碼和本地保存做準備工作。
avpicture_fill((AVPicture*)m_rgbFrame, buffer, PIX_FMT_BGRA, width, height);
int rec=sws_scale(swsCtx, (const uint8_t**)m_rgbFrame->data, m_rgbFrame->linesize, 0, pcodecCtx->height,_m_yuvFrame->data, _m_yuvFrame->linesize);
int state=avcodec_encode_video2(pcodecCtx, &avpakt, _m_yuvFrame, &got_packet_ptr);//將原始數(shù)據(jù)編碼成H264裸數(shù)據(jù)
[self TSpacket:&avpakt];//打包
int nRet = av_interleaved_write_frame(_oc, packet);//將ts數(shù)據(jù)寫入本地文件
[delegate_sendData SendH264Data:_oc->pb->buffer+havepk*188 Size:tspk*188];//rtp打包ts流數(shù)據(jù)進行流媒體直播
av_free_packet(packet);//釋放內(nèi)存
HLS是一個由蘋果公司提出的基于HTTP的流媒體網(wǎng)絡傳輸協(xié)議。本項目的本地播放錄像功能所采用的也是HLS協(xié)議,在手機本地搭建一個輕量級的Web服務,只需要支持靜態(tài)文件訪問,然后調(diào)用系統(tǒng)的播放器類播放本地的M3U8文件即可。實現(xiàn)如下:
httpServer = [[HTTPServer alloc] init];[httpServer setType:@"_http._tcp."]; [httpServer setPort:52479];[httpServer setDocumentRoot:filePath]; [httpServer start:&error];//建立輕量級本地Web服務
然后即可調(diào)用系統(tǒng)播放組件MPMoviePlayerController進行播放,這樣一個基于流媒體技術的移動視頻直播系統(tǒng)的實現(xiàn)基本完成。
3 移動直播系統(tǒng)測試
在實驗室網(wǎng)絡條件下,分別從RTSP用戶驗證、VLC視頻請求播放、流媒體視頻轉(zhuǎn)發(fā)、iOS視頻采集軟件、本地播放錄像四方面對移動直播系統(tǒng)進行測試。結(jié)果軟件運行正常,VLC視頻直播圖像較為清晰流暢,無明顯時延,用戶體驗較好,達到了實時播放的效果。各界面效果如圖4~圖7所示。
綜上所述,該移動直播系統(tǒng)利用手機終端的便利性,能夠在任何場景利用手機進行拍攝;并且使用3G/4G網(wǎng)絡連接手機移動直播平臺,就可以在互聯(lián)網(wǎng)上實現(xiàn)對突發(fā)事件的現(xiàn)場同步播出,或者在網(wǎng)絡條件不好的情況下保存本地,而后進行上傳,供其他用戶隨時隨地地點播錄像視頻,足以應付基本的突發(fā)事件。利用手機的視頻拍攝和傳送能力,開發(fā)即時視頻直播系統(tǒng)將會帶來巨大的市場效應。
參考文獻
[1] 程瀅穎.移動終端上視頻直播系統(tǒng)的研究與設計[D].上海:華東理工大學,2012.
[2] 方濤.數(shù)字電視業(yè)務信息及其編碼[M].北京:國防工業(yè)出版社,2003.
[3] 路錦正.MPEG-4/H.264視頻編解碼工程實踐[M].北京:電子工業(yè)出版社,2011.
[4] ISO/IEC 13818-1 information technology-generic coding of moving pictures and associated audio[S]:Syetems Recommendation H.222.0,1994.