Giter VIP home page Giter VIP logo

jt1078's Introduction

JT1078

道路运输车辆卫星定位系统-视频通讯协议主要分为三大部分。

  1. [设备终端到平台的通信也就是JT808]
  2. 企业平台到政府监管的通信也就是JT809
  3. 设备终端上传的实时音视频流数据也就是视频服务器
    3.1 将1078的数据(h264)编码成FLV
    3.2 将1078的数据(h264)编码成HLS
    3.3 将1078的数据(h264)编码成FMp4
  4. ====音频部分暂未实现====

MIT LicenceGithub Build status

NuGet安装

Package Name Version Pre Version Downloads
Install-Package JT1078 JT1078 JT1078 JT1078
Install-Package JT1078.Flv JT1078.Flv JT1078.Flv JT1078.Flv
Install-Package JT1078.Hls JT1078.Hls JT1078.Hls JT1078.Hls
Install-Package JT1078.FMp4 JT1078.FMp4 JT1078.FMp4 JT1078.FMp4

基于JT1078音视频流数据的RTP协议

前提条件

  1. 掌握进制转换:二进制转十六进制;
  2. 掌握BCD编码、Hex编码;
  3. 掌握各种位移、异或;
  4. 掌握快速ctrl+c、ctrl+v;
  5. 掌握Span<T>的基本用法
  6. 掌握以上装逼技能,就可以开始搬砖了。

数据结构解析

帧头标识 标注1 标注1 包序号 SIM 卡号 逻辑通道号 标注3 时间戳 Last I Frame Interval Last Frame Interval 数据体长度 数据体
FH_Flag Label1 Label2 SN SIM LogicChannelNumber Label3 Timestamp LastIFrameInterval LastFrameInterval DataBodyLength Bodies

标注1(Label1)

RTP协议的版本号 填充标志 扩展标志 CSRC计数器
V P X CC

标注2(Label2)

标志位,确定是否完整数据帧的边界 负载类型
M PT

标注3(Label3)

数据类型 分包处理标记
DataType SubpackageType

1.参考JTT1078文档 2.参考RTP协议

举个栗子1

1.组包


JT1078Package jT1078Package = new JT1078Package();
jT1078Package.Label1 = new JT1078Label1(0x81);
jT1078Package.Label2 = new JT1078Label2(0xE2);
jT1078Package.SN = 0x1088;
jT1078Package.SIM = "11234567810";
jT1078Package.LogicChannelNumber = 0x01;
jT1078Package.Label3 = new JT1078Label3(0x10);
jT1078Package.Timestamp = 1562085870204;
jT1078Package.LastIFrameInterval = 0x0280;
jT1078Package.LastFrameInterval = 0x0028;
jT1078Package.Bodies = "00 00 00 01 61 E1 A2 BF 00 98 CF C0 EE 1E 17 28 34 07 78 8E 39 A4 03 FD DB D1 D5 46 BF B0 63 01 3F 59 AC 34 C9 7A 02 1A B9 6A 28 A4 2C 08".ToHexBytes();
var hex = JT1078Serializer.Serialize(jT1078Package).ToHexString();
// 输出结果Hex:
//30 31 63 64 81 E2 10 88 01 12 34 56 78 10 01 10 00 00 01 6B B3 92 CA 7C 02 80 00 28 00 2E 00 00 00 01 61 E1 A2 BF 00 98 CF C0 EE 1E 17 28 34 07 78 8E 39 A4 03 FD DB D1 D5 46 BF B0 63 01 3F 59 AC 34 C9 7A 02 1A B9 6A 28 A4 2C 08

2.手动解包

1.原包:
30 31 63 64 81 E2 10 88 01 12 34 56 78 10 01 10 00 00 01 6B B3 92 CA 7C 02 80 00 28 00 2E 00 00 00 01 61 E1 A2 BF 00 98 CF C0 EE 1E 17 28 34 07 78 8E 39 A4 03 FD DB D1 D5 46 BF B0 63 01 3F 59 AC 34 C9 7A 02 1A B9 6A 28 A4 2C 08

2.拆解:
30 31 63 64              --帧头表示
81                       --Label1 =>10000001 V P X CC
E2                       --Label2 =>11100010 M PT
10 88                    --SN 包序号
01 12 34 56 78 10        --SIM卡号
01                       --逻辑通道号
10                       --Label3 =>数据类型 分包处理标记
00 00 01 6B B3 92 CA 7C  --时间戳
02 80                    --Last I Frame Interval
00 28                    --Last Frame Interval
00 2E                    --数据体长度
00 00 00 01 61 E1 A2 BF  --数据体
00 98 CF C0 EE 1E 17 28
34 07 78 8E 39 A4 03 FD
DB D1 D5 46 BF B0 63 01
3F 59 AC 34 C9 7A 02 1A
B9 6A 28 A4 2C 08

3.程序解包

var bytes = "30 31 63 64 81 E2 10 88 01 12 34 56 78 10 01 10 00 00 01 6B B3 92 CA 7C 02 80 00 28 00 2E 00 00 00 01 61 E1 A2 BF 00 98 CF C0 EE 1E 17 28 34 07 78 8E 39 A4 03 FD DB D1 D5 46 BF B0 63 01 3F 59 AC 34 C9 7A 02 1A B9 6A 28 A4 2C 08".ToHexBytes();
JT1078Package package = JT1078Serializer.Deserialize(bytes);
Assert.Equal(0x81, package.Label1.ToByte());
Assert.Equal(0xE2, package.Label2.ToByte());
Assert.Equal(0x1088, package.SN);
Assert.Equal("011234567810", package.SIM);
Assert.Equal(0x01, package.LogicChannelNumber);
Assert.Equal(0x10, package.Label3.ToByte());
Assert.Equal((ulong)1562085870204, package.Timestamp);
Assert.Equal(0x0280, package.LastIFrameInterval);
Assert.Equal(0x0028, package.LastFrameInterval);
Assert.Equal(0x002E, package.DataBodyLength);
Assert.Equal("00 00 00 01 61 E1 A2 BF 00 98 CF C0 EE 1E 17 28 34 07 78 8E 39 A4 03 FD DB D1 D5 46 BF B0 63 01 3F 59 AC 34 C9 7A 02 1A B9 6A 28 A4 2C 08".ToHexBytes(), package.Bodies);

使用BenchmarkDotNet性能测试报告(只是玩玩,不能当真)

BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i7-8700K CPU 3.70GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores
.NET Core SDK=3.1.100
  [Host]     : .NET Core 3.1.0 (CoreCLR 4.700.19.56402, CoreFX 4.700.19.56404), X64 RyuJIT
  Job-SIQGUC : .NET Core 3.1.0 (CoreCLR 4.700.19.56402, CoreFX 4.700.19.56404), X64 RyuJIT

Platform=AnyCpu  Server=False  Toolchain=.NET Core 3.1  
Method N Mean Error StdDev Gen 0 Gen 1 Gen 2 Allocated
JT1078Serializer 100 183.51 us 2.207 us 2.064 us 37.8418 - - 232.81 KB
JT1078Deserialize 100 35.88 us 0.503 us 0.420 us 23.8037 - - 146.09 KB
JT1078Serializer 10000 23,107.15 us 196.882 us 184.164 us 3781.2500 - - 23281.25 KB
JT1078Deserialize 10000 3,620.54 us 45.558 us 40.386 us 2382.8125 3.9063 - 14609.38 KB
JT1078Serializer 100000 236,213.13 us 5,465.042 us 6,074.380 us 38000.0000 - - 232812.5 KB
JT1078Deserialize 100000 37,065.84 us 665.875 us 590.281 us 23785.7143 - - 146093.75 KB

基于JT1078的Flv视频编码器

前提条件

  1. 掌握JT078解码;
  2. 了解H264解码;
  3. 掌握FLV编码;

由于网上资料比较多,自己也不擅长写文章,这边只是着重写一些在实际开发中需要注意的问题。

注意:目前仅支持H264编码的视频播放,主次码流的切换。由于多数设备厂商只支持一路通道只能存在主码流或者子码流,所以不考虑同时上传主次码流。

关注点

  1. 在组包FLV的时候需要注意将解析的NALU值放入VideoTagsData中,格式:[NALU.Length 长度]+[NALU 值]...[NALU.Length 长度]+[NALU 值]可以存放多个NALU。

  2. JT1078的属性大有用处。

JT1078属性 FLV属性
Timestamp JT1078的Timestamp为FLv的Timestamp
DataType JT1078的DataType为FLv的FrameType的值(判断是否为关键帧)
LastFrameInterval JT1078的LastFrameInterval为FLv(B/P帧)的CompositionTime值

基于JT1078的Hls视频编码器

前提条件

  1. 掌握JT078解码;
  2. 了解H264解码;
  3. 掌握TS编码;
  4. 掌握Hls编码;

基于JT1078的FMp4视频编码器

前提条件

  1. 掌握JT078解码;
  2. 了解H264解码;
  3. 掌握FMp4编码;

使用BenchmarkDotNet性能测试报告(只是玩玩,不能当真)

BenchmarkDotNet=v0.12.0, OS=Windows 10.0.18363
Intel Core i7-8700K CPU 3.70GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores
.NET Core SDK=3.1.100
  [Host]     : .NET Core 3.1.0 (CoreCLR 4.700.19.56402, CoreFX 4.700.19.56404), X64 RyuJIT
  Job-GMXLRW : .NET Core 3.1.0 (CoreCLR 4.700.19.56402, CoreFX 4.700.19.56404), X64 RyuJIT

Platform=AnyCpu  Server=False  Toolchain=.NET Core 3.1  
Method N Mean Error StdDev Gen 0 Gen 1 Gen 2 Allocated
EXPGolombReader 100 11.23 us 0.032 us 0.025 us 1.5259 - - 9.38 KB
H264Decoder 100 1,218.74 us 23.313 us 27.752 us 126.9531 1.9531 - 786.72 KB
FlvEncoder 100 215.40 us 3.245 us 2.533 us 249.0234 3.4180 - 1528.91 KB
EXPGolombReader 10000 1,170.19 us 22.642 us 25.167 us 152.3438 - - 937.5 KB
H264Decoder 10000 119,152.25 us 955.118 us 893.418 us 12800.0000 200.0000 - 78672.14 KB
FlvEncoder 10000 21,582.41 us 587.627 us 549.667 us 24937.5000 - - 152890.63 KB
EXPGolombReader 100000 11,687.72 us 162.828 us 152.309 us 1515.6250 - - 9375 KB
H264Decoder 100000 1,192,549.87 us 7,656.632 us 7,162.018 us 128000.0000 3000.0000 - 786718.75 KB
FlvEncoder 100000 216,951.31 us 3,513.653 us 2,934.059 us 249333.3333 - - 1528906.66 KB

jt1078's People

Contributors

china-live avatar smallchi avatar waterliu99 avatar yedajiang44 avatar zhulangren avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jt1078's Issues

性能测试

BenchmarkDotNet=v0.13.1, OS=Windows 10.0.19045
11th Gen Intel Core i7-11700F 2.50GHz, 1 CPU, 16 logical and 8 physical cores
.NET SDK=8.0.202
[Host] : .NET 6.0.28 (6.0.2824.12007), X64 RyuJIT [AttachedDebugger]
Job-LZLOBH : .NET 6.0.28 (6.0.2824.12007), X64 RyuJIT

Platform=AnyCpu Server=False Toolchain=.NET 6.0

Method N Mean Error StdDev Gen 0 Gen 1 Allocated
EXPGolombReader 100 7,341.12 ns 66.693 ns 55.692 ns 1.1444 - 9,600 B
H264Decoder 100 780,702.98 ns 2,497.850 ns 2,336.490 ns 95.7031 1.9531 805,600 B
FMp4Encoder 100 28.61 ns 0.194 ns 0.172 ns - - -
EXPGolombReader 10000 730,992.98 ns 5,814.555 ns 4,855.417 ns 114.2578 - 960,006 B
H264Decoder 10000 78,743,807.62 ns 981,727.009 ns 918,308.054 ns 9571.4286 142.8571 80,561,253 B
FMp4Encoder 10000 2,290.20 ns 24.414 ns 22.837 ns - - -
EXPGolombReader 100000 7,265,561.56 ns 37,196.671 ns 34,793.789 ns 1140.6250 - 9,600,045 B
H264Decoder 100000 785,847,980.00 ns 5,303,053.644 ns 4,960,479.669 ns 96000.0000 2000.0000 805,603,376 B
FMp4Encoder 100000 22,444.51 ns 83.161 ns 69.443 ns - - -

关于自定义位置附加工厂

厂商AttachInfoId一位AttachInfoLength两位,参考DEMO10的代码,但是
IJT808Config接口中的IJT808_0x0200_Custom_Factory也是自定义实现的,我在引用nuget包版本的情况下应该如何修改呢

视频延迟问题

我今天部署到阿里云服务器。在客户端访问有15秒左右的延迟。这个延迟有点高。大神哪里需要修改配置吗?谢谢

建议将JT1078.Protocol项目中的音/视频编解码部分抽象为接口,为上层应用项目提供扩展的可能性

变更内容

  1. JT1078.Protocol项目中新建Video目录,将现有的H264目录移动到Video下。
  2. JT1078.Protocol项目音/视频解码/编码抽象定义为接口,为上层项目提供扩展的可能性。

变更理由

  1. 终端上来的视频不一定是H264、也有可能是其它格式。同时Video与Audio相对应,更能体现代码结构的条理性,提升代码的可读性。
    2.当前项目音视频解码和编码为强依赖实现,目前实际项目时就遇到,我需要在在自己的项目中引用 JT1078.Flv ,但要自己增加音频部分,原本直接引用NuGet包就可以了,但现在我需要将 JT1078.Protocol和JT1078.Flv源码拷贝过去自行编译修改。
    3.音视频编解码本身就是一项相当专业且复杂的工作,我们不可能在这个协议库里把所有音视频编解码方法都实现或集成进来。
    4.本质上,协议库和音视频编解码没有直接关系,将音视频编解码相关功能内置到协议库中,会导致协议库臃肿且丧失可扩展性。
    将音视频编解码相关功能抽象为接口,让上层应用根据需要自行选择或实现,内置最常用,最基本的默认实现就可以了。

相关影响

  1. 变更后,JT1078.Protocol 项目中原 JT1078.Protocol.H264 命名空间 将同步变更为 JT1078.Protocol.Video.H264
  2. 从现有的H264Decoder提取接口IH264Decoder,原直接使用H264编码的地方,如 H264Decoder h264Decoder = new H264Decoder();变更为 IH264Decoder h264Decoder = new H264Decoder();services.AddSingleton(); 变更为
    services.AddSingleton<IH264Decoder,H264Decoder>();
    3.音频相关的和上面第2条类似...

0x9101 code example

Could you please provide a small example how can I send a 0x9101 code to start multimedia streaming.

您好 请问 下发0x9102指令 切换码流(主码流,子码流 )切换不成功

JT808_0x9102 jT808_0X9102 = new JT808_0x9102();
jT808_0X9102.ChannelNo = channel;
jT808_0X9102.ControlCmd = controlcmd;
jT808_0X9102.StreamType = streamtype;
JT808Package jT808Package = new JT808Package
{
Header = new JT808Header
{
MsgId = JT808_JT1078_MsgId.音视频实时传输控制.ToUInt16Value(),
MsgNum = msgNum,
TerminalPhoneNo = sim,
MessageBodyProperty = new JT808HeaderMessageBodyProperty()
},
Bodies = jT808_0X9102
};
var byteData = JT808Serializer.Serialize(jT808Package);
result = jT808UnificationSendService.Send(sim, byteData);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.