乐高易车联网流媒体网关中间件使用手册
广西乐高易网络有限公司
www.legaoyi.com
修订日期:2024年2月20日
目录
乐高易软件 乐高易车联网流媒体网关中间件 技术支持:78772895(QQ)
平台架构
平台概述
流媒体网关中间件是一个基于《道路运输车辆卫星定位系统车载视频通信协议》(JT/T 1078-2016)通信协议规范(实现5.5.3章节“实时音视频及透传数据传输”中的实时视频、语音对讲、历史视频回放、云台控制等)的流媒体网关中间件软件,具备轻量级、模块化设计的特点,不依赖于第三方服务,可独立部署,可嵌入原有平台中实现实时视频监控功能。主要功能包括:
(1)视频推流:支持音视频推流以及转推,输出HLS、RTMP、HTTP-FLV、 websocket-FLV等多种直播源,多视频终端同步播放。
(2)视频转码:转码服务是对音视频文件进行重新编解码的服务单元,它能对各种编码和封装格式,各种码率、分辨率和帧率的音视频文件按要求进行批量转换,以适应不同网络带宽情况下多平台、多终端的播放要求。转码服务能胜任高强度、大数据量的视频资源转码工作,实现将各种格式的视频资源快速转码成适合面向互联网播出的视频格式,使视频资源转码后可立即面向互联网进行发布,使您的多媒体应用更加便捷。
(3)跨网络跨终端:支持 Flash、HTML5 播放,能够通过宽带互联网、移动互联网和双向电视网络向 Windows 终端、iOS 终端、Android 终端、电视盒子等所有类型终端提供流畅的视音频播出服务,提供 HLS、HTTP、RTMP、HTML5 规范下的播出服务。
平台架构
注:流媒体网关中间件不包括信令服务器部分,若需要信令服务器需要单独购买乐高易车联网网关中间件模块。
音视频直播流程:
步骤一:业务平台通过信令服务器向车载终端发送1078协议音视频开启控制指令;
步骤二:车载设备接收到音视频开启控制指令,向信令服务器发送应答开启成功指令,同时开始向流媒体服务器开始推送音视频流;
步骤三:流媒体服务器进行音视频解码以及转码,封装并发布成HTTP-FLV/WS-FLV流;
乐高易软件 乐高易车联网流媒体网关中间件 技术支持:78772895(QQ)
步骤四:业务平台接收到车载设备应答开启音视频成功指令后,启动流媒体播放器(flv.js、西瓜播放器等)从流媒体服务器拉流,开始播放音视频;
步骤五:若有对讲,调用麦克风录音,获取麦克风音频流(PCM),封装成1078协议字节流,调用流媒体服务器weksocket接口进行推流;
步骤六:流媒体服务器进行对讲音频流进行解码以及转码,重新封装成1078协议字节流并推送给车载设备,实现对讲。
平台接口
音视频拉流
音视频拉流支持HTTP-FLV以及WS-FLV拉流,使用播放器可直接播放该URL网络流。前端可用flv.js播放器等H5播放器进行播放(可参考flv-demo项目)。
请求路径:
GET ${host}/live/{tag}? auth_key=timestamp-rand-uid-md5hash
请求参数:
参数名称
必须
类型
说明
tag
是
string
路径参数,流媒体标识,规则:
直播:{deviceSn}-{ channelId}-live.flv
回放:{deviceSn}-{ channelId}-his.flv
auth_key
是
String
url参数,鉴权密钥,如果网关中间件没有开启签名认证则不需要传递该参数,格式:
timestamp:签算服务器生成鉴权URL的时间,与鉴权URL的默认有效时长共同控制鉴权URL的失效时间。时间点取自签算服务器的Unix时间戳(Unix时间戳是从UTC时间1970年01月01日00时00分00秒到现在的总秒数,是十进制的整型正数,固定长度为10,与时区无关);
rand:随机数,一般取值为0。如果要确保每次生成的URL不同,建议使用UUID,不能包含中划线(-),例如:
477b3bbc253f467b8def6711128c****
uid:用户ID,暂未使用(设置成0即可);
md5hash:
通过MD5算法计算出的验证字符串。由数字0~9和小写英文字母a~z混合组成,固定长度为32。md5hash的值通过以下字符串计算得到:
乐高易软件 乐高易车联网流媒体网关中间件 技术支持:78772895(QQ)
str= "URI-timestamp-rand-uid-PrivateKey"md5hash = md5sum(sstring)
URI:用户的请求对象相对地址,不包含参数,如:/130040522966-1-live.flv;
PrivateKey:视频点播控制台配置的主Key或备Key,二者皆可。配置方法请参见开启鉴权并配置鉴权URL;
md5sum:表示计算MD5值,请使用开发语言对应的函数。
返回参数:
音视频流
请求例子:
GET http://localhost:26080/live/130040522966-1-live.flv?auth_key=1670292880956-c2a3ea40041847b7a694a1247f845f30-0-a6f629ac3a8835ac00edb86fa41d7428
GET ws://localhost:26080/live/130040522966-1-live.flv?auth_key=1670292880956-c2a3ea40041847b7a694a1247f845f30-0-a6f629ac3a8835ac00edb86fa41d7428
GET wss://localhost:26080/live/130040522966-1-live.flv?auth_key=1670292880956-c2a3ea40041847b7a694a1247f845f30-0-a6f629ac3a8835ac00edb86fa41d7428
对讲推流
对讲推流支持websocket推流
请求路径:
POST ${host}/ws/ walkie/{auth_key}
请求参数:
请求消息体为从麦克风的PCM音频流(单声道,16位,8000hz)封装成为1078协议的字节流。
参数名称
必须
类型
说明
auth_key
是
String
url参数,鉴权密钥,如果网关中间件没有开启签名认证该参数可传递设备id(deviceSn),格式:
timestamp:签算服务器生成鉴权URL的时间,与鉴权URL的默认有效时长共同控制鉴权URL的
乐高易软件 乐高易车联网流媒体网关中间件 技术支持:78772895(QQ)
失效时间。时间点取自签算服务器的Unix时间戳(Unix时间戳是从UTC时间1970年01月01日00时00分00秒到现在的总秒数,是十进制的整型正数,固定长度为10,与时区无关);
rand:随机数,一般取值为0。如果要确保每次生成的URL不同,建议使用UUID,不能包含中划线(-),例如:
477b3bbc253f467b8def6711128c****
uid:用户ID,暂未使用(设置成0即可);
md5hash:
通过MD5算法计算出的验证字符串。由数字0~9和小写英文字母a~z混合组成,固定长度为32。md5hash的值通过以下字符串计算得到:
str= "URI-timestamp-rand-uid-PrivateKey"md5hash = md5sum(sstring)
URI:用户的请求对象相对地址固定为"/walkie";
PrivateKey:视频点播控制台配置的主Key或备Key,二者皆可。配置方法请参见开启鉴权并配置鉴权URL;
md5sum:表示计算MD5值,请使用开发语言对应的函数。
返回参数:
请求例子:
POST http://localhost:28090/ws/walkie/1670292880956-c2a3ea40041847b7a694a1247f845f30-0-a6f629ac3a8835ac00edb86fa41d7428
注:前端js版对讲demo,请联系www.legaoyi.com获取。
添加白名单
流媒体网关中间件开启白名单功能后,只有在白名单中的车载设备才能够连接流媒体服务器。业务平台在开启音视频之前,需要调用该接口,添加车载设备白名单。
请求路径:
PUT ${host}/stream/whiteList/{deviceSn}
乐高易软件 乐高易车联网流媒体网关中间件 技术支持:78772895(QQ)
请求参数:
参数名称
必须
类型
说明
deviceSn
是
string
路径参数,设备id列表,逗号分隔
返回参数:
请求例子:
PUT http://localhost:28090/stream/whiteList/013609616300
删除白名单
流媒体网关中间件开启白名单功能后,只有在白名单中的车载设备才能够连接流媒体服务器。业务平台在开启音视频之前,需要调用该接口,添加车载设备白名单。
请求路径:
DELETE ${host}/stream/whiteList/{deviceSn}
请求参数:
参数名称
必须
类型
说明
deviceSn
是
string
路径参数,设备id列表,逗号分隔
返回参数:
请求例子:
DELETE http://localhost:28090/stream/whiteList/013609616300
获取当前音视频信息列表
请求路径:
GET ${host}/stream/list
请求参数:
参数名称
必须
类型
说明
返回参数:
{
"code":0,
"message":"success",
}
{
"code":0,
"message":"success",
}
乐高易软件 乐高易车联网流媒体网关中间件 技术支持:78772895(QQ)
请求例子:
GET http://localhost:28090/stream/list
获取指定音视频信息
请求路径:
GET ${host}/stream/{deviceSn}/{channelId}/{type}
请求参数:
参数名称
必须
类型
说明
deviceSn
是
string
路径参数,设备id列表
channelId
是
Integer
路径参数,音视频通道号
type
是
Integer
路径参数,流类型:1:实时视频;2:视频回放
返回参数:
{
"code":0,
"message":"success",
"data":[
{
"deviceSn":"013609616300",//设备id
"channelId":1,//通道号
"createTime":1234546545888,//开始推流时间
"updateTime":1232454645645,//最后推流时间
"currentTime":132464546565,//当前时间
"in":1325465,//接收字节数
"out":1325486,//对讲字节数
"videoFormat":"h264",//视频格式
"audioFormat":"g711a",//音频格式
"isHisilicon":false,//是否海思芯片
"ip":"127.0.0.1" //车载设备ip
}
]
}
乐高易软件 乐高易车联网流媒体网关中间件 技术支持:78772895(QQ)
请求例子:
GET http://localhost:28090/stream/013609616300/1/1
获取指定音视频订阅者列表
请求路径:
GET ${host}/stream/subscribers/{tag}
请求参数:
参数名称
必须
类型
说明
tag
是
string
路径参数,音视频拉流标识
返回参数:
{
"code":0,
"message":"success",
"data":{
"deviceSn":"013609616300",
"channelId":1,
"createTime":1234546545888,
"updateTime":1232454645645,
"currentTime":132464546565,
"in":1325465,
"out":1325486,
"videoFormat":"h264",
"audioFormat":"g711a",
"isHisilicon":false,
"ip":"127.0.0.1"
}
}
乐高易软件 乐高易车联网流媒体网关中间件 技术支持:78772895(QQ)
请求例子:
GET http://localhost:28090/stream/subscribers/013609616300-1.flv
获取指定音视频订阅者列表
请求路径:
GET ${host}/stream/ subscribers/{deviceSn}/{channelId}/{type}
请求参数:
参数名称
必须
类型
说明
deviceSn
是
string
路径参数,设备id
channelId
是
Integer
路径参数,音视频通道号
type
是
Integer
路径参数,流类型:1:实时视频;2:视频回放
返回参数:
{
"code":0,
"message":"success",
"data":[
{
"deviceSn":"013609616300",
"channelId":1,
"id":"1234546545888",
"tag":"live-013609616322-1",
"currentTime":132464546565,
"in":1325465,
"out":1325486,
"ip":"127.0.0.1"
}
]
}
乐高易软件 乐高易车联网流媒体网关中间件 技术支持:78772895(QQ)
请求例子:
GET http://localhost:28090/stream/subscribers/013609616300/1/1
获取指定音视频是否存在订阅者
请求路径:
GET ${host}/stream/subscribers/exists/{deviceSn}/{channelId}/{type}
请求参数:
参数名称
必须
类型
说明
deviceSn
是
string
路径参数,设备id
channelId
是
Integer
路径参数,音视频通道号
type
是
Integer
路径参数,流类型:1:实时视频;2:视频回放
返回参数:
请求例子:
GET http://localhost:28090/stream/subscribers/exists/013609616300/1/1
{
"code":0,
"message":"success",
"data":[
{
"deviceSn":"013609616300",
"channelId":1,
"id":"1234546545888",
"tag":"live-013609616322-1",
"currentTime":132464546565,
"in":1325465,
"out":1325486,
"ip":"127.0.0.1"
}
]
}
{
"code":0,
"message":"success",
"data":true
}
乐高易软件 乐高易车联网流媒体网关中间件 技术支持:78772895(QQ)
开启视频录制
流媒体网关中间件开启录制功能后,客户端可调用接口进行视频录制功能,录制的视频文件将存在在流媒体服务器本地磁盘中,可通过nginx搭建文件服务器进行访问下载该视频文件。
请求路径:
POST ${host}/stream /record/{deviceSn}/{channelId}/{type}
请求参数:
参数名称
必须
类型
说明
deviceSn
是
string
路径参数,设备id列表
channelId
是
Integer
路径参数,音视频通道号
type
是
Integer
路径参数,流类型:1:实时视频;2:视频回放
返回参数:
请求例子:
POST http://localhost:28090/stream/whiteList/013609616300/1/1
停止视频录制
客户端在开启视频录制功能后,在结束录制视频时需要调用该接口来停止视频录制功能,否则流媒体服务器会一直录制直至设备下线。
请求路径:
DELETE ${host}/stream/ record/{streamId}
请求参数:
参数名称
必须
类型
说明
streamId
是
string
视频文件id
返回参数:
{
"code":0,
"message":"success",
"data":{
"streamId":"视频文件id",
"fileName":"视频文件存储路径"
}
}
乐高易软件 乐高易车联网流媒体网关中间件 技术支持:78772895(QQ)
请求例子:
DELETE http://localhost:28090/stream/record/013609616300
应用程序部署
依赖环境
操作系统:建议使用linux,centOS 7以上版本。
Java环境:建议安装jdk 1.8。
应用程序
elink-iov-jt1078-vedio-gateway,为java应用程序,运行在java环境上。
8.2.1 配置文件
配置文件application.properties,存放目录为应用程序根目录下的conf文件夹(注:该文件夹下所有的文件必须,不能删除)。
#音视频web API http接口端口
server.port=28090
#音视频http-flv/websocket-flv拉流端口,内部使用
elink.jt1078flv.server.port=26080
#视频拉流签名privateKey列表,逗号分隔;为空则不开启签名验证
elink.security.jt1078.privateKey=6d126501ab01362728e19f5c88e927cd
#视频拉流签名过期时间,单位:分钟;小于等于0则不过期
elink.security.jt1078.signature.expireIn=720
#协议所使用的TCP端口
#JT/T 1078-2016版本协议实时音视频推流端口
elink.jt10782016Live.server.port=6037
#JT/T 1078-2016版本协议历史视频
{
"code":0,
"message":"success",
}
乐高易软件 乐高易车联网流媒体网关中间件 技术支持:78772895(QQ)
elink.jt10782016His.server.port=6038
##JT/T 1078-2019版本协议实时音视频推流端口
elink.jt10782019Live.server.port=6039
##JT/T 1078-2019版本协议实时音视频推流端口
elink.jt10782019His.server.port=6040
注意其中配置“6037,6038,6039,6040”,为车载终端设备连接流媒体服务器的推流TCP端口,注意操作系统配置防火墙对外开放该端口。
8.2.2 程序运行
把elink-iov-jt1078-vedio-gateway应用程序复制到安装有java环境的操作系统中即可,应用程序的启动脚本文件放在应用程序根目录下的bin文件夹中。注意启动应用程序前需检查端口是否已被其他应用程序占用(linux下执行命令:netstat -ano|grep 6037)。
windows操作系统
方式一:双击 bin/startup.bat执行文件启动应用程序,以该方式启动,命令窗口关闭之后,程序也将停止,不建议以该方式启动。
方式二:以后台服务形式运行,操作步骤:
1、双击bin/installAppService.bat执行文件把应用程序注册成为win后台服务。注册成功之后,会在win服务列表中有一个名字为“elink-iov-jt1078-vedio-gateway”的服务,该服务为开机自动启动;
2、可以在命令窗口中使用命令或者在服务列表中手动启动或者停止。命令方式:
启动程序:net start elink-iov-jt1078-vedio-gateway
停止程序:net stop elink-iov-jt1078-vedio-gateway
3、双击bin/uninstallAppService.bat执行文件,则卸载“elink-iov-jt1078-vedio-gateway”已经注册的win后台服务。程序卸载时可双击该执行文件。
linux操作系统
bin/startup.sh为linux下启动脚本(需要赋予该文件执行权限:chmod 777 startup.sh)。
启动程序命令:./startup.sh start
停止程序命令:./startup.sh stop
linux命令注解:
console
启动并显示控制台信息
start
作为一个守护进程后台启动
stop
停止程序
restart
重启程序
condrestart
重启已经运行的程序,与前者区别是程序必须已经在运行
status
查看该程序状态
install
将程序安装为自启动服务,即随系统启动而启动
remove
卸载自启动服务
dump
报告运行时的Java thread dump(thread dump百度百科:http://baike.baidu.com/view/5111187.htm)
注意事项:
a、启动前需要检查车联网网关所使用的端口是否被占用,linux下命令:netstat -ano|grep
乐高易软件 乐高易车联网流媒体网关中间件 技术支持:78772895(QQ)
6037
b、查看程序是否启动linux命令:ps -aux | grep elink-iov-jt1078-vedio-gateway;
c、若需要重启车联网网关应用,在停止程序之后,需要查看程序所监听端口(如:netstat -ano|grep 6037,一般等待一两分钟就能完全释放,取决于操作系统的socket timeout配置)是否完全释放在重新启动应用,否则程序启动会报错。
日志管理
logback-spring.xml为日志配置文件,通过修改该配置文件可以配置输出日志的级别,平台默认级别为“info”。当平台已经进入稳定运行阶段,接入的车辆数量比较大时,为了减少打印日志对系统的性能影响,建议把日志级别调整为“error”级别。见以下标红部分:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 日志级别 -->
<property name="log.level" value="INFO"/>
<logger name="io.netty" level="ERROR" />
<logger name="org.springframework" level="ERROR" />
<logger name="com.legaoyi.iov.gateway.mq" level="INFO" additivity="false">
<appender-ref ref="mqAppender" />
<appender-ref ref="errorAppender" />
</logger>
<!-- 设备上行消息日志 -->
<logger name="com.legaoyi.iov.protocol.server.LoggerChannelInboudHandler" level="ERROR" additivity="false">
<appender-ref ref="inboundAppender" />
<appender-ref ref="errorAppender" />
</logger>
<!-- 设备下行消息日志 -->
<logger name="com.legaoyi.iov.protocol.server.LoggerChannelOutboudHandler" level="ERROR" additivity="false">
<appender-ref ref="outboundAppender" />
<appender-ref ref="errorAppender" />
</logger>
<!-- 设备上下线日志 -->
<logger name="com.legaoyi.iov.protocol.server.SessionManager" level="WARN" additivity="false">
<appender-ref ref="onlineAppender" />
<appender-ref ref="errorAppender" />
</logger>
乐高易软件 乐高易车联网流媒体网关中间件 技术支持:78772895(QQ)
<logger name="com.legaoyi.iov.protocol.server.ChannelInboundEventHandler" level="WARN" additivity="false">
<appender-ref ref="onlineAppender" />
<appender-ref ref="errorAppender" />
</logger>
<root level="${log.level}">
<appender-ref ref="fileAppender" />
<appender-ref ref="errorAppender" />
<appender-ref ref="consoleAppender" />
</root>
</configuration>
elink-iov-jt1078-vedio-gateway.log
日志文件放在应用程序根目录下的logs文件夹中,默认保留最近7天的日志,默认日志级别为“info”。该日志主要存放了中间件程序运行异常日志.
inbound.log
日志文件放在应用程序根目录下的logs文件夹中,默认保留最近7天的日志,默认日志级别为“info”。该日志存放了车载终端设备发送给流媒体服务器的原始消息。
outbound.log
日志文件放在应用程序根目录下的logs文件夹中,默认保留最近7天的日志,默认日志级别为“info”。该日志存放了流媒体服务器发送给车载终端设备的原始消息。
online.log
日志文件放在应用程序根目录下的logs文件夹中,默认保留最近7天的日志。该日志存放了车载终端设备推流上下线日志。
error.log
日志文件放在应用程序根目录下的logs文件夹中,默认保留最近7天的日志。该日志存放了网关处理消息的错误日志。
Nginx代理配置
由于对讲使用H5技术,浏览器获取麦克风权限需要HTTPS支持,故平台如需要对讲功能首先需要搭建HTTPS环境,然后通过使用nginx代理转发前端请求到流媒体服务器即可,参考一下配置:
#对讲wss转发配置
location ^~ /ws/intercom {
乐高易软件 乐高易车联网流媒体网关中间件 技术支持:78772895(QQ)
proxy_pass http://127.0.0.1:28090;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Origin "";
proxy_redirect off;
}
# https-flv或者wss-flv拉流转发配置
location /live {
proxy_pass http://127.0.0.1:26080;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Origin "";
proxy_redirect off;
}