基于Java的RTSP服务

因公司项目需求,需要开发一个基于java的RTSP服务,支持RTP/UDP和RTP/TCP模式的VLC播放。本人在这方面也是小白一个,于是各种谷歌,百度查找资料学习RTSP/RTP相关的理论知识,理论知识了解的差不多了,就想找一些java的成熟案例。可以找了一圈后发现根本没有java相关的可用案例。好在有一篇C++相关的可以借鉴,再此特别感谢这位大牛博主,不光技术好,博文也写的特别好。非常适合对于初学RTSP的小白。传送地址:http://blog.csdn.net/weixin_42462202/article/details/98986535。经过1周的学习和摸索最后成功开发出一个基于Java的RTSP服务,实现了RTP/UDP/TCP的在线实时视频播放。本文不讲述理论相关的,理论相关的参考上面的博客地址,讲的不要太好。这里只上经过公司项目实战验证的干货。

开发Java的RTSP服务主要有三个大步骤要点:

1、解析客户端RTSP请求协议并返回信息给客户端(建立通信连接)。

进入开发,首选需要一个网络通信开发包用于RTSP服务和客户端之间的通信,我这里选用的是netty-4.1.45.Final。netty4本身就支持RTSP协议的封装,所以在解析RTSP协议命令的时候非常方便。如图:
基于Java的RTSP服务

有了RTSP消息解析器后,自定义的Handler就可以轻松获取到相应的RTSP请求参数了,通过DefaultHttpRequest,HttpHeaders,你想要的请求信息都能有获取到请求信息后,按协议要求响应相应数据。如图:

基于Java的RTSP服务
基于Java的RTSP服务

2、提取nalu视频数据。

h264视频文件都是00 00 01或00 00 00 01为起始码,自己可以写个算法解析byte[]数组起始码提取nalu数据。参考如图:

基于Java的RTSP服务
基于Java的RTSP服务
上图readNalu方法就是提取nalu的算法方法,没有截全,主要是不同数据源方式可能有小差异,比如本地h264视频文件方式,可以通过open方法读取到全部的数据到byte[],提取nalu的时候比较简单,因为所有数据都在一起。但如果是海康终端设备数据,设备流服务数据本身就分片了,会出现有些片不包含起始码,有些片包含多个起始码。遇到的时候要注意,让readNalu方法兼容提取到每一个nalu数据,不然最后播放会出现绿屏或者花屏现象。

3、提取到的nalu数据进行nalu数据RTP打包和发送

不知道RTP包格式的请阅读本文开头的传送地址博客,打包有三种方式:单NALU打包、聚合打包、分片打包。常用的是单NALU打包和分片打包。客户端接收到正确协议格式的RTP数据包即可播放视频,RTP包发送有UDP模式和TCP模式之分,区别在于RTP/TCP模式多四个字节数据头。如图:
基于Java的RTSP服务
基于Java的RTSP服务基于Java的RTSP服务
基于Java的RTSP服务
上几张图是RTP打包和TCP模式发送代码,TCP模式最后是通过netty的channel发送的。UPD模式很简单,只要知道客户端IP地址和端口即可用DatagramPacket发送。代码中的iosesson是用户会话管理的。开发测试阶段可以不用。打包好的RTP直接调用channel发送即可。

以上就是大致的步骤和核心代码,目前只实现了视频的播放和回访,后期还有音频的效果需要实现,因需要忙别的项目,音频的实现暂时还没研究,有兴趣的同学可以加wx一起交流wx号:javaxiao,最后放几张本地h264视频文件效果图:

基于Java的RTSP服务
基于Java的RTSP服务
基于Java的RTSP服务