public void SerializeTest2() { JT1078Package jT1078Package = new JT1078Package(); jT1078Package.Label1 = new JT1078Label1(0x81); jT1078Package.Label2 = new JT1078Label2(0x88); jT1078Package.SN = 0x10BA; jT1078Package.SIM = "11234567810"; jT1078Package.LogicChannelNumber = 0x01; jT1078Package.Label3 = new JT1078Label3(0x30); jT1078Package.Timestamp = 1562085871501; jT1078Package.Bodies = "FE 6D 3B BE EF 3E 4E 7D FF B7 6D 5F F5 6F C7 BE 6F DF 77 DC DF 8E ED 3B 6F E3 3F B5 73 DF 6F EC F8 FD FF FE BE EF DB F7 6F DB BF FD D7 BF 6F FB 6F 6E F7 FF 5F DF BF D3 F7 8F FD FA B2 EF 3E F7 5F FF F1 5D 3F BF FB 26 BE ED C7 B7 7D 3F AE E3 FB EF 1D 3B AE 93 FE EF 7F DF 77 93 FE B6 65 3B BD FA E6 8E ED F8 F7 EF DB B1 FF C6 6F 7C FF EF FD DB 71 7F FF 6E EE 3E".ToHexBytes(); var hex = JT1078Serializer.Serialize(jT1078Package).ToHexString(); Assert.Equal("30 31 63 64 81 88 10 BA 01 12 34 56 78 10 01 30 00 00 01 6B B3 92 CF 8D 00 78 FE 6D 3B BE EF 3E 4E 7D FF B7 6D 5F F5 6F C7 BE 6F DF 77 DC DF 8E ED 3B 6F E3 3F B5 73 DF 6F EC F8 FD FF FE BE EF DB F7 6F DB BF FD D7 BF 6F FB 6F 6E F7 FF 5F DF BF D3 F7 8F FD FA B2 EF 3E F7 5F FF F1 5D 3F BF FB 26 BE ED C7 B7 7D 3F AE E3 FB EF 1D 3B AE 93 FE EF 7F DF 77 93 FE B6 65 3B BD FA E6 8E ED F8 F7 EF DB B1 FF C6 6F 7C FF EF FD DB 71 7F FF 6E EE 3E".Replace(" ", ""), hex); }
public void SerializeTest4() { JT1078Package jT1078Package = new JT1078Package(); jT1078Package.Label1 = new JT1078Label1(0x81); jT1078Package.Label2 = new JT1078Label2(0x88); jT1078Package.SN = 0x1135; jT1078Package.SIM = "11234567810"; jT1078Package.LogicChannelNumber = 0x01; jT1078Package.Label3 = new JT1078Label3(0x30); jT1078Package.Timestamp = 1562085874181; jT1078Package.Bodies = "B7 6D FF EF 7D FB A9 9D FE A9 1F 37 77 F3 37 BE EF FB F7 FB FB BE 7D DF B7 FD FB 76 AF DE 77 65 C7 EF E3 FB BE FF DB 4E FF DB B7 63 FF EE EF D8 BE 1D 37 B7 7D E7 7D F3 C6 F7 FD F4 BE 1F F7 B7 55 FF 76 FC FE CE 7B FF B7 7D 3F F5 FF FE 76 6C DF FE 53 DB CF 6D FB BF FD DE B1 EF 3E 77 D3 3F 6E 9A BF BF FF DB F7 FD DB 7F 63 FF 6E EC F8 EE 1F FB FD 7F FB 7D 7C DB".ToHexBytes(); var hex = JT1078Serializer.Serialize(jT1078Package).ToHexString(); Assert.Equal("30 31 63 64 81 88 11 35 01 12 34 56 78 10 01 30 00 00 01 6B B3 92 DA 05 00 78 B7 6D FF EF 7D FB A9 9D FE A9 1F 37 77 F3 37 BE EF FB F7 FB FB BE 7D DF B7 FD FB 76 AF DE 77 65 C7 EF E3 FB BE FF DB 4E FF DB B7 63 FF EE EF D8 BE 1D 37 B7 7D E7 7D F3 C6 F7 FD F4 BE 1F F7 B7 55 FF 76 FC FE CE 7B FF B7 7D 3F F5 FF FE 76 6C DF FE 53 DB CF 6D FB BF FD DE B1 EF 3E 77 D3 3F 6E 9A BF BF FF DB F7 FD DB 7F 63 FF 6E EC F8 EE 1F FB FD 7F FB 7D 7C DB".Replace(" ", ""), hex); }
public void JT1078SerializeTest() { for (int i = 0; i < N; i++) { JT1078Package jT1078Package = new JT1078Package(); jT1078Package.Label1 = new JT1078Label1(0x81); jT1078Package.Label2 = new JT1078Label2(0x88); jT1078Package.SN = 0x1135; jT1078Package.SIM = "11234567810"; jT1078Package.LogicChannelNumber = 0x01; jT1078Package.Label3 = new JT1078Label3(0x30); jT1078Package.Timestamp = 1562085874181; jT1078Package.Bodies = Enumerable.Range(0, 900).Select(s => (byte)(s + 1)).ToArray(); var hex = JT1078Serializer.Serialize(jT1078Package); } }
public void EncoderVideoTagTest1() { try { var bytes = "3031636481E206AD0019013050370210000001749162905508480050000E0000000161E4025F0000030037A03031636481E206AE001901305037021000000174916290A508980050000E0000000161E4225F0000030037A0".ToHexBytes(); FlvEncoder encoder = new FlvEncoder(); JT1078Package package = JT1078Serializer.Deserialize(bytes); JT1078Package fullpackage = JT1078Serializer.Merge(package); if (fullpackage != null) { var videoTag = encoder.EncoderVideoTag(fullpackage, false); } } catch (Exception ex) { } }
public void EncoderVideoTagTest2() { try { var bytes = "3031636481E2022D0019013050370210000001749179C79D05C80050000E0000000161E1E2FF000003006840".ToHexBytes(); FlvEncoder encoder = new FlvEncoder(); JT1078Package package = JT1078Serializer.Deserialize(bytes); JT1078Package fullpackage = JT1078Serializer.Merge(package); if (fullpackage != null) { var videoTag = encoder.EncoderVideoTag(fullpackage, false); } } catch (Exception ex) { } }
public void SerializeTest1() { 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(); Assert.Equal("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".Replace(" ", ""), hex); }
public void MergeTest() { var lines = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "JT1078.txt")); JT1078Package merge = null; int mergeBodyLength = 0; foreach (var line in lines) { var data = line.Split(','); var bytes = data[5].ToHexBytes(); JT1078Package package = JT1078Serializer.Deserialize(bytes); mergeBodyLength += package.DataBodyLength; merge = JT1078Serializer.Merge(package); } Assert.NotNull(merge); Assert.Equal(mergeBodyLength, merge.Bodies.Length); Assert.Equal(JT1078SubPackageType.分包处理时的第一个包, merge.Label3.SubpackageType); }
public void SerializeTest3() { JT1078Package jT1078Package = new JT1078Package(); jT1078Package.Label1 = new JT1078Label1(0x81); jT1078Package.Label2 = new JT1078Label2(0xE2); jT1078Package.SN = 0x10BB; jT1078Package.SIM = "11234567810"; jT1078Package.LogicChannelNumber = 0x01; jT1078Package.Label3 = new JT1078Label3(0x10); jT1078Package.LastIFrameInterval = 0x0730; jT1078Package.LastFrameInterval = 0x0028; jT1078Package.Timestamp = 1562085871404; jT1078Package.Bodies = "00 00 00 01 61 E4 62 BF 00 32 BE 88 82 3B 94 6F 41 EE 7C 28 7D 82 A5 9C 29 49 A8 4C BF".ToHexBytes(); var hex = JT1078Serializer.Serialize(jT1078Package).ToHexString(); Assert.Equal("30 31 63 64 81 E2 10 BB 01 12 34 56 78 10 01 10 00 00 01 6B B3 92 CF 2C 07 30 00 28 00 1D 00 00 00 01 61 E4 62 BF 00 32 BE 88 82 3B 94 6F 41 EE 7C 28 7D 82 A5 9C 29 49 A8 4C BF".Replace(" ", ""), hex); }
//private ConcurrentDictionary<string, byte> AudioCounter = new ConcurrentDictionary<string, byte>(); public byte[] CreateSDT(JT1078Package jt1078Package, int minBufferSize = 188) { byte[] buffer = TSArrayPool.Rent(minBufferSize); try { TS_SDT_Package package = new TS_SDT_Package(); package.Header = new TS_Header(); package.Header.PID = 0x0011; package.Header.AdaptationFieldControl = AdaptationFieldControl.无自适应域_仅含有效负载; package.Header.ContinuityCounter = 0; package.TableId = 0x42; package.TransportStreamId = 0x0001; package.VersionNumber = 0; package.CurrentNextIndicator = 0x01; package.SectionNumber = 0x00; package.LastSectionNumber = 0x00; package.OriginalNetworkId = 0xFF01; package.Services = new List <TS_SDT_Service>(); package.Services.Add(new TS_SDT_Service() { ServiceId = 0x0001, EITScheduleFlag = 0x00, EITPresentFollowingFlag = 0x00, RunningStatus = TS_SDT_Service_RunningStatus.运行, FreeCAMode = 0x00, Descriptors = new List <TS_SDT_Service_Descriptor> { new TS_SDT_Service_Descriptor { Tag = 0x48, ServiceType = TS_SDT_Service_Descriptor_ServiceType.数字电视业务, ServiceProvider = ServiceProvider, ServiceName = ServiceName } } }); TSMessagePackWriter writer = new TSMessagePackWriter(buffer); package.ToBuffer(ref writer); return(writer.FlushAndGetArray()); } finally { TSArrayPool.Return(buffer); } }
public void CreateM3U8File(JT1078Package fullpackage, byte[] data) { //ecode_slice_header error 以非关键帧开始的报错信息 //生成一个ts文件 var ts_name = $"{m3U8Option.TsFileCount}.ts"; var ts_filepath = Path.Combine(m3U8Option.HlsFileDirectory, ts_name); CreateTsFile(ts_filepath, data); var media_sequence_no = m3U8Option.TsFileCount - m3U8Option.TsFileCapacity; var del_ts_name = $"{media_sequence_no}.ts"; //更新m3u8文件 UpdateM3U8File(m3U8Option.AccumulateSeconds, media_sequence_no + 1, del_ts_name, ts_name); m3U8Option.IsNeedFirstHeadler = true; m3U8Option.AccumulateSeconds = 0; m3U8Option.TsFileCount = m3U8Option.TsFileCount + 1; }
public void ToBufferTest2() { FileStream fileStream = null; try { var filepath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "JT1078_1.ts"); File.Delete(filepath); var lines = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "JT1078_1.txt")); fileStream = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write); TSEncoder tSEncoder = new TSEncoder(); foreach (var line in lines) { var data = line.Split(','); var bytes = data[6].ToHexBytes(); JT1078Package package = JT1078Serializer.Deserialize(bytes); JT1078Package fullpackage = JT1078Serializer.Merge(package); if (fullpackage != null) { var sdt = tSEncoder.CreateSDT(); string sdtHEX = sdt.ToHexString(); fileStream.Write(sdt); var pat = tSEncoder.CreatePAT(); string patHEX = pat.ToHexString(); fileStream.Write(pat); var pmt = tSEncoder.CreatePMT(); fileStream.Write(pmt); var pes = tSEncoder.CreatePES(fullpackage); fileStream.Write(pes); } } } catch (Exception ex) { Assert.Throws <Exception>(() => { }); } finally { fileStream?.Close(); fileStream?.Dispose(); } }
private void Button1_Click(object sender, EventArgs e) { if (string.IsNullOrEmpty(this.textBox1.Text)) { MessageBox.Show("请输入数据包!"); return; } try { var buffer = this.textBox1.Text.ToHexBytes(); JT1078Package package = JT1078Serializer.Deserialize(buffer); this.textBox2.Text = JsonConvert.SerializeObject(package, Formatting.Indented); } catch (Exception ex) { this.textBox2.Text = JsonConvert.SerializeObject(ex); } }
public List <JT1078Package> ParseNALUTests() { List <JT1078Package> packages = new List <JT1078Package>(); var lines = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "jt1078_3.txt")); int mergeBodyLength = 0; foreach (var line in lines) { var data = line.Split(','); var bytes = data[6].ToHexBytes(); JT1078Package package = JT1078Serializer.Deserialize(bytes); mergeBodyLength += package.DataBodyLength; var packageMerge = JT1078Serializer.Merge(package); if (packageMerge != null) { packages.Add(packageMerge); } } return(packages); }
private H264NALU Create(JT1078Package package, ReadOnlySpan <byte> naluheader, int startCodePrefix) { H264NALU nALU = new H264NALU(); nALU.SIM = package.SIM; nALU.DataType = package.Label3.DataType; nALU.LogicChannelNumber = package.LogicChannelNumber; nALU.LastFrameInterval = package.LastFrameInterval; nALU.LastIFrameInterval = package.LastIFrameInterval; if (startCodePrefix == 3) { nALU.StartCodePrefix = H264NALU.Start1; } else if (startCodePrefix == 4) { nALU.StartCodePrefix = H264NALU.Start2; } nALU.NALUHeader = new NALUHeader(naluheader); return(nALU); }
public void ParseNALUTest3() { string file = "jt1078_1"; var lines = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", $"{file}.txt")); string filepath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", $"{file}.h264"); if (File.Exists(filepath)) { File.Delete(filepath); } using var fileStream = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write); foreach (var line in lines) { var data = line.Split(','); var bytes = data[6].ToHexBytes(); JT1078Package package = JT1078Serializer.Deserialize(bytes); fileStream.Write(package.Bodies); } fileStream.Close(); }
protected override Task ExecuteAsync(CancellationToken stoppingToken) { MsgConsumer.OnMessage((Message) => { JT1078Package package = JT1078Serializer.Deserialize(Message.Data); var merge = JT1078.Protocol.JT1078Serializer.Merge(package); if (merge != null) { var hasHttpSessionn = HttpSessionManager.GetAllHttpContextBySimAndChannelNo(merge.SIM, merge.LogicChannelNumber); if (hasHttpSessionn.Count > 0) { M3U8FileManage.CreateTsData(merge); } else { M3U8FileManage.Clear(merge.SIM, merge.LogicChannelNumber); } } }); return(Task.CompletedTask); }
public void DeserializeTest2() { //30 31 63 64 //81 //88 //10 BA //01 12 34 56 78 10 //01 //30 //00 00 01 6B B3 92 CF 8D //00 78 //FE 6D 3B BE EF 3E 4E 7D //FF B7 6D 5F F5 6F C7 BE //6F DF 77 DC DF 8E ED 3B //6F E3 3F B5 73 DF 6F EC //F8 FD FF FE BE EF DB F7 //6F DB BF FD D7 BF 6F FB //6F 6E F7 FF 5F DF BF D3 //F7 8F FD FA B2 EF 3E F7 //5F FF F1 5D 3F BF FB 26 //BE ED C7 B7 7D 3F AE E3 //FB EF 1D 3B AE 93 FE EF //7F DF 77 93 FE B6 65 3B //BD FA E6 8E ED F8 F7 EF //DB B1 FF C6 6F 7C FF EF //FD DB 71 7F FF 6E EE 3E var bytes = "30 31 63 64 81 88 10 BA 01 12 34 56 78 10 01 30 00 00 01 6B B3 92 CF 8D 00 78 FE 6D 3B BE EF 3E 4E 7D FF B7 6D 5F F5 6F C7 BE 6F DF 77 DC DF 8E ED 3B 6F E3 3F B5 73 DF 6F EC F8 FD FF FE BE EF DB F7 6F DB BF FD D7 BF 6F FB 6F 6E F7 FF 5F DF BF D3 F7 8F FD FA B2 EF 3E F7 5F FF F1 5D 3F BF FB 26 BE ED C7 B7 7D 3F AE E3 FB EF 1D 3B AE 93 FE EF 7F DF 77 93 FE B6 65 3B BD FA E6 8E ED F8 F7 EF DB B1 FF C6 6F 7C FF EF FD DB 71 7F FF 6E EE 3E".ToHexBytes(); JT1078Package package = JT1078Serializer.Deserialize(bytes); Assert.Equal(0x81, package.Label1.ToByte()); Assert.Equal(0x88, package.Label2.ToByte()); Assert.Equal(0x10BA, package.SN); Assert.Equal("011234567810", package.SIM); Assert.Equal(0x01, package.LogicChannelNumber); Assert.Equal(0x30, package.Label3.ToByte()); Assert.Equal((ulong)1562085871501, package.Timestamp); Assert.Equal(0x0078, package.DataBodyLength); Assert.Equal("FE 6D 3B BE EF 3E 4E 7D FF B7 6D 5F F5 6F C7 BE 6F DF 77 DC DF 8E ED 3B 6F E3 3F B5 73 DF 6F EC F8 FD FF FE BE EF DB F7 6F DB BF FD D7 BF 6F FB 6F 6E F7 FF 5F DF BF D3 F7 8F FD FA B2 EF 3E F7 5F FF F1 5D 3F BF FB 26 BE ED C7 B7 7D 3F AE E3 FB EF 1D 3B AE 93 FE EF 7F DF 77 93 FE B6 65 3B BD FA E6 8E ED F8 F7 EF DB B1 FF C6 6F 7C FF EF FD DB 71 7F FF 6E EE 3E".ToHexBytes(), package.Bodies.ToArray()); }
public void DeserializeTest4() { //30 31 63 64 //81 //88 //11 35 //01 12 34 56 78 10 //01 //30 //00 00 01 6B B3 92 DA 05 //00 78 //B7 6D FF EF 7D FB A9 9D //FE A9 1F 37 77 F3 37 BE //EF FB F7 FB FB BE 7D DF //B7 FD FB 76 AF DE 77 65 //C7 EF E3 FB BE FF DB 4E //FF DB B7 63 FF EE EF D8 //BE 1D 37 B7 7D E7 7D F3 //C6 F7 FD F4 BE 1F F7 B7 //55 FF 76 FC FE CE 7B FF //B7 7D 3F F5 FF FE 76 6C //DF FE 53 DB CF 6D FB BF //FD DE B1 EF 3E 77 D3 3F //6E 9A BF BF FF DB F7 FD //DB 7F 63 FF 6E EC F8 EE //1F FB FD 7F FB 7D 7C DB var bytes = "30 31 63 64 81 88 11 35 01 12 34 56 78 10 01 30 00 00 01 6B B3 92 DA 05 00 78 B7 6D FF EF 7D FB A9 9D FE A9 1F 37 77 F3 37 BE EF FB F7 FB FB BE 7D DF B7 FD FB 76 AF DE 77 65 C7 EF E3 FB BE FF DB 4E FF DB B7 63 FF EE EF D8 BE 1D 37 B7 7D E7 7D F3 C6 F7 FD F4 BE 1F F7 B7 55 FF 76 FC FE CE 7B FF B7 7D 3F F5 FF FE 76 6C DF FE 53 DB CF 6D FB BF FD DE B1 EF 3E 77 D3 3F 6E 9A BF BF FF DB F7 FD DB 7F 63 FF 6E EC F8 EE 1F FB FD 7F FB 7D 7C DB".ToHexBytes(); JT1078Package package = JT1078Serializer.Deserialize(bytes); Assert.Equal(0x81, package.Label1.ToByte()); Assert.Equal(0x88, package.Label2.ToByte()); Assert.Equal(0x1135, package.SN); Assert.Equal("011234567810", package.SIM); Assert.Equal(0x01, package.LogicChannelNumber); Assert.Equal(0x30, package.Label3.ToByte()); Assert.Equal((ulong)1562085874181, package.Timestamp); Assert.Equal(0x0078, package.DataBodyLength); Assert.Equal("B7 6D FF EF 7D FB A9 9D FE A9 1F 37 77 F3 37 BE EF FB F7 FB FB BE 7D DF B7 FD FB 76 AF DE 77 65 C7 EF E3 FB BE FF DB 4E FF DB B7 63 FF EE EF D8 BE 1D 37 B7 7D E7 7D F3 C6 F7 FD F4 BE 1F F7 B7 55 FF 76 FC FE CE 7B FF B7 7D 3F F5 FF FE 76 6C DF FE 53 DB CF 6D FB BF FD DE B1 EF 3E 77 D3 3F 6E 9A BF BF FF DB F7 FD DB 7F 63 FF 6E EC F8 EE 1F FB FD 7F FB 7D 7C DB".ToHexBytes(), package.Bodies.ToArray()); }
public byte[] CreatePMT(JT1078Package jt1078Package, int minBufferSize = 188) { byte[] buffer = TSArrayPool.Rent(minBufferSize); try { TS_PMT_Package package = new TS_PMT_Package(); package.Header = new TS_Header(); package.Header.ContinuityCounter = PMTCounter.AddOrUpdate(jt1078Package.GetKey(), 0, (a, b) => { if (b > 0xf) { return(0); } else { return((byte)(b + 1)); } }); package.Header.AdaptationFieldControl = AdaptationFieldControl.无自适应域_仅含有效负载; package.Header.PayloadUnitStartIndicator = 1; package.Header.PID = 4096; package.TableId = 0x02; package.Components = new List <TS_PMT_Component>(); package.Components.Add(new TS_PMT_Component { StreamType = StreamType.h264, ElementaryPID = 256, ESInfoLength = 0 }); TSMessagePackWriter messagePackReader = new TSMessagePackWriter(buffer); package.ToBuffer(ref messagePackReader); return(messagePackReader.FlushAndGetArray()); } finally { TSArrayPool.Return(buffer); } }
private H264NALU Create(JT1078Package package, ReadOnlySpan <byte> nalu, int startCodePrefix) { H264NALU nALU = new H264NALU(); nALU.SIM = package.SIM; nALU.DataType = package.Label3.DataType; nALU.LogicChannelNumber = package.LogicChannelNumber; nALU.LastFrameInterval = package.LastFrameInterval; nALU.LastIFrameInterval = package.LastIFrameInterval; nALU.Timestamp = package.Timestamp; nALU.Slice = (nalu[1] & 0x80) == 0x80; nALU.RawData = nalu.ToArray(); if (startCodePrefix == 3) { nALU.StartCodePrefix = H264NALU.Start1; } else if (startCodePrefix == 4) { nALU.StartCodePrefix = H264NALU.Start2; } nALU.NALUHeader = new NALUHeader(nalu.Slice(0, 1)); return(nALU); }
/// <summary> /// 编码其他视频数据盒子 /// </summary> /// <param name="package">jt1078完整包</param> /// <param name="moofOffset">moof位置</param> /// <returns></returns> public byte[] EncoderOtherVideoBox(JT1078Package package, ulong moofOffset = 0) { byte[] buffer = FMp4ArrayPool.Rent(package.Bodies.Length + 4096); FMp4MessagePackWriter writer = new FMp4MessagePackWriter(buffer); try { var nalus = h264Decoder.ParseNALU(package); var movieFragmentBox = new MovieFragmentBox(); movieFragmentBox.MovieFragmentHeaderBox = new MovieFragmentHeaderBox(); movieFragmentBox.MovieFragmentHeaderBox.SequenceNumber = package.SN; movieFragmentBox.TrackFragmentBox = new TrackFragmentBox(); movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox = new TrackFragmentHeaderBox(0x39); movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.TrackID = 1; movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.BaseDataOffset = moofOffset; movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleDuration = 48000; movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleSize = (uint)package.Bodies.Length; movieFragmentBox.TrackFragmentBox.TrackFragmentHeaderBox.DefaultSampleFlags = 0x1010000; movieFragmentBox.TrackFragmentBox.TrackFragmentBaseMediaDecodeTimeBox = new TrackFragmentBaseMediaDecodeTimeBox(); movieFragmentBox.TrackFragmentBox.TrackFragmentBaseMediaDecodeTimeBox.BaseMediaDecodeTime = package.Timestamp * 1000; //trun movieFragmentBox.TrackFragmentBox.TrackRunBox = new TrackRunBox(flags: 0x5); movieFragmentBox.TrackFragmentBox.TrackRunBox.FirstSampleFlags = 0; movieFragmentBox.TrackFragmentBox.TrackRunBox.TrackRunInfos = new List <TrackRunBox.TrackRunInfo>(); movieFragmentBox.TrackFragmentBox.TrackRunBox.TrackRunInfos.Add(new TrackRunBox.TrackRunInfo()); movieFragmentBox.ToBuffer(ref writer); var mediaDataBox = new MediaDataBox(); mediaDataBox.Data = nalus.Select(s => s.RawData).ToList(); mediaDataBox.ToBuffer(ref writer); var data = writer.FlushAndGetArray(); return(data); } finally { FMp4ArrayPool.Return(buffer); } }
public void 测试可以播放的Flv3() { FileStream fileStream = null; try { var filepath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "JT1078_3.flv"); var lines = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "JT1078_3.txt")); fileStream = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write); bool isNeedFirstHeadler = true; FlvEncoder encoder = new FlvEncoder(); foreach (var line in lines) { var data = line.Split(','); var bytes = data[6].ToHexBytes(); JT1078Package package = JT1078Serializer.Deserialize(bytes); JT1078Package fullpackage = JT1078Serializer.Merge(package); if (fullpackage != null) { var videoTag = encoder.EncoderVideoTag(fullpackage, isNeedFirstHeadler); fileStream.Write(videoTag); isNeedFirstHeadler = false; } } } catch (Exception ex) { Assert.Throws <Exception>(() => { }); } finally { fileStream?.Close(); fileStream?.Dispose(); } }
public async ValueTask ProduceAsync(string terminalNo, JT1078Package data) { await Channel.Channel.Writer.WriteAsync((terminalNo, data)); }
public JT1078Request(JT1078Package package, byte[] src) { Package = package; Src = src; }
public byte[] CreatePES(JT1078Package jt1078Package, int minBufferSize = 188) { //将1078一帧的数据拆分成一小段一小段的PES包 byte[] buffer = TSArrayPool.Rent(jt1078Package.Bodies.Length + minBufferSize); TSMessagePackWriter messagePackReader = new TSMessagePackWriter(buffer); //TSHeader + Adaptation + PES1 //TSHeader + PES2 //TSHeader + Adaptation + PESN try { int totalLength = 0; TS_Package package = new TS_Package(); package.Header = new TS_Header(); //ts header 4 totalLength += 4; package.Header.PID = 256; string key = jt1078Package.GetKey(); if (VideoCounter.TryGetValue(key, out byte counter)) { if (counter > 0xf) { counter = 0; } package.Header.ContinuityCounter = counter++; VideoCounter.TryUpdate(key, counter, counter); } else { package.Header.ContinuityCounter = counter++; VideoCounter.TryAdd(key, counter); } package.Header.PayloadUnitStartIndicator = 1; package.Header.Adaptation = new TS_AdaptationInfo(); package.Payload = new PES_Package(); package.Payload.StreamId = 0xe0; package.Payload.PESPacketLength = 0; //PESStartCode + StreamId + PESPacketLength //3 + 1 + 2 totalLength += (3 + 1 + 2); package.Payload.PTS_DTS_Flag = PTS_DTS_Flags.all; if (jt1078Package.Label3.DataType == JT1078DataType.视频I帧) { //ts header adaptation //PCRIncluded + PCR //1 + 5 totalLength += (1 + 5); package.Header.Adaptation.PCRIncluded = PCRInclude.包含; package.Header.Adaptation.PCR = jt1078Package.LastIFrameInterval; package.Payload.DTS = jt1078Package.LastIFrameInterval; package.Payload.PTS = jt1078Package.LastIFrameInterval; } else { //ts header adaptation //PCRIncluded //1 totalLength += 1; package.Header.Adaptation.PCRIncluded = PCRInclude.包含; package.Payload.DTS = jt1078Package.LastFrameInterval; package.Payload.PTS = jt1078Package.LastFrameInterval; } //Flag1 + PTS_DTS_Flag + DTS + PTS //1 + 1 + 5 + 5 totalLength += 12; //根据计算剩余的长度进行是否需要填充第一包 var remainingLength = FiexdTSLength - totalLength; int index = 0; //情况1:1078的第一包不够剩余(remainingLength)字节 //情况2:1078的第一包比剩余(remainingLength)字节多 //情况3: 1078的第一包等于剩余(remainingLength)字节 //填充大小 int fullSize = jt1078Package.Bodies.Length - remainingLength; package.Payload.Payload = new ES_Package(); if (fullSize < 0) { //这个很重要,需要控制 package.Header.AdaptationFieldControl = AdaptationFieldControl.时带有自适应域和有效负载; //还差一点 fullSize = Math.Abs(fullSize); package.Header.Adaptation.FillSize = (byte)fullSize; package.Payload.Payload.NALUs = new List <byte[]>() { jt1078Package.Bodies }; package.ToBuffer(ref messagePackReader); } else if (fullSize == 0) { //这个很重要,需要控制 package.Header.AdaptationFieldControl = AdaptationFieldControl.无自适应域_仅含有效负载; //刚刚好 package.Header.Adaptation.FillSize = 0; package.Payload.Payload.NALUs = new List <byte[]>() { jt1078Package.Bodies }; package.ToBuffer(ref messagePackReader); } else { //这个很重要,需要控制 package.Header.AdaptationFieldControl = AdaptationFieldControl.时带有自适应域和有效负载; //太多了,需要拆分 package.Header.Adaptation.FillSize = 0; package.Payload.Payload.NALUs = new List <byte[]>(); ReadOnlySpan <byte> dataReader = jt1078Package.Bodies; package.Payload.Payload.NALUs.Add(dataReader.Slice(index, remainingLength).ToArray()); index += remainingLength; package.ToBuffer(ref messagePackReader); while (index != jt1078Package.Bodies.Length) { if (counter > 0xf) { counter = 0; } int segmentFullSize = jt1078Package.Bodies.Length - index; if (segmentFullSize >= FiexdSegmentPESLength) { CreateSegmentPES(ref messagePackReader, dataReader.Slice(index, FiexdSegmentPESLength).ToArray(), counter++); } else { CreateSegmentPES(ref messagePackReader, dataReader.Slice(index, segmentFullSize).ToArray(), counter++); index += segmentFullSize; } } VideoCounter.TryUpdate(key, counter, counter); } return(messagePackReader.FlushAndGetArray()); } finally { TSArrayPool.Return(buffer); } }
public void Setup() { var lines = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "JT1078_1.txt")); foreach (var line in lines) { var data = line.Split(','); var bytes = data[6].ToHexBytes(); JT1078Package package = JT1078Serializer.Deserialize(bytes); Package = JT1078Serializer.Merge(package); } H264NALUs = h264Decoder.ParseNALU(Package); SPSNALu = H264NALUs.FirstOrDefault(f => f.NALUHeader.NalUnitType == NalUnitType.SPS); SPSNALu.RawData = h264Decoder.DiscardEmulationPreventionBytes(SPSNALu.RawData); List <JT1078Package> packages = new List <JT1078Package>(); var lines3 = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "jt1078_3.txt")); int mergeBodyLength = 0; foreach (var line in lines3) { var data = line.Split(','); var bytes = data[6].ToHexBytes(); JT1078Package package = JT1078Serializer.Deserialize(bytes); mergeBodyLength += package.DataBodyLength; var packageMerge = JT1078Serializer.Merge(package); if (packageMerge != null) { packages.Add(packageMerge); } } List <H264NALU> nalus = new List <H264NALU>(); bool segmentFlag = false; foreach (var package in packages) { if (segmentFlag) { break; } List <H264NALU> h264NALUs = h264Decoder.ParseNALU(package); foreach (var nalu in h264NALUs) { if (nalu.Slice) { //H264 NALU slice first_mb_in_slice nalus.Add(nalu); } else { if (nalus.Count > 0) { FMp4H264NALUs = new List <H264NALU>(nalus); segmentFlag = true; nalus.Clear(); } nalus.Add(nalu); } } } }
/// <summary> /// 编码首个视频盒子 /// </summary> /// <param name="package">jt1078完整包</param> /// <returns></returns> public byte[] EncoderFirstVideoBox(JT1078Package package) { byte[] buffer = FMp4ArrayPool.Rent(package.Bodies.Length + 4096); FMp4MessagePackWriter writer = new FMp4MessagePackWriter(new byte[10 * 1024 * 1024]); try { var nalus = h264Decoder.ParseNALU(package); var spsNALU = nalus.FirstOrDefault(n => n.NALUHeader.NalUnitType == 7); //SPS spsNALU.RawData = h264Decoder.DiscardEmulationPreventionBytes(spsNALU.RawData); var ppsNALU = nalus.FirstOrDefault(n => n.NALUHeader.NalUnitType == 8); ppsNALU.RawData = h264Decoder.DiscardEmulationPreventionBytes(ppsNALU.RawData); ExpGolombReader h264GolombReader = new ExpGolombReader(spsNALU.RawData); var spsInfo = h264GolombReader.ReadSPS(); //ftyp FileTypeBox fileTypeBox = new FileTypeBox(); fileTypeBox.MajorBrand = "isom"; fileTypeBox.MinorVersion = "\0\0\u0002\0"; fileTypeBox.CompatibleBrands.Add("isom"); fileTypeBox.CompatibleBrands.Add("iso6"); fileTypeBox.CompatibleBrands.Add("iso2"); fileTypeBox.CompatibleBrands.Add("avc1"); fileTypeBox.CompatibleBrands.Add("mp41"); //moov MovieBox movieBox = new MovieBox(); movieBox.MovieHeaderBox = new MovieHeaderBox(0, 0); movieBox.MovieHeaderBox.CreationTime = 0; movieBox.MovieHeaderBox.ModificationTime = 0; movieBox.MovieHeaderBox.Duration = 0; movieBox.MovieHeaderBox.Timescale = 1000; movieBox.MovieHeaderBox.NextTrackID = 2; movieBox.TrackBox = new TrackBox(); movieBox.TrackBox.TrackHeaderBox = new TrackHeaderBox(0, 3); movieBox.TrackBox.TrackHeaderBox.CreationTime = 0; movieBox.TrackBox.TrackHeaderBox.ModificationTime = 0; movieBox.TrackBox.TrackHeaderBox.TrackID = 1; movieBox.TrackBox.TrackHeaderBox.Duration = 0; movieBox.TrackBox.TrackHeaderBox.TrackIsAudio = false; movieBox.TrackBox.TrackHeaderBox.Width = (uint)spsInfo.width; movieBox.TrackBox.TrackHeaderBox.Height = (uint)spsInfo.height; movieBox.TrackBox.MediaBox = new MediaBox(); movieBox.TrackBox.MediaBox.MediaHeaderBox = new MediaHeaderBox(); movieBox.TrackBox.MediaBox.MediaHeaderBox.CreationTime = 0; movieBox.TrackBox.MediaBox.MediaHeaderBox.ModificationTime = 0; movieBox.TrackBox.MediaBox.MediaHeaderBox.Timescale = 1200000; movieBox.TrackBox.MediaBox.MediaHeaderBox.Duration = 0; movieBox.TrackBox.MediaBox.HandlerBox = new HandlerBox(); movieBox.TrackBox.MediaBox.HandlerBox.HandlerType = HandlerType.vide; movieBox.TrackBox.MediaBox.HandlerBox.Name = "VideoHandler"; movieBox.TrackBox.MediaBox.MediaInformationBox = new MediaInformationBox(); movieBox.TrackBox.MediaBox.MediaInformationBox.VideoMediaHeaderBox = new VideoMediaHeaderBox(); movieBox.TrackBox.MediaBox.MediaInformationBox.DataInformationBox = new DataInformationBox(); movieBox.TrackBox.MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox = new DataReferenceBox(); movieBox.TrackBox.MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox.DataEntryBoxes = new List <DataEntryBox>(); movieBox.TrackBox.MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox.DataEntryBoxes.Add(new DataEntryUrlBox(1)); movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox = new SampleTableBox(); movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox = new SampleDescriptionBox(movieBox.TrackBox.MediaBox.HandlerBox.HandlerType); movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.SampleEntries = new List <SampleEntry>(); AVC1SampleEntry avc1 = new AVC1SampleEntry(); avc1.AVCConfigurationBox = new AVCConfigurationBox(); //h264 avc1.Width = (ushort)movieBox.TrackBox.TrackHeaderBox.Width; avc1.Height = (ushort)movieBox.TrackBox.TrackHeaderBox.Height; avc1.AVCConfigurationBox.AVCLevelIndication = spsInfo.levelIdc; avc1.AVCConfigurationBox.AVCProfileIndication = spsInfo.profileIdc; avc1.AVCConfigurationBox.ProfileCompatibility = (byte)spsInfo.profileCompat; avc1.AVCConfigurationBox.PPSs = new List <byte[]>() { ppsNALU.RawData }; avc1.AVCConfigurationBox.SPSs = new List <byte[]>() { spsNALU.RawData }; movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.SampleEntries.Add(avc1); movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.TimeToSampleBox = new TimeToSampleBox(); movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleToChunkBox = new SampleToChunkBox(); movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.SampleSizeBox = new SampleSizeBox(); movieBox.TrackBox.MediaBox.MediaInformationBox.SampleTableBox.ChunkOffsetBox = new ChunkOffsetBox(); movieBox.MovieExtendsBox = new MovieExtendsBox(); movieBox.MovieExtendsBox.TrackExtendsBoxs = new List <TrackExtendsBox>(); TrackExtendsBox trex = new TrackExtendsBox(); trex.TrackID = 1; trex.DefaultSampleDescriptionIndex = 1; trex.DefaultSampleDuration = 0; trex.DefaultSampleSize = 0; trex.DefaultSampleFlags = 0; movieBox.MovieExtendsBox.TrackExtendsBoxs.Add(trex); fileTypeBox.ToBuffer(ref writer); movieBox.ToBuffer(ref writer); var data = writer.FlushAndGetArray(); return(data); } finally { FMp4ArrayPool.Return(buffer); } }
public void 测试主次码流切换() { FileStream fileStream = null; H264Decoder decoder = new H264Decoder(); List <H264NALU> h264NALULs = new List <H264NALU>(); FlvEncoder encoder = new FlvEncoder(); try { var filepath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "JT1078_5.flv"); var lines = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "JT1078_5.txt")); if (File.Exists(filepath)) { File.Delete(filepath); } JT1078Package Package = null; foreach (var line in lines) { var data = line.Split(','); var bytes = data[6].ToHexBytes(); JT1078Package package = JT1078Serializer.Deserialize(bytes); Package = JT1078Serializer.Merge(package); if (Package != null) { var tmp = decoder.ParseNALU(Package); if (tmp != null && tmp.Count > 0) { h264NALULs = h264NALULs.Concat(tmp).ToList(); } } } var tmp1 = h264NALULs.Where(w => w.NALUHeader.NalUnitType == 7).ToList(); List <SPSInfo> tmpSpss = new List <SPSInfo>(); List <ulong> times = new List <ulong>(); List <ushort> lastIFrameIntervals = new List <ushort>(); List <ushort> lastFrameIntervals = new List <ushort>(); List <int> type = new List <int>(); foreach (var item in h264NALULs) { //type.Add(item.NALUHeader.NalUnitType); times.Add(item.Timestamp); lastFrameIntervals.Add(item.LastFrameInterval); lastIFrameIntervals.Add(item.LastIFrameInterval); if (item.NALUHeader.NalUnitType == 7) { ExpGolombReader expGolombReader = new ExpGolombReader(item.RawData); tmpSpss.Add(expGolombReader.ReadSPS()); } } fileStream = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write); var totalPage = (h264NALULs.Count + 10 - 1) / 10; for (var i = 0; i < totalPage; i++) { var flv2 = encoder.CreateFlvFrame(h264NALULs.Skip(i * 10).Take(10).ToList()); if (flv2.Length != 0) { //fileStream.Write(flv2); } } } catch (Exception ex) { Assert.Throws <Exception>(() => { }); } finally { fileStream?.Close(); fileStream?.Dispose(); } }
public byte[] CreatePES(JT1078Package jt1078Package, int minBufferSize = 188) { //将1078一帧的数据拆分成一小段一小段的PES包 byte[] buffer = TSArrayPool.Rent(jt1078Package.Bodies.Length + minBufferSize); TSMessagePackWriter messagePackReader = new TSMessagePackWriter(buffer); //TSHeader + Adaptation + PES1 //TSHeader + PES2 //TSHeader + Adaptation + PESN try { int totalLength = 0; TS_Package package = new TS_Package(); package.Header = new TS_Header(); //ts header 4 totalLength += 4; package.Header.PID = 256; package.Header.PackageType = PackageType.Data_Start; string key = jt1078Package.GetKey(); if (VideoCounter.TryGetValue(key, out byte counter)) { if (counter > 0xf) { counter = 0; } } else { VideoCounter.Add(key, counter); } package.Header.ContinuityCounter = counter; counter++; package.Header.PayloadUnitStartIndicator = 1; package.Header.Adaptation = new TS_AdaptationInfo(); package.Payload = new PES_Package(); package.Payload.StreamId = 0xe0; package.Payload.PESPacketLength = 0; //PESStartCode + StreamId+ Flag1 + PTS_DTS_Flag + PESPacketLength //3 + 1 + 1 + 1 + 2 totalLength += (3 + 1 + 1 + 1 + 2); package.Payload.PTS_DTS_Flag = PTS_DTS_Flags.all; long timestamp = (long)jt1078Package.Timestamp; if (jt1078Package.Label3.DataType == JT1078DataType.视频I帧) { //ts header adaptation //PCRIncluded + Timestamp //1 + 6 totalLength += (1 + 6); package.Header.Adaptation.PCRIncluded = PCRInclude.包含; package.Header.Adaptation.Timestamp = timestamp; package.Payload.DTS = timestamp * H264DefaultHZ; package.Payload.PTS = package.Payload.DTS + jt1078Package.LastIFrameInterval * H264DefaultHZ; } else if (jt1078Package.Label3.DataType == JT1078DataType.视频P帧) { //ts header adaptation //PCRIncluded //1 totalLength += 1; package.Header.Adaptation.PCRIncluded = PCRInclude.包含; package.Payload.DTS = timestamp * H264DefaultHZ; package.Payload.PTS = package.Payload.DTS + jt1078Package.LastFrameInterval * H264DefaultHZ; } //Flag1 + PTS_DTS_Flag + DTS + PTS //1 + 1 + 5 + 5 = 12 totalLength += 12; totalLength += TSConstants.FiexdESPackageHeaderLength; //根据计算剩余的长度进行是否需要填充第一包 var remainingLength = FiexdTSLength - totalLength; int index = 0; //情况1:1078的第一包不够剩余(remainingLength)字节 //情况2:1078的第一包比剩余(remainingLength)字节多 //情况3: 1078的第一包等于剩余(remainingLength)字节 //填充大小 int fullSize = jt1078Package.Bodies.Length - remainingLength; package.Payload.Payload = new ES_Package(); if (fullSize < 0) { //这个很重要,需要控制 package.Header.AdaptationFieldControl = AdaptationFieldControl.时带有自适应域和有效负载; //还差一点 fullSize = Math.Abs(fullSize); package.Header.Adaptation.FillSize = (byte)fullSize; package.Payload.Payload.NALUs = new List <byte[]>() { jt1078Package.Bodies }; package.ToBuffer(ref messagePackReader); } else if (fullSize == 0) { //这个很重要,需要控制 package.Header.AdaptationFieldControl = AdaptationFieldControl.无自适应域_仅含有效负载; //刚刚好 package.Header.Adaptation.FillSize = 0; package.Payload.Payload.NALUs = new List <byte[]>() { jt1078Package.Bodies }; package.ToBuffer(ref messagePackReader); } else { //这个很重要,需要控制 package.Header.AdaptationFieldControl = AdaptationFieldControl.时带有自适应域和有效负载; //太多了,需要拆分 package.Header.Adaptation.FillSize = 0; package.Payload.Payload.NALUs = new List <byte[]>(); ReadOnlySpan <byte> dataReader = jt1078Package.Bodies; package.Payload.Payload.NALUs.Add(dataReader.Slice(index, remainingLength).ToArray()); index += remainingLength; package.ToBuffer(ref messagePackReader); while (index != jt1078Package.Bodies.Length) { if (counter > 0xf) { counter = 0; } int segmentFullSize = jt1078Package.Bodies.Length - index; if (segmentFullSize >= FiexdSegmentPESLength) { CreateSegmentPES(ref messagePackReader, dataReader.Slice(index, FiexdSegmentPESLength).ToArray(), counter); index += FiexdSegmentPESLength; } else { var nalu = dataReader.Slice(index, segmentFullSize).ToArray(); //当等于183字节的时候 //12698D08E8DBDBCDF6C6FA19DD88490E908D687D1755BE87DF82754BE2D245270569310B3030A4904DF1883ED09A68CA1C79BC4B97642B5BC095A55E56868D05370D3BC8B7B60B4642A486B6852656C01FFADACEF4BD4320E8BE9C54D44177A433CC37493FA1D8ACD0164E92454D03B6EC0617B133AEF43B599BF85632AB9B5FF671F0DDAA07E8F279F5639BA88E3FFFFCE1D3351FAF43DF23BCEB7E3B2CAB3EABAED23B25097B7F51FF38E8D0EBAB589CEC42B0440EB8 //if (jt1078Package.Label3.DataType == JT1078DataType.视频P帧) //{ // string hex = dataReader.Slice(index, segmentFullSize).ToArray().ToHexString(); //} CreateSegmentPES(ref messagePackReader, dataReader.Slice(index, segmentFullSize).ToArray(), counter); index += segmentFullSize; } counter++; } } VideoCounter[key] = counter; return(messagePackReader.FlushAndGetArray()); } finally { TSArrayPool.Return(buffer); } }