李闻斌
【摘 要】通过研究RTSP协议,实现流媒体服务通过RTSP地址接收来自多台编码器、NVR、DVR传输过来的实时视频图像,并转发给多个客户端进行实时图像浏览,避免客户端直接访问前端摄像机,降低网络流量和数据对网络的占用;同时既可单文件转发,也可时间轴方式转发历史视频给客户端,并提供历史视频下载。
【Abstract】Through studying the RTSP protocol, the streaming media service can receive real-time video images transmitted from multiple encoders, NVR and DVR through the RTSP address, and forward to multiple clients for real-time image browsing, which avoids direct access to front-end cameras by clients, reduce the network traffic and data occupation of the network.At the same time,it can forward history video to client in either single file or time axis mode, and provide history video download.
【关键词】RTSP协议; 流媒体; 实时视频; 时间轴; 视频下载
【Keywords】RTSP protocol; streaming media; real-time video; time axis; video download
【中图分类号】G354 【文献标志码】A 【文章编号】1673-1069(2018)05-0153-03
1引言
随着经济社会的发展,各地都在大力推广平安城市、智慧城市,而大量视频监控系统建设起来后却面临着一个重要问题:如何共享海量的历史视频。由于各个视频厂家的历史视频格式都不一样,都必须得用他们自己的解码库来解码播放,这就导致要播放如此多种类的视频就得准备几个甚至十几个不同的播放器,同时还不能用视频编辑工具对它们进行编辑。本文讨论的流媒体服务,通过RTSP地址接收摄像头的音视频流,再以标准RTSP转发实时音视频,对音视频不做任何处理;同时历史视频即可点播,也可时间轴(时间段)播放,还可下载保存为标准MP4格式,可用普通播放器播放,如VLC、暴风影音。
2 技术介绍
2.1 IOCP模型
IOCP全称I/O Completion Port,中文译为I/O完成端口。IOCP是一个异步I/O的API,它可以高效地将I/O事件通知给应用程序,适用于能控制并发执行的高负载服务器的一个技术,就是用于高效处理很多很多的客户端进行数据交换的一个模型[1]。
本文实现的流媒体服务应用于windows平台,采用IOCP模型可以实现多线程快速处理多客户端的各种请求,有效避免因程序造成的等待。
2.2 SDK技术
软件开发工具包(外语首字母缩写:SDK、外语全称:Software Development Kit)一般都是一些软件工程师为特定的软件包、软件框架、硬件平台、操作系统等建立应用软件时的开发工具的集合[2]。
每个视频设备生产厂家为获取音视频流、控制云台、亮度、色度等以及存储历史视频文件及播放功能等等,都有相应的SDK开发包。由于没有国家标准,每个SDK对实时流和历史视频的定义和格式都不一样,形成了各种技术壁垒,无形中阻碍了视频的共享,特别是历史视频的共享。
2.3 RTSP协议[3]
实时流协议(RTSP)是应用级协议,控制实时数据的发送。该协议用于C/S模型,是一个基于文本的协议,用于在客户端和服务器端建立和协商实时流会话。RTSP在体系结构上位于RTP和RTCP之上,它使用TCP或UDP完成数据传输。
经研究发现每个视频设备生产厂家的视频监控设备(摄像头)都可以通过RTSP地址直接获得音视频流,RTSP地址如:rtsp://user:pwd@%IP:554/h264/ch1/sub/av_stream或rtsp://user:pwd@%IP:554/stream1,只要获得用户名和密码就可以直接访问设备获取实时流,极大的方便后续的开发,如:存储历史视频、视频播放器。
3 流媒体服务的实现
流媒体服务通过跨网段以及跨平台转发视频流服务提高了视频联网平台视频流管理以及传输的稳定性、高效性和合理性,为用户请求实时和历史视频提供了快速的响应速度以及详细的反馈信息[4-5]。
由于流媒体服务主要功能是视频转发[6] 和视频回放,也就是实时视频数据流转发和历史视频数据流转发。实时视频数据流通过RTSP地址直接从视频监控设备(摄像头)获得,历史视频数据流则通过读取存储在存储服务器上的历史视频文件获得。
历史视频数据流又分为单视频数据流和时间轴视频数据流。单视频数据流很好理解就是读取存储服务器上的单个历史视频文件形成视频数据流进行传输,时间轴视频数据流则要求读取多个历史视频文件的数据媒体信息将它们整合形成一个视频数据流信息来进行传输。这是由于高清视频文件的存储时间一般在10分钟左右,如果要查看20分钟的视频,普通操作(单视频播放)是播放完一个再选择下一个播放,很不方便,通过时间轴的方式播放視频只需要用户选择好开始时间和结束时间即可观看此时间段内的视频,特别是案件发生时间持续两个视频文件,可以省去在两个历史视频文件间切换的时间,进而流畅的观看整个过程。
此外,流媒体服务还提供下载功能。下载也分为单视频下载和时间轴视频下载。
由于实时视频数据流转发和历史视频数据流转发请求,以及历史视频的下载都涉及到RTSP协议的应用,本文着重讲述RTSP客户端和服务端的实现及在流媒体服务中的应用。
3.1 RTSP客户端
实时视频数据流通过RTSP地址直接从视频监控设备(摄像头)获得,此时流媒体服务作为RTSP客户端,通过RTSP协议请求视频监控设备上的服务程序来获得实时视频数据流。利用C++语言实现RTSP协议的Client: class MRTSPClient。
类MRTSPClient完成连接设备服务、请求options、请求describe、解析SDP、请求setup、请求play和请求teardown。
主要函数包括:
bool openUrl(); //连接设备服务
int request_options();//请求options
int request_describe();//请求describe
int parseSDP();//解析SDP
int request_setup(); //请求setup
int request_play();//请求play
int request_teardown();//请求teardown
3.2 RTSP服务端
在转发实时视频数据流、历史视频数据流和历史视频文件下载时,流媒体服务作为RTSP服务端,接收客户端的连接和请求。利用C++语言实现IOCP模型和解析RTSP协议请求函数。
类CRTSPSocket实现IOCP模型,主要函数包括:
bool _InitializeIOCP();// 初始化IOCP
bool _InitializeListenSocket();// 初始化Socket
static DWORD WINAPI _WorkerThread();//為IOCP请求服务的工作者线程
static DWORD WINAPI _ClientHandle();//管理接入客户的线程
bool _DoRecv();//接收客户端RTSP协议数据并交由ParseMessage函数处理
RTSP协议解析函数包括:
void ParseMessage();//分配处理
int handleCmd_Option();//解析option请求
int handleCmd_Describe();//解析describe请求
int handleCmd_Setup();//解析setup请求
int handleCmd_Play();//解析play请求
int handleCmd_Teardown();//解析teardown请求
在处理时间轴视频流时需要读取多个历史视频文件的媒体信息并整合形成一个视频流,使用到的函数openFile(list
具体的历史视频文件的媒体信息整合算法如下:
for (list
{
RecordInfo* pRecordInfo = (RecordInfo*)*iter;
if (dateDiff(pRecordInfo->sEndTime, sTime, SECOND) > 0)
continue;
if (sBeginTime == "0")
sBeginTime = pRecordInfo->sBeginTime;
if (dateDiff(eTime, pRecordInfo->sBeginTime, SECOND) >= 0)
break;
string strFilePath = pRecordInfo->sFilePath;
FILE* pFilefp = fopen(strFilePath.c_str(), "rb");
if (pFilefp == NULL)
{
pRecordInfo->m_bFileIsExist = FALSE;
continue;
}
fclose(pFilefp);
string fileHead = strFilePath + ".list";
FILE* pFileHeadfp = fopen(fileHead.c_str(), "rb");
if (pFileHeadfp == NULL)
{
pRecordInfo->m_bFileIsExist = FALSE;
continue;
}
pRecordInfo->m_bFileIsExist = TRUE;
pRecordInfo->m_bLastFile = FALSE;
stFileHead stfileHead;
memset(&stfileHead;, 0, sizeof(stFileHead));
fread(&stfileHead;, 1, sizeof(stFileHead), pFileHeadfp);
pRecordInfo->m_dwTimeCount = stfileHead.m_dwTimeCount;//总时间
pRecordInfo->m_dwIFrameCount = stfileHead.m_dwIFrameCount;//I帧总数
pRecordInfo->m_pszFrameHead = new stFrameHead[stfileHead.m_dwIFrameCount];
memset(pRecordInfo->m_pszFrameHead, 0, sizeof(stFrameHead)*stfileHead.m_dwIFrameCount);
fread(pRecordInfo->m_pszFrameHead, 1, sizeof(stFrameHead)*stfileHead.m_dwIFrameCount, pFileHeadfp);
fclose(pFileHeadfp);
secTime[vid_idx] += pRecordInfo->m_dwTimeCount;
secFrame[vid_idx] += stfileHead.m_dwIFrameCount;
sEndTime = pRecordInfo->sEndTime;
}
double startDiff, endDiff;
startDiff = dateDiff(sBeginTime, sTime, SECOND);//开始时间与第一个录像文件的录像开始时间相差的秒数
endDiff = dateDiff(eTime, sEndTime, SECOND);//结束时间与最后一个录像文件的录像结束时间相差的秒数
startPos = startDiff >= 0 ? startDiff : 0;
endPos = endDiff >= 0 ? endDiff : 0;
//校驗播放总时间
secTime[vid_idx] -= startDiff;
secTime[vid_idx] -= endDiff;
frameRate[vid_idx] = 25;//暂时用25
_sample_rate[vid_idx] = 90000;
m_iterFile = m_fileList.begin();
RecordInfo* pRecordInfo = (RecordInfo*)*m_iterFile;
startDur = (startDiff * pRecordInfo->m_dwIFrameCount) / pRecordInfo->m_dwTimeCount;
pRecordInfo = (RecordInfo*)(m_fileList.back());
pRecordInfo->m_bLastFile = TRUE;
endDur = pRecordInfo->m_dwIFrameCount - (endDiff * pRecordInfo->m_dwIFrameCount) / pRecordInfo->m_dwTimeCount;
//校验I帧总数
secFrame[vid_idx] -= startDur;
secFrame[vid_idx] -= endDur;
4 小结
本文提出的基于IOCP和RTSP的流媒体服务主要是面向视频监控系统,通过RTSP地址直接从视频监控设备(摄像头)获得实时流,此方法成功绕开了设备厂家的SDK,降低了对设备厂家SDK的依赖,既可以加速后续新厂家设备的加入,也实现了历史视频文件的统一格式,形成标准的MP4文件供查看及播放,在一定程度上实现了兼容性的视频监控系统,避免了信息孤岛的形成,同时兼具可扩展性、可移植性。
【参考文献】
【1】百度百科. https://baike.baidu.com/item/IOCP/9207102?fr=aladdin, 2018
【2】百度百科. https://baike.baidu.com/item/sdk/7815680,2017.
【3】SCHULZRINNE H, RAO A, LANPHIER R. RFC 2326, Real time streaming protocol[S]. 1998
【4】赵心翔,傅秀芬.复杂硬件环境下流媒体服务器的设计实现[J].网络新媒体技术,2011,32(1):31-36
【5】吴超.流媒体服务器在远程监控中的应用[J].港口科技,2013(8):37-41.
【6】李婷,张武,陈晓.一种基于多核网络处理器的流媒体转发单元的实现[J].网络新媒体技术, 2012,01(2):28-33.