文献标识码: A
文章编号: 0258-7998(2014)09-0111-03
流媒体指视频、音频、文本字幕等不同格式的多媒体数据用实时网络传输协议作为媒介承载,并以连续媒体流的形式从源发送端向目的接收端传输,在目的端接收到一定的缓存数据后,就可以将上述流播放出来的网络多媒体内容,是在网络上按时间先后次序传输和播放的连续音/视频数据流[1]。3G、4G的普及和移动终端日新月异的发展为移动直播系统提供了一定的技术保证,视频拍摄和视频数据传输是3G/4G手机的基本功能,随着计算机处理能力的提升以及图像处理能力和网络通信的不断成熟,每个手机用户都有了进行视频直播的可能,使得直播系统已经进入高速发展的时期。
1 总体框架设计
移动直播系统主要包括移动设备端、服务器端和播放器三部分,基本流程包括移动终端现场视频的拍摄、压缩编码、视频数据格式封装、RTP封装和数据发送,及本地录像数据的保存并在3G/Wi-Fi下进行上传;接收端实现接收数据、解封装、数据储存、视频信号发生,主要采用市场已有的支持rtsp协议的主流播放器,可进行二次开发扩展;流媒体服务器实现根据播放器的请求对移动设备端的视频数据进行转发,以及采用RTCP控制协议优化移动设备端的码率,自适应网络带宽,以求最佳的用户体验;RTSP信令服务器负责系统中信令消息的传输、转发,是系统通信协议实现的关键部分,同时又要负责对系统中各个终端的管理,完成发送端、接收端和RTSP信令服务器的交互会话。这种平台化的设计既方便了对移动设备端和播放器端的统一管理,又能增强系统整体的负载能力。移动直播系统的设计框架如图1所示。
2 移动直播系统模块设计
由于移动直播系统的播放器软件采用VLC开源播放器为例,所以主要介绍流媒体服务器的模块设计和iOS数据采集软件的模块设计。
2.1 流媒体服务器模块设计
流媒体服务器主要包括如图2所示的功能模块。
图2中各模块功能:(1)VLC视频请求模块:主要负责当VLC播放器发生视频请求时,根据视频请求查找请求的设备是否在线,如果在线则通知视频直播数据转发模块转发所请求的视频数据;(2)直播数据转发模块:负责所有的视频数据转发,主要实现同时直播多路时的负载均衡,最大程度地减轻服务器压力;(3)视频点播模块:主要是采用苹果公司所特有的HLS(HTTP Live Streaming)技术,实现对iOS直播软件端保存的视频文件进行随时随地的点播回放。
项目选择以live555开源库作为基础库,设计出符合功能和性能要求的流媒体转发服务器。以下简单介绍利用live555开源库开发出一个实现流媒数据流转发的服务器。
TaskScheduler* scheduler=BasicTaskScheduler::createNew();
UsageEnvironment* env=BasicUsageEnvironment::createNew(*scheduler);
这里创建两个关键的对象用于事件调度,实现了对事件的异步读取、对事件句柄的设置及对错误信息的输出等,是整个事件驱动的核心。
RTSPServer* rtspServer=RTSPServer::createNew(*env,8554,authDB);//authDB为用户验证的用户数据库
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数据流转发的MediaSession添加到RTSP服务中。MPEG2对应一个数据源,sms作为RTSP服务的数据源会话。当有VLC客户端请求时,进行用户验证,如验证通过则从数据源获取数据进行数据转发。这样一个简单的服务就建立起来了。
2.2 iOS数据采集软件的模块设计
iOS设备数据采集端主要包括如图3所示的功能模块。
图3中各主要模块的功能:(1)H.264编码:将摄像头采集到的原始图像数据进行H.264压缩编码,便于在网络中传输,减少发送到网络中的码率[2];(2)TS码流封装:基于MPEG-2标准(ISO13818-1)的视频压缩编码,将H.264编码出的ES流打包成PES流, PES流再按188 B的固定长度加上必要的节目专用信息PSI组成传送TS码流;(3)本地保存:设备在直播的同时对摄像头采集编码出的TS流数据进行保存,为了用户能实现对历史录像进行观看,主要包含两个文件,一个是.M3U8文件,用于单码率适配流的HLS技术,项目中只用到了一种CIF码率,另一个是.ts文件,存储视频数据的切片媒体文件;(4)本地HLS和本地播放:建立本地HLS服务,本地回看录像文件。
以下是软件实现过程的简单介绍。
do {
if (self.avCaptureSession!=nil) break;
[self vcrEncoderInit];
//对原始数据采集所需的一些变量进行初始化
[self cameraSetting]; //对摄像头的参数进行设置
} while (0);
[self startVideoCapture]; //启动摄像头采集实时视频帧
将采集的原始数据通ffmpeg库进行H.264编码,根据MPEG-2标准(ISO13818-1)的视频压缩编码,将H.264编码出的ES流打包成PES流,PES流再按188 B的固定长度加上必要的节目专用信息PSI组成传送TS码流[3-4],并进行本地保存。
av_register_all();//注册编码器
pCodec=avcodec_find_encoder(AV_CODEC_ID_H264);//查找H264编码器
pcodecCtx=avcodec_alloc_context3(pCodec);//分配编码器上下文内存空间
avcodec_open2(pcodecCtx, pCodec, NULL);//打开H264编码器
_m_yuvFrame=avcodec_alloc_frame();//分配yuv图像帧内存空间
m_rgbFrame=avcodec_alloc_frame();//分配rgb图像格式的内存空间
swsCtx=sws_getContext(pcodecCtx->width, pcodecCtx->height, PIX_FMT_BGRA, pcodecCtx->width, pcodecCtx->
height, PIX_FMT_YUV420P, SWS_FAST_BILINEAR, NULL, NULL, NULL);//rgb转为yuv图像转换的上下文句柄
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();//分配输出到文件的上下文内存空间
_oc->oformat = ofmt;//设置输出格式
avio_open(&_oc->pb, output, AVIO_FLAG_WRITE);//以写格式打开文件
avformat_write_header(_oc, &pAVDictionary);//写入ts的节目专用信息头
上面都是为接下来的编码和本地保存做准备工作。
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);//将原始数据编码成H264裸数据
[self TSpacket:&avpakt];//打包
int nRet = av_interleaved_write_frame(_oc, packet);//将ts数据写入本地文件
[delegate_sendData SendH264Data:_oc->pb->buffer+havepk*188 Size:tspk*188];//rtp打包ts流数据进行流媒体直播
av_free_packet(packet);//释放内存
HLS是一个由苹果公司提出的基于HTTP的流媒体网络传输协议。本项目的本地播放录像功能所采用的也是HLS协议,在手机本地搭建一个轻量级的Web服务,只需要支持静态文件访问,然后调用系统的播放器类播放本地的M3U8文件即可。实现如下:
httpServer = [[HTTPServer alloc] init];[httpServer setType:@"_http._tcp."]; [httpServer setPort:52479];[httpServer setDocumentRoot:filePath]; [httpServer start:&error];//建立轻量级本地Web服务
然后即可调用系统播放组件MPMoviePlayerController进行播放,这样一个基于流媒体技术的移动视频直播系统的实现基本完成。
3 移动直播系统测试
在实验室网络条件下,分别从RTSP用户验证、VLC视频请求播放、流媒体视频转发、iOS视频采集软件、本地播放录像四方面对移动直播系统进行测试。结果软件运行正常,VLC视频直播图像较为清晰流畅,无明显时延,用户体验较好,达到了实时播放的效果。各界面效果如图4~图7所示。
综上所述,该移动直播系统利用手机终端的便利性,能够在任何场景利用手机进行拍摄;并且使用3G/4G网络连接手机移动直播平台,就可以在互联网上实现对突发事件的现场同步播出,或者在网络条件不好的情况下保存本地,而后进行上传,供其他用户随时随地地点播录像视频,足以应付基本的突发事件。利用手机的视频拍摄和传送能力,开发即时视频直播系统将会带来巨大的市场效应。
参考文献
[1] 程滢颖.移动终端上视频直播系统的研究与设计[D].上海:华东理工大学,2012.
[2] 方涛.数字电视业务信息及其编码[M].北京:国防工业出版社,2003.
[3] 路锦正.MPEG-4/H.264视频编解码工程实践[M].北京:电子工业出版社,2011.
[4] ISO/IEC 13818-1 information technology-generic coding of moving pictures and associated audio[S]:Syetems Recommendation H.222.0,1994.