diff --git a/src/JT1078.Hls.Test/TS_SDT_Package_Test.cs b/src/JT1078.Hls.Test/TS_SDT_Package_Test.cs
new file mode 100644
index 0000000..7348366
--- /dev/null
+++ b/src/JT1078.Hls.Test/TS_SDT_Package_Test.cs
@@ -0,0 +1,20 @@
+using JT1078.Hls.Enums;
+using JT1078.Hls.MessagePack;
+using JT1078.Protocol.Extensions;
+using System;
+using System.Collections.Generic;
+using Xunit;
+
+namespace JT1078.Hls.Test
+{
+ ///
+ /// ʹdoc/video/demo0.ts
+ ///
+ public class TS_SDT_Package_Test
+ {
+ [Fact]
+ public void ToBufferTest()
+ {
+ }
+ }
+}
diff --git a/src/JT1078.Hls/Enums/RunningStatus.cs b/src/JT1078.Hls/Enums/RunningStatus.cs
new file mode 100644
index 0000000..92d06e4
--- /dev/null
+++ b/src/JT1078.Hls/Enums/RunningStatus.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT1078.Hls.Enums
+{
+ ///
+ /// 运行状态
+ ///
+ public enum RunningStatus
+ {
+ 未定义=0,
+ 未运行=1,
+ 几秒后开始=2,
+ 暂停=3,
+ 运行=4,
+
+ }
+}
diff --git a/src/JT1078.Hls/JT1078.Hls.csproj b/src/JT1078.Hls/JT1078.Hls.csproj
index 20792fa..0d097b9 100644
--- a/src/JT1078.Hls/JT1078.Hls.csproj
+++ b/src/JT1078.Hls/JT1078.Hls.csproj
@@ -33,4 +33,7 @@
+
+
+
diff --git a/src/JT1078.Hls/MessagePack/TSMessagePackWriter.cs b/src/JT1078.Hls/MessagePack/TSMessagePackWriter.cs
index 4ae781f..08791c9 100644
--- a/src/JT1078.Hls/MessagePack/TSMessagePackWriter.cs
+++ b/src/JT1078.Hls/MessagePack/TSMessagePackWriter.cs
@@ -163,5 +163,11 @@ namespace JT1078.Hls.MessagePack
{
return writer.WrittenCount;
}
+ public void WriteString(string value)
+ {
+ byte[] codeBytes = TSConstants.Encoding.GetBytes(value);
+ codeBytes.CopyTo(writer.Free);
+ writer.Advance(codeBytes.Length);
+ }
}
}
diff --git a/src/JT1078.Hls/TSConstants.cs b/src/JT1078.Hls/TSConstants.cs
index 9f1fff9..78cd0a3 100644
--- a/src/JT1078.Hls/TSConstants.cs
+++ b/src/JT1078.Hls/TSConstants.cs
@@ -6,6 +6,12 @@ namespace JT1078.Hls
{
public static class TSConstants
{
+ static TSConstants()
+ {
+ Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
+ Encoding = Encoding.GetEncoding("GBK");
+ }
+ public static Encoding Encoding { get; }
///
/// 固定包长度
///
diff --git a/src/JT1078.Hls/TS_SDT_Package.cs b/src/JT1078.Hls/TS_SDT_Package.cs
index 80cac8e..5610478 100644
--- a/src/JT1078.Hls/TS_SDT_Package.cs
+++ b/src/JT1078.Hls/TS_SDT_Package.cs
@@ -3,6 +3,7 @@ using JT1078.Hls.Interfaces;
using JT1078.Hls.MessagePack;
using System;
using System.Collections.Generic;
+using System.Diagnostics.Tracing;
using System.Linq;
using System.Text;
@@ -15,12 +16,12 @@ namespace JT1078.Hls
{
public TS_Header Header { get; set; }
///
- /// PAT表固定为0x00
+ ///
/// 8bit
///
public byte TableId { get; set; } = 0x42;
///
- /// 固定为二进制1
+ ///
/// 1bit
///
internal byte SectionSyntaxIndicator { get; set; }
@@ -43,14 +44,14 @@ namespace JT1078.Hls
/// 传输流ID
/// 16bit
///
- internal ushort TransportStreamId { get; set; } = 0x0001;
+ internal ushort TransportStreamId { get; set; }
///
///
/// 2bit
///
internal byte Reserved2 { get; set; }
///
- /// 版本号,
+ ///
/// 5bit
///
public byte VersionNumber { get; set; }
@@ -79,7 +80,7 @@ namespace JT1078.Hls
/// 1Byte
///
internal byte ReservedFutureUse2 { get; set; }
- public List Services { get; set; }
+ public List Services { get; set; }
///
/// 前面数据的CRC32校验码
@@ -88,33 +89,21 @@ namespace JT1078.Hls
public void ToBuffer(ref TSMessagePackWriter writer)
{
- Header.PackageType = PackageType.PAT;
- Header.ToBuffer(ref writer);
writer.WriteByte(TableId);
- //SectionSyntaxIndicator Zero Reserved1 SectionLength
- //1 0 11 0000 0000 0000
- //(ushort)(0b_1011_0000_0000_0000 | SectionLength)
writer.Skip(2, out int SectionLengthPosition);
writer.WriteUInt16(TransportStreamId);
- //Reserved2 VersionNumber CurrentNextIndicator
- //11 00000 1
- var a = 0xC0 & (Reserved2 << 6);
- var b = 0x3E & (VersionNumber << 3);
- var c = (byte)(a | b | CurrentNextIndicator);
- writer.WriteByte(c);
+ writer.WriteByte((byte)(Reserved2 << 6 | VersionNumber << 1 | CurrentNextIndicator));
writer.WriteByte(SectionNumber);
writer.WriteByte(LastSectionNumber);
- //if (Programs != null)
- //{
- // foreach (var program in Programs)
- // {
- // program.ToBuffer(ref writer);
- // }
- //}
- const int crcLength= 4;
- writer.WriteUInt16Return((ushort)(0b_1011_0000_0000_0000 | (ushort)(writer.GetCurrentPosition() - SectionLengthPosition - 2)+ crcLength), SectionLengthPosition);
- //打包ts流时PAT和PMT表是没有adaptation field的,不够的长度直接补0xff即可。
- //ts header(4B) + adaptation field length(1)
+ writer.WriteUInt16(OriginalNetworkId);
+ writer.WriteByte(ReservedFutureUse2);
+ foreach (var service in Services)
+ {
+ service.ToBuffer(ref writer);
+ }
+ ushort servicesLength =(ushort)( writer.GetCurrentPosition() - SectionLengthPosition);
+ const int crcLength = 4;
+ writer.WriteUInt16Return((ushort)(SectionSyntaxIndicator<<15 | ReservedFutureUse1<<14 | servicesLength+ crcLength), SectionLengthPosition);
writer.WriteCRC32(5);
var size = TSConstants.FiexdPackageLength - writer.GetCurrentPosition();
writer.WriteArray(Enumerable.Range(0, size).Select(s => (byte)0xFF).ToArray());
diff --git a/src/JT1078.Hls/TS_SDT_Service.cs b/src/JT1078.Hls/TS_SDT_Service.cs
new file mode 100644
index 0000000..50458cd
--- /dev/null
+++ b/src/JT1078.Hls/TS_SDT_Service.cs
@@ -0,0 +1,76 @@
+using JT1078.Hls.Enums;
+using JT1078.Hls.Interfaces;
+using JT1078.Hls.MessagePack;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace JT1078.Hls
+{
+ ///
+ /// 业务描述服务
+ ///
+ public class TS_SDT_Service : ITSMessagePackFormatter
+ {
+ ///
+ /// 业务标识符
+ /// 用于在 TS 流中识别不同的业务。service_id 与program_map_section 中的 program_number 取同一值
+ /// 16bit
+ ///
+ internal ushort ServiceId { get; set; }
+ ///
+ ///
+ /// 6bit
+ ///
+ internal byte ReservedFutureUse { get; set; }
+ ///
+ /// EIT 时间表标志
+ /// 置“1”时,表示业务的 EIT 时间表信息存在于当前 TS 中(一个 EIT 时间表子表两次出现的最大时间间隔信息见 ETR 211)。
+ /// 置“0”时,表示业务的 EIT 时间表信息不在当前 TS 中
+ /// 1bit
+ ///
+ internal byte EITScheduleFlag { get; set; }
+ ///
+ /// EIT 当前后续标志
+ /// 置“1”时,表示业务的 EIT 当前后续信息存在于当前 TS 中(一个 EIT 当前后续子表两次出现的最大时间间隔信息见ETR 211)
+ /// 置“0”时,表示业务的 EIT 当前后续信息不在当前 TS 中。
+ /// 1bit
+ ///
+ public byte EITPresentFollowingFlag { get; set; }
+ ///
+ /// 运行状态
+ /// 对于一个 NVOD 业务,running_status 的值都置“0”
+ /// 3bit
+ ///
+ internal RunningStatus RunningStatus { get; set; }
+ ///
+ /// 自由条件接收模式
+ /// 置“0”时,表示业务的所有组件都未被加扰
+ /// 置“1”时,表示一路或多路码流的接收由 CA 系统控制。
+ /// 1bit
+ ///
+ internal byte FreeCAMode { get; set; }
+ ///
+ /// 描述符循环长度
+ /// 指出从本字段的下一个字节开始的描述符的总字节长度。
+ /// 12bit
+ ///
+ public ushort DescriptorsLoopLength { get; set; }
+
+ public List Descriptors { get; set; }
+
+ public void ToBuffer(ref TSMessagePackWriter writer)
+ {
+ writer.WriteUInt16(ServiceId);
+ writer.WriteByte((byte)((ReservedFutureUse << 2) | (EITScheduleFlag << 1) | EITPresentFollowingFlag));
+ writer.Skip(2, out var position);
+ foreach (var descriptor in Descriptors)
+ {
+ descriptor.ToBuffer(ref writer);
+ }
+ DescriptorsLoopLength = (ushort)(writer.GetCurrentPosition() - position);
+ writer.WriteUInt16Return((ushort)(((ushort)RunningStatus << 13) | ((ushort)FreeCAMode << 12) | DescriptorsLoopLength), position);
+ }
+ }
+}
diff --git a/src/JT1078.Hls/TS_SDT_Service_.cs b/src/JT1078.Hls/TS_SDT_Service_.cs
deleted file mode 100644
index e347080..0000000
--- a/src/JT1078.Hls/TS_SDT_Service_.cs
+++ /dev/null
@@ -1,123 +0,0 @@
-using JT1078.Hls.Enums;
-using JT1078.Hls.Interfaces;
-using JT1078.Hls.MessagePack;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace JT1078.Hls
-{
- ///
- /// 业务描述服务
- ///
- public class TS_SDT_Service : ITSMessagePackFormatter
- {
- public TS_Header Header { get; set; }
- ///
- /// PAT表固定为0x00
- /// 8bit
- ///
- public byte TableId { get; set; } = 0x42;
- ///
- /// 固定为二进制1
- /// 1bit
- ///
- internal byte SectionSyntaxIndicator { get; set; }
- ///
- ///
- /// 1bit
- ///
- internal byte ReservedFutureUse1 { get; set; }
- ///
- ///
- /// 2bit
- ///
- internal byte Reserved1 { get; set; }
- ///
- /// 后面数据的长度
- /// 12bit
- ///
- public ushort SectionLength { get; set; }
- ///
- /// 传输流ID
- /// 16bit
- ///
- internal ushort TransportStreamId { get; set; } = 0x0001;
- ///
- ///
- /// 2bit
- ///
- internal byte Reserved2 { get; set; }
- ///
- /// 版本号,
- /// 5bit
- ///
- public byte VersionNumber { get; set; }
- ///
- ///
- /// 1bit
- ///
- public byte CurrentNextIndicator { get; set; }
- ///
- ///
- /// bit8
- ///
- internal byte SectionNumber { get; set; }
- ///
- ///
- /// bit8
- ///
- internal byte LastSectionNumber { get; set; }
- ///
- ///
- /// bit8
- ///
- internal ushort OriginalNetworkId { get; set; }
- ///
- ///
- /// 1Byte
- ///
- internal byte ReservedFutureUse2 { get; set; }
- public List Services { get; set; }
-
- ///
- /// 前面数据的CRC32校验码
- ///
- public uint CRC32 { get; set; }
-
- public void ToBuffer(ref TSMessagePackWriter writer)
- {
- Header.PackageType = PackageType.PAT;
- Header.ToBuffer(ref writer);
- writer.WriteByte(TableId);
- //SectionSyntaxIndicator Zero Reserved1 SectionLength
- //1 0 11 0000 0000 0000
- //(ushort)(0b_1011_0000_0000_0000 | SectionLength)
- writer.Skip(2, out int SectionLengthPosition);
- writer.WriteUInt16(TransportStreamId);
- //Reserved2 VersionNumber CurrentNextIndicator
- //11 00000 1
- var a = 0xC0 & (Reserved2 << 6);
- var b = 0x3E & (VersionNumber << 3);
- var c = (byte)(a | b | CurrentNextIndicator);
- writer.WriteByte(c);
- writer.WriteByte(SectionNumber);
- writer.WriteByte(LastSectionNumber);
- //if (Programs != null)
- //{
- // foreach (var program in Programs)
- // {
- // program.ToBuffer(ref writer);
- // }
- //}
- const int crcLength= 4;
- writer.WriteUInt16Return((ushort)(0b_1011_0000_0000_0000 | (ushort)(writer.GetCurrentPosition() - SectionLengthPosition - 2)+ crcLength), SectionLengthPosition);
- //打包ts流时PAT和PMT表是没有adaptation field的,不够的长度直接补0xff即可。
- //ts header(4B) + adaptation field length(1)
- writer.WriteCRC32(5);
- var size = TSConstants.FiexdPackageLength - writer.GetCurrentPosition();
- writer.WriteArray(Enumerable.Range(0, size).Select(s => (byte)0xFF).ToArray());
- }
- }
-}
diff --git a/src/JT1078.Hls/TS_SDT_Service_Descriptor.cs b/src/JT1078.Hls/TS_SDT_Service_Descriptor.cs
index 19e0406..0c501a4 100644
--- a/src/JT1078.Hls/TS_SDT_Service_Descriptor.cs
+++ b/src/JT1078.Hls/TS_SDT_Service_Descriptor.cs
@@ -13,111 +13,53 @@ namespace JT1078.Hls
///
public class TS_SDT_Service_Descriptor : ITSMessagePackFormatter
{
- public TS_Header Header { get; set; }
- ///
- /// PAT表固定为0x00
- /// 8bit
- ///
- public byte TableId { get; set; } = 0x42;
- ///
- /// 固定为二进制1
- /// 1bit
- ///
- internal byte SectionSyntaxIndicator { get; set; }
- ///
- ///
- /// 1bit
- ///
- internal byte ReservedFutureUse1 { get; set; }
///
///
- /// 2bit
- ///
- internal byte Reserved1 { get; set; }
- ///
- /// 后面数据的长度
- /// 12bit
- ///
- public ushort SectionLength { get; set; }
- ///
- /// 传输流ID
- /// 16bit
+ /// 8bit
///
- internal ushort TransportStreamId { get; set; } = 0x0001;
+ public byte DescriptorTag { get; set; } = 0x48;
///
///
- /// 2bit
- ///
- internal byte Reserved2 { get; set; }
- ///
- /// 版本号,
- /// 5bit
+ /// 8bit
///
- public byte VersionNumber { get; set; }
+ internal byte DescriptorLength { get; set; } = 0x12;
///
///
- /// 1bit
+ /// 8bit
///
- public byte CurrentNextIndicator { get; set; }
+ internal byte ServiceType { get; set; } = 0x01;
///
///
- /// bit8
+ /// 8bit
///
- internal byte SectionNumber { get; set; }
+ internal byte ServiceProviderLength { get; set; }
///
///
- /// bit8
+ /// ServiceProviderLength
///
- internal byte LastSectionNumber { get; set; }
+ public string ServiceProvider { get; set; }
///
///
- /// bit8
+ /// 8bit
///
- internal ushort OriginalNetworkId { get; set; }
+ internal byte ServiceNameLenth { get; set; }
///
///
- /// 1Byte
+ /// ServiceNameLenth
///
- internal byte ReservedFutureUse2 { get; set; }
- public List Services { get; set; }
-
- ///
- /// 前面数据的CRC32校验码
- ///
- public uint CRC32 { get; set; }
-
+ internal string ServiceName { get; set; }
public void ToBuffer(ref TSMessagePackWriter writer)
{
- Header.PackageType = PackageType.PAT;
- Header.ToBuffer(ref writer);
- writer.WriteByte(TableId);
- //SectionSyntaxIndicator Zero Reserved1 SectionLength
- //1 0 11 0000 0000 0000
- //(ushort)(0b_1011_0000_0000_0000 | SectionLength)
- writer.Skip(2, out int SectionLengthPosition);
- writer.WriteUInt16(TransportStreamId);
- //Reserved2 VersionNumber CurrentNextIndicator
- //11 00000 1
- var a = 0xC0 & (Reserved2 << 6);
- var b = 0x3E & (VersionNumber << 3);
- var c = (byte)(a | b | CurrentNextIndicator);
- writer.WriteByte(c);
- writer.WriteByte(SectionNumber);
- writer.WriteByte(LastSectionNumber);
- //if (Programs != null)
- //{
- // foreach (var program in Programs)
- // {
- // program.ToBuffer(ref writer);
- // }
- //}
- const int crcLength= 4;
- writer.WriteUInt16Return((ushort)(0b_1011_0000_0000_0000 | (ushort)(writer.GetCurrentPosition() - SectionLengthPosition - 2)+ crcLength), SectionLengthPosition);
- //打包ts流时PAT和PMT表是没有adaptation field的,不够的长度直接补0xff即可。
- //ts header(4B) + adaptation field length(1)
- writer.WriteCRC32(5);
- var size = TSConstants.FiexdPackageLength - writer.GetCurrentPosition();
- writer.WriteArray(Enumerable.Range(0, size).Select(s => (byte)0xFF).ToArray());
+ writer.WriteByte(DescriptorTag);
+ writer.Skip(1,out var position);
+ writer.WriteByte(ServiceType);
+ writer.Skip(1, out var serviceProviderLengthPosition);
+ writer.WriteString(ServiceProvider);
+ writer.WriteByteReturn((byte)(writer.GetCurrentPosition() - serviceProviderLengthPosition), serviceProviderLengthPosition);
+ writer.Skip(1, out int SeviceNameLengthPosition);
+ writer.WriteString(ServiceName);
+ writer.WriteByteReturn((byte)(writer.GetCurrentPosition() - SeviceNameLengthPosition), SeviceNameLengthPosition);
+ writer.WriteByteReturn((byte)(writer.GetCurrentPosition() - position), position);
}
}
}