Java实现部标JTT1078实时音视频传输指令——视频流负载包(RTP)传输
一、 说一说实现的思路
- 1.接收平台方下发的0x9101命令(实时音视频传输请求)
- 2.解析下发的0x9101命令,拿到音视频上传数据的服务器IP和端口号
- 3.开始获取设备摄像头的每一帧视频数据,这里需要注意的是:视频数据支持的格式有:H.264,H.265,AVS,SVAC;详细的可以查看JTT1078协议的(表12)
- 4.将每一帧的数据封装成(表19)音视频流及透传数据传输协议负载包格式
二、解析平台下发的0x9101命令这里就不说了,拿到下发的数据在上传视频流的时候需要
- 解析到数据后就连接上服务器即可。
三、获取视频流数据并编码成H.264视频格式
我这里是在Android平台实现的可以看下我这篇文章Android采集摄像头的视频流数据并使用MediaCodec编码为H264格式
四、将获取到的H.264视频流的每一帧数据进行RTP包封装,来看下协议 5.5.3 :
五、提取出一些重要的信息
- 表中定义的bit位按照大端模式填写:也就是将bit按字符串从左到右排列然后在转成byte
- 字段PT(负载类型,见表19):这处是文档写错了,应该是见(表12)
- 字段数据类型:I/P/B帧的判断,这个就大家可以参考下这位博主的H264码流的I/P/B帧NALU判断
简单说下:一帧H264的视频流数据一般为0x00 0x00 0x00 0x01 或 0x00 0x00 0x01开头,所以0x01后面的这个字节就是NALU类型 - 数据体长度不超过950个byte:如果一帧数据大于了950byte就需要分包了
下面就来看代码的具体实现了
//实时视频数据包序号
private static int RTP_VIDEO_COUNT = 0;
//计算这一I帧距离上一I帧的间隔
private static long LAST_I_FRAME_TIME;
//计算这一帧与上一帧的间隔
private static long LAST_FRAME_TIME;/*** 打包实时视频RTP包** @param data H.264一帧的视频数据* @param phone SIM卡号* @param liveClient 与服务器的连接*/
public static synchronized void videoLive(byte[] data, int channelNum, String phone, LiveClient liveClient) {List<byte[]> dataList = new ArrayList<>();//每个包的大小double everyPkgSize = 950.d;int length = data.length;if (data.length > everyPkgSize) {//分包的总包数long totalPkg = Math.round(Math.ceil(length / everyPkgSize));for (int i = 1; i <= totalPkg; i++) {int end = (int) (i * everyPkgSize);if (end >= length) {end = length;}byte[] bytes = Arrays.copyOfRange(data, (int) ((i - 1) * everyPkgSize), end);dataList.add(bytes);}} else {dataList.add(data);}for (int i = 0; i < dataList.size(); i++) {byte[] pkgData = dataList.get(i);ByteBuf buffer = Unpooled.buffer();buffer.writeBytes(new byte[]{0x30, 0x31, 0x63, 0x64});// V P X CCString vpxcc = "10 0 0 0001".replace(" ", "");buffer.writeByte(Integer.parseInt(vpxcc, 2));// M PTString mpt = "0 1100010".replace(" ", "");buffer.writeByte(Integer.parseInt(mpt, 2));//包序号buffer.writeBytes(ByteUtil.int2Word(RTP_VIDEO_COUNT));//SIMbuffer.writeBytes(ByteUtil.string2Bcd(phone));//逻辑通道号buffer.writeByte(channelNum);String dataType = "";//取h264的第5个字节,即NALU类型byte NALU = data[4];if ((NALU & 0x1F) == 5) {//这是I帧dataType = "0000";LAST_I_FRAME_TIME = System.currentTimeMillis();} else {dataType = "0001";}//分包标记if (dataList.size() == 1) {//不分包dataType += "0000";} else if (i == 0) {//第一个包dataType += "0001";} else if (i == dataList.size() - 1) {//最后一个包dataType += "0010";} else {//中间包dataType += "0011";}//数据类型 分分包标记buffer.writeByte(Integer.parseInt(dataType, 2));//时间戳buffer.writeBytes(ByteUtil.long2Bytes(System.currentTimeMillis()));//Last I Frame Intervallong difIFrame = System.currentTimeMillis() - LAST_I_FRAME_TIME;buffer.writeBytes(ByteUtil.int2Word(difIFrame));//Last Frame Intervallong difFrame = System.currentTimeMillis() - LAST_FRAME_TIME;buffer.writeBytes(ByteUtil.int2Word(difFrame));//数据体长度buffer.writeBytes(ByteUtil.int2Word(pkgData.length));//数据体buffer.writeBytes(pkgData);//发送数据if (liveClient != null) {liveClient.sendData(ByteBufUtil.toArray(buffer));}RTP_VIDEO_COUNT++;}LAST_FRAME_TIME = System.currentTimeMillis();
}
实在没找到Java这边怎么判断B/P帧,所以我这里只判断了是不是I帧,如果不是则都认为是P帧
- 第一步就是判断一帧数据是否要分包,如果需要分包则将分好的每一个包添加至集合中
- 第二步把对应的字段数据填入
- 第三步计算 Last I Frame Interval(这一I帧距离上一I帧的间隔),Last Frame Interval(这一帧距离上一帧的间隔)的时间间隔
- 第四步直接发送就可以了
整个协议的重点就是获取视频流数据并编码H.264,判断每一帧数据是那一帧(I/B/P),计算帧间隔;这样就搞定了视频流上传了
最后附上:使用Netty封装的 部标JTT808,JTT1078,渝标协议 数据上传Android端示例GitHub项目地址
Java实现部标JTT1078实时音视频传输指令——视频流负载包(RTP)传输相关推荐
- 从编码、网络传输、架构设计揭秘腾讯云高质量、高可用实时音视频技术实践...
在互联网飞速发展的时代,视频应用无处不在,各行各业对视频技术的需求开始爆发.伴随视频分辨率的提高,音视频玩法的快速更新以及用户对观看体验需求的不断增加,越来越多的应用场景对音视频技术提出了更高的要求. ...
- RTSP实时音视频传输介绍
<RTP协议封装H264/H265/AAC> <rtsp采用MD5加密摘要认证的交互过程> 目录 一.前言 二.RTSP的信令格式 三.RTSP的通信过程 四.RTSP服务器设 ...
- 如何构建全球实时音视频云及其海外网络传输优化
点击上方"LiveVideoStack"关注我们 全球不同国家和地区的网络基建水平参差不齐,如何利用有限的网络资源提供更高质量的音视频通话体验是音视频服务商必须面对的挑战.在此次L ...
- java音视频处理类,Android Java实时音视频SDK自定义视频前处理功能 - 开发者中心 - ZEGO即构科技...
自定义视频前处理 更新时间:2021-02-07 17:47 1 功能简介 当 SDK 自带的美颜无法满足需求,例如需要做挂件.贴纸,或者美颜效果无法达到预期时,推荐开发者使用自定义视频前处理功能.该 ...
- QOS FEC NACK 实时音视频传输库测试报告(声网、腾讯实时音视频测试)
目录 QOS-FEC-NACK传输库简介 实验环境 测试DEMO说明 测试项说明 测试结果 竞品分析 总结 QOS FE ...
- IoT 设备高质量的实时音视频传输解决方案
12月10日,实时互动云服务开创者及引领者声网Agora在北京举办了媒体沟通会,发布了首款定义轻互动直播场景的"极速直播"与可降低50%直播带宽成本的"低码高清" ...
- 微信团队分享:微信每日亿次实时音视频聊天背后的技术解密
本文内容整理自腾讯专家研究员 & 微信视频技术负责人谷沉沉在 2017 ArchSummit 全球架构师峰会上的技术分享. 1.前言 2012 年 7 月,微信 4.2 版本首次加入了实时音视 ...
- 技术福利:最全实时音视频开发要用到的开源工程汇总
[转自] https://my.oschina.net/jb2011/blog/1619628 1.前言 实时音视频的开发学习有很多可以参考的开源项目.一个实时音视频应用共包括几个环节:采集.编码.前 ...
- 福利贴:最全实时音视频开发要用到的开源工程汇总
1.前言 实时音视频的开发学习有很多可以参考的开源项目.一个实时音视频应用共包括几个环节:采集.编码.前后处理.传输.解码.缓冲.渲染等很多环节.每一个细分环节,还有更细分的技术模块.比如,前后处理环 ...
- 实时音视频技术(WebRTC/voip/Linphone/P2P)
实时音视频技术(WebRTC/voip/Linphone/P2P) 视频社交与语音社交??? 实时视频(直播)/语音通信.多媒体技术团队在音视频编解码.前后处理.传输等技术: 在语音社交.视 ...
最新文章
- Informatica:当好大数据的清道夫
- Android 实现微信QQ分享以及第三方登录
- javascript技巧收集(200多个)---转
- java读取 info.plist源码_Java 解析 IPA 文件,读取 Info.plist 信息-Go语言中文社区
- Vue.js 计算属性和侦听器
- max格式转obj小工具_PDF文件转JPG等图片格式的小工具
- 【蓝桥杯省赛】冲刺练习题【数学公式】倒计时【06】天(准考证组委会已下发,请查询)
- Qt 多线程并发高阶类QtConcurrent 的使用
- 【Python】猜数小游戏(文件操作)
- mysql数据绑定listview_将数据库数据用代码绑定到Listview
- Eclipse 项目导入 Android Studio 导致的乱码问题解决
- Systemview5安装的问题:the license for this version of systemview has expired......
- python mkv转mp4,h264格式的flv和mkv无损转换成mp4的方法
- Windows | 用youtube-dl批量下载mp3格式音频
- 用python写一个躲避球十分简单的小游戏
- 让每个3D建模师都心动的:超详细人体结构构图分析
- 螺旋传动设计系统lisp_螺旋传动的设计计算.pdf
- css怎么修改图片像素,CSS 像素图制作攻略
- C语言strchr()函数以及strstr()函数的实现
- java基础学习:java中的反射
热门文章
- 英寸和厘米的交互python_Python新手尝试编写厘米到英寸的代码,反之亦然
- 什么是社会融资规模,M0、M1、M2?
- python 面向对象全面详解
- 基于air720等air7xx的4G模块luat程序下载
- openCV 简单实现身高测量(二)
- hdmi接口和计算机连接,hdmi接口,手把手教你hdmi接口怎么连接电视
- msxml6_x86.msi和msxml6_ia64.msi和msxml6_x64.msi的选择
- 呼叫中心点击拨打接口升级代码
- linux卸载kodi,如何在Ubuntu 18.04上安装Kodi
- 怎么无痕去除图片中的文字