罗玉盘
随着互联网行业的快速发展和移动智能手机的普及,移动视频的需求呈爆炸式增长,人们对于随时随地的多媒体访问需求日益迫切[1]。本文基于Live555 和Androidpn 设计并实现了视频实时传输系统。其中Live555 是一个为流媒体提供解决方案的跨平台的C++开源项目,Androidpn 实现了从服务器到Android 移动平台的文本消息推送,是基于XMPP 协议的Java 实现。通过流媒体控制传输,软硬件编解码,在局域网内实现Android 设备之间流畅视频传输功能[2]。文章具体讨论分析系统服务器端的设计和实现,考虑到移动设备的性能限制,通过服务器转发视频流后,可实现多终端播放。目前Live555 工程无法自定义视频文件存放目录和服务监听端口号,通过优化Live555 开源工程,加入启动参数设置,实现了多用户同时进行视频传输。
本系统主要包含两个子系统,分别是客户端和服务器端。客户端可同时发送和播放视频数据,服务器端则集成了Live555 和Androidpn 两个开源框架,其中Live555 负责视频流处理,Androidpn 负责消息推送。系统的功能结构如图1 所示,业务流程如图2 所示。
系统的各个子系统功能详细介绍如下:
1)采集客户端主要负责对视频数据的采集、编码和发送。采集客户端的视频发送过程是与服务器建立RTSP 连接[1],从摄像头提取视频数据,使用H.264 进行编码[3],打包成 RTP 数据包,发送至服务器端。
2)流媒体服务器端主要负责收集客户端发送的视频数据,进行存储并转发,同时提供对视频数据以及客户端用户进行管理控制的功能。流媒体服务器集成了Live555 和Androidpn 两个开源框架,其中Live555 负责实现视频直播、点播以及录制等功能,Androidpn 负责实现客户端在线管理以及服务端到客户端的消息推送。
3)播放客户端主要负责对视频数据的接收、解码和播放。客户端的视频播放过程是与服务器建立RTSP 连接,接收并解析RTP 数据包,解码出视频数据进行播放。
图1 视频实时传输系统功能结构图
图2 视频实时传输系统业务流程图
为了支持多用户同时在线进行传输,需要对Live555 进行功能扩展,使其能够自定义监听端口号,不同用户监听不同端口,同时能够自定义视频文件存放目录,在点播视频时可方便快捷地定位到视频文件。
首先,优化mediaServer 项目,此项目用于实现视频文件点播功能。在DynamicRTSPServer.hh 中添加变量,用于记录视频文件存放目录。在live555MediaServer.cpp中的main函数中,添加从命令行读取端口号和视频文件存放目录参数的代码。在RTSPServer 的初始化代码行中,将原来的默认端口号554 改为接收到的参数值。对DynamicRTSPServer 的视频文件存放目录变量进行初始化。在DynamicRTSPServer.cpp 的lookupServerMediaSession 函 数 中,将目录路径和文件名进行拼接形成完整路径,作为ServerMediaSession 的键值。这样,将项目编译后可生成mediaServer.exe 文件,通过命令行执行mediaServer.exe-p port-d fileDir 命令即可实现视频文件点播功能。
其次,优化proxyServer 项目,该项目用于实现视频流转发功能。在live555ProxyServer.cpp中同样添加从命令行读取端口号参数的代码。在RTSPServer 的初始化代码行中,将原来的默认端口号554 改为接收到的参数值。这样,将项目编译后可生成proxyServer.exe 文件,通过命令行执行proxyServer.exe-p port rtsp_url 命令即可实现对指定视频流的转发功能。
最后,优化openRTSP 项目,该项目用于实现视频流录制功能。在playCommon.cpp 的main 函数中,已经有从命令行读取视频文件存放目录参数的代码。但是在setupStreams 函数中,原有代码对保存的视频文件名进行了修改,需将其改为接收到的参数值。这样,将项目编译后可生成openRTSP.exe 文件,通过命令行执行openRTSP.exe-F filePath rtsp_url 命令即可实现对指定视频流的录制功能。
将Live555 优化完毕并编译好可执行文件后,下一步,需要搭建服务器端程序。在Androidpn 项目的基础上,集成Live555 的功能。
首先,将所有可执行文件拷贝至Androidpn 工程的WEB-INF/video 目录下。
其次,定义MediaServerFacade 类,该类实现多个服务接口,包括getUserList,getVideoList,call,reply,stop 等。其中getUserList 方法返回当前在线用户列表,通过遍历ClientSession获取每个会话的用户名;getVideoList 方法返回历史视频列表,通过Runtime.getRuntime().exec()方法执行上节中的命令行启动点播服务进程,然后扫描视频文件存放目录获取所有视频文件名称;call 方法实现呼叫指定用户,通过NotificationManager 的sendNotifications 方 法将呼叫请求推送给指定用户;reply 方法实现用户呼叫应答,若被呼叫的用户选择拒绝本次呼叫,通过NotificationManager 的sendNotifications 方法将拒绝信息推送给呼叫用户,若被呼叫的用户选择接受本次呼叫,通过Runtime.getRuntime().exec()方法执行上节中的命令行启动转发服务和录制服务进程,并通过NotificationManager 的sendNotifications 方法将转发视频流的地址推送给双方用户;stop 方法实现停止视频传输,通过Process.destroy()方法结束转发服务和录制服务进程,并将停止信息推送给另一方用户。
最后,修改WEB-INF/web.xml,添加servlet,对客户端的服务调用进行拦截。
将集成完毕的服务端部署到中间件上,并启动中间件。这里以视频实时传输功能为例,当两个移动终端进行视频通信时,在PC 上打开VLC 播放器[2],输入其中一个终端的转发视频流地址,也能同时接收视频,播放结果比较理想。
测试表明,在Android 移动系统下,服务器对客户端的视频传送非常流畅,可实现多终端接收,稳定可靠。
当今世界,随着移动终端的种类逐渐增多,功能逐渐增强,普及率逐渐升高,视频通信的市场需求越来越强烈。本系统实现了Android 移动终端之间的视频通信,多终端接收视频流,视频录制及点播功能,具有实际意义。