diff --git a/src/JT1078.Hls.Test/JT1078.Hls.Test.csproj b/src/JT1078.Hls.Test/JT1078.Hls.Test.csproj
index 47b3e2b..55d92a8 100644
--- a/src/JT1078.Hls.Test/JT1078.Hls.Test.csproj
+++ b/src/JT1078.Hls.Test/JT1078.Hls.Test.csproj
@@ -6,11 +6,16 @@
false
+
+
+
+
+
diff --git a/src/JT1078.Hls.Test/M3U8Config.cs b/src/JT1078.Hls.Test/M3U8Config.cs
deleted file mode 100644
index e698afb..0000000
--- a/src/JT1078.Hls.Test/M3U8Config.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace JT1078.Hls.Test
-{
- ///
- /// m3u8配置文件
- ///
- public class M3U8Config
- {
- ///
- /// m3u8文件中包含的ts文件数
- ///
- public int TsFileCount { get; set; } = 10;
- ///
- /// 每个ts文件的最大时长
- ///
- public int TsFileMaxSecond { get; set; } = 10;
- ///
- /// m3u8文件中第一个ts文件序号
- ///
- public int FirstTsSerialNo { get; set; } = 0;
- }
-}
diff --git a/src/JT1078.Hls.Test/M3U8_Test.cs b/src/JT1078.Hls.Test/M3U8_Test.cs
new file mode 100644
index 0000000..ddb0825
--- /dev/null
+++ b/src/JT1078.Hls.Test/M3U8_Test.cs
@@ -0,0 +1,46 @@
+using JT1078.Protocol;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using Xunit;
+using JT1078.Protocol.Extensions;
+
+namespace JT1078.Hls.Test
+{
+ public class M3U8_Test
+ {
+ ///
+ /// 生成m3u8索引文件
+ ///
+ [Fact]
+ public void Test4()
+ {
+ try
+ {
+ var hls_file_directory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "terminalno");
+ if (!File.Exists(hls_file_directory)) Directory.CreateDirectory(hls_file_directory);
+ var m3u8_filepath = Path.Combine(hls_file_directory, "live.m3u8");
+
+ TSEncoder tSEncoder = new TSEncoder(new M3U8FileManage (new Options.M3U8Option { HlsFileDirectory = hls_file_directory, M3U8Filepath = m3u8_filepath }) );
+ var lines = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "JT1078_3.txt"));
+ 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)
+ {
+ tSEncoder.CreateM3U8File(fullpackage);
+ }
+ }
+ tSEncoder.AppendM3U8End();
+ }
+ catch (Exception ex)
+ {
+ Assert.Throws(() => { });
+ }
+ }
+ }
+}
diff --git a/src/JT1078.Hls.Test/TS_Package_Test.cs b/src/JT1078.Hls.Test/TS_Package_Test.cs
index 0b135ea..f1a45a0 100644
--- a/src/JT1078.Hls.Test/TS_Package_Test.cs
+++ b/src/JT1078.Hls.Test/TS_Package_Test.cs
@@ -81,7 +81,7 @@ namespace JT1078.Hls.Test
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();
+ TSEncoder tSEncoder = new TSEncoder(new M3U8FileManage(new Options.M3U8Option { }));
foreach (var line in lines)
{
var data = line.Split(',');
@@ -128,7 +128,7 @@ namespace JT1078.Hls.Test
var lines = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "JT1078_3.txt"));
fileStream = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write);
bool isNeedFirstHeadler = true;
- TSEncoder tSEncoder = new TSEncoder();
+ TSEncoder tSEncoder = new TSEncoder(new M3U8FileManage(new Options.M3U8Option { }));
foreach (var line in lines)
{
var data = line.Split(',');
@@ -168,209 +168,6 @@ namespace JT1078.Hls.Test
fileStream?.Dispose();
}
}
- ///
- /// 生成m3u8索引文件
- ///
- [Fact]
- public void Test4()
- {
- try
- {
- ArrayPool arrayPool = ArrayPool.Create();
- M3U8Config m3U8Config = new M3U8Config();
- Ts_File_Manage ts_File_Manage = new Ts_File_Manage();
- double file_real_second = m3U8Config.TsFileMaxSecond;
-
- var lines = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "JT1078_3.txt"));
- bool isNeedFirstHeadler = true;
- TSEncoder tSEncoder = new TSEncoder();
-
- ulong init_seconds = 0;
- int duration = 0;
- int accu_seconds = 0;
-
- var hls_file_direcotry = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264");
- var m3u8Filepath = Path.Combine(hls_file_direcotry, "index.m3u8");
- AppendM3U8Start(m3u8Filepath, m3U8Config.TsFileMaxSecond, m3U8Config.FirstTsSerialNo);
-
- var fileData= arrayPool.Rent(18888888);
-
- int fileIndex = 0;
- 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)
- {
- if (accu_seconds / 1000>= m3U8Config.TsFileMaxSecond) {
- //ecode_slice_header error 以非关键帧开始的报错信息
- file_real_second = accu_seconds / 1000.0;//秒
- //生成一个ts文件
- var ts_name = $"{m3U8Config.FirstTsSerialNo}.ts";
- var ts_filepath = Path.Combine(hls_file_direcotry, ts_name);
- ts_File_Manage.CreateTsFile(ts_filepath, fileData.AsSpan().Slice(0, fileIndex).ToArray());
- isNeedFirstHeadler = true;
- arrayPool.Return(fileData);
- fileData = arrayPool.Rent(18888888);
- fileIndex = 0;
- var media_sequence_no = m3U8Config.FirstTsSerialNo - m3U8Config.TsFileCount;
- var del_ts_name=$"{media_sequence_no}.ts";
- var del_ts_filepath = Path.Combine(hls_file_direcotry, del_ts_name);
- //更新m3u8文件
- UpdateM3U8File(m3u8Filepath, file_real_second, media_sequence_no+1, del_ts_filepath, del_ts_name,ts_name);
-
- accu_seconds = 0;
- m3U8Config.FirstTsSerialNo = m3U8Config.FirstTsSerialNo + 1;
- }
-
- if (init_seconds == 0)
- {
- init_seconds = fullpackage.Timestamp;
- }
- else {
- duration =(int)( fullpackage.Timestamp - init_seconds);
- init_seconds = fullpackage.Timestamp;
- accu_seconds = Convert.ToInt32(accu_seconds) + duration;
- }
-
- if (isNeedFirstHeadler)
- {
- var sdt = tSEncoder.CreateSDT(fullpackage);
- string sdtHEX = sdt.ToHexString();
- sdt.CopyTo(fileData, fileIndex);
- fileIndex = sdt.Length;
- var pat = tSEncoder.CreatePAT(fullpackage);
- string patHEX = pat.ToHexString();
- pat.CopyTo(fileData, fileIndex);
- fileIndex = fileIndex + pat.Length;
- var pmt = tSEncoder.CreatePMT(fullpackage);
- pmt.CopyTo(fileData, fileIndex);
- fileIndex = fileIndex + pmt.Length;
- var pes = tSEncoder.CreatePES(fullpackage, 18888);
- pes.CopyTo(fileData, fileIndex);
- fileIndex = fileIndex + pes.Length;
- isNeedFirstHeadler = false;
- }
- else
- {
- var pes = tSEncoder.CreatePES(fullpackage, 18888);
- pes.CopyTo(fileData, fileIndex);
- fileIndex = fileIndex + pes.Length;
- }
- }
- }
- AppendM3U8End(m3u8Filepath);
- }
- catch (Exception ex)
- {
- Assert.Throws(() => { });
- }
- }
-
- private void CreateTsFile(string ts_filepath, byte[] data)
- {
- using (var fileStream = new FileStream(ts_filepath, FileMode.OpenOrCreate, FileAccess.Write))
- {
- fileStream.Write(data);
- }
- }
-
-
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- private void UpdateM3U8File(string m3u8_filepath,double tsRealSecond,int media_sequence_no, string del_ts_filepath,string del_ts_name, string ts_name) {
- StringBuilder sb = new StringBuilder();
- if (File.Exists(del_ts_filepath))
- {
- //删除最早一个ts文件
- File.Delete(del_ts_filepath);
- bool startAppendFileContent = true;
- bool isFirstEXTINF = true;
- using (StreamReader sr = new StreamReader(m3u8_filepath))
- {
- while (!sr.EndOfStream)
- {
- var text = sr.ReadLine();
- if (text.Length == 0) continue;
- if (text.StartsWith("#EXT-X-MEDIA-SEQUENCE"))
- {
- string media_sequence = $"#EXT-X-MEDIA-SEQUENCE:{media_sequence_no}";
- sb.AppendLine(media_sequence);
- continue;
- }
- if (text.StartsWith("#EXTINF") && isFirstEXTINF)
- {
- startAppendFileContent = false;
- continue;
- }
- if (text.StartsWith(del_ts_name) && isFirstEXTINF)
- {
- isFirstEXTINF = false;
- startAppendFileContent = true;
- continue;
- }
- if (startAppendFileContent)
- {
- sb.AppendLine(text);
- }
- }
- }
- AppendTsToM3u8(m3u8_filepath, tsRealSecond, ts_name, sb, false);
- }
- else {
- AppendTsToM3u8(m3u8_filepath, tsRealSecond, ts_name, sb);
- }
- }
- ///
- /// m3u8追加ts文件
- ///
- ///
- ///
- ///
- ///
- private void AppendTsToM3u8(string m3u8_filepath, double tsRealSecond, string tsName, StringBuilder sb,bool isAppend=true) {
- sb.AppendLine($"#EXTINF:{tsRealSecond},");//extra info,分片TS的信息,如时长,带宽等
- sb.AppendLine($"{tsName}");//文件名
- using (StreamWriter sw = new StreamWriter(m3u8_filepath, isAppend))
- {
- sw.WriteLine(sb);
- }
- }
-
- private void AppendM3U8Start(string filepath,int fileMaxSecond,int firstTSSerialno) {
- if(File.Exists(filepath)) File.Delete(filepath);
- StringBuilder sb = new StringBuilder();
- sb.AppendLine("#EXTM3U");//开始
- sb.AppendLine("#EXT-X-VERSION:3");//版本号
- sb.AppendLine("#EXT-X-ALLOW-CACHE:NO");//是否允许cache
-
- sb.AppendLine($"#EXT-X-TARGETDURATION:{fileMaxSecond}");//每个分片TS的最大的时长
- sb.AppendLine($"#EXT-X-MEDIA-SEQUENCE:{firstTSSerialno}");//第一个TS分片的序列号
- using (StreamWriter sw = new StreamWriter(filepath,true))
- {
- sw.WriteLine(sb);
- }
- }
- ///
- /// 添加结束标识
- ///
- ///
- private void AppendM3U8End(string filepath) {
- StringBuilder sb = new StringBuilder();
- sb.AppendLine("#EXT-X-ENDLIST"); //m3u8文件结束符 表示视频已经结束 有这个标志同时也说明当前流是一个非直播流
- //#EXT-X-PLAYLIST-TYPE:VOD/Live //VOD表示当前视频流不是一个直播流,而是点播流(也就是视频的全部ts文件已经生成)
- using (StreamWriter sw = new StreamWriter(filepath,true))
- {
- sw.WriteLine(sb);
- }
- }
///
///
diff --git a/src/JT1078.Hls.Test/Ts_File_Manage.cs b/src/JT1078.Hls.Test/Ts_File_Manage.cs
deleted file mode 100644
index dc16f6e..0000000
--- a/src/JT1078.Hls.Test/Ts_File_Manage.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-
-namespace JT1078.Hls.Test
-{
- ///
- /// ts文件管理
- ///
- public class Ts_File_Manage
- {
- ///
- /// 创建ts文件
- ///
- /// ts文件路径
- /// 文件内容
- public void CreateTsFile(string ts_filepath, byte[] data)
- {
- DeleteTsFile(ts_filepath);
- using (var fileStream = new FileStream(ts_filepath, FileMode.CreateNew, FileAccess.Write))
- {
- fileStream.Write(data);
- }
- }
-
- ///
- /// 删除ts文件
- ///
- /// ts文件路径
- public void DeleteTsFile(string ts_filepath)
- {
- if (File.Exists(ts_filepath)) File.Delete(ts_filepath);
- }
- ///
- /// ts文件是否存在
- ///
- ///
- ///
- public bool ExistTsFile(string ts_filepath) {
- return File.Exists(ts_filepath);
- }
- }
-}
diff --git a/src/JT1078.Hls/M3U8FileManage.cs b/src/JT1078.Hls/M3U8FileManage.cs
new file mode 100644
index 0000000..8070ead
--- /dev/null
+++ b/src/JT1078.Hls/M3U8FileManage.cs
@@ -0,0 +1,159 @@
+using System;
+using System.Buffers;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using JT1078.Hls.Options;
+using JT1078.Protocol;
+using JT1078.Protocol.Extensions;
+
+namespace JT1078.Hls
+{
+ ///
+ /// m3u8文件管理
+ ///
+ public class M3U8FileManage
+ {
+ public readonly M3U8Option m3U8Option;
+
+ public M3U8FileManage(M3U8Option m3U8Option)
+ {
+ this.m3U8Option = m3U8Option;
+ AppendM3U8Start(m3U8Option.TsFileMaxSecond, m3U8Option.TsFileCount);
+ }
+
+ 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 AppendM3U8Start(int fileMaxSecond, int firstTSSerialno)
+ {
+ if (File.Exists(m3U8Option.M3U8Filepath)) File.Delete(m3U8Option.M3U8Filepath);
+ StringBuilder sb = new StringBuilder();
+ sb.AppendLine("#EXTM3U");//开始
+ sb.AppendLine("#EXT-X-VERSION:3");//版本号
+ sb.AppendLine("#EXT-X-ALLOW-CACHE:NO");//是否允许cache
+
+ sb.AppendLine($"#EXT-X-TARGETDURATION:{fileMaxSecond}");//每个分片TS的最大的时长
+ sb.AppendLine($"#EXT-X-MEDIA-SEQUENCE:{firstTSSerialno}");//第一个TS分片的序列号
+ using (StreamWriter sw = new StreamWriter(m3U8Option.M3U8Filepath, true))
+ {
+ sw.WriteLine(sb);
+ }
+ }
+
+ ///
+ /// 添加结束标识
+ ///
+ ///
+ public void AppendM3U8End()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.AppendLine("#EXT-X-ENDLIST"); //m3u8文件结束符 表示视频已经结束 有这个标志同时也说明当前流是一个非直播流
+ //#EXT-X-PLAYLIST-TYPE:VOD/Live //VOD表示当前视频流不是一个直播流,而是点播流(也就是视频的全部ts文件已经生成)
+ using (StreamWriter sw = new StreamWriter(m3U8Option.M3U8Filepath, true))
+ {
+ sw.WriteLine(sb);
+ }
+ }
+
+ ///
+ /// m3u8追加ts文件
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void AppendTsToM3u8(double tsRealSecond, string tsName, StringBuilder sb, bool isAppend = true)
+ {
+ sb.AppendLine($"#EXTINF:{tsRealSecond},");//extra info,分片TS的信息,如时长,带宽等
+ sb.AppendLine($"{tsName}");//文件名
+ using (StreamWriter sw = new StreamWriter(m3U8Option.M3U8Filepath, isAppend))
+ {
+ sw.WriteLine(sb);
+ }
+ }
+
+ ///
+ /// 更新m3u8文件
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void UpdateM3U8File(double tsRealSecond, int media_sequence_no, string del_ts_name, string ts_name)
+ {
+ StringBuilder sb = new StringBuilder();
+ var del_ts_filepath = Path.Combine(m3U8Option.HlsFileDirectory, del_ts_name);
+ if (File.Exists(del_ts_filepath))
+ {
+ //删除最早一个ts文件
+ File.Delete(del_ts_filepath);
+ bool startAppendFileContent = true;
+ bool isFirstEXTINF = true;
+ using (StreamReader sr = new StreamReader(m3U8Option.M3U8Filepath))
+ {
+ while (!sr.EndOfStream)
+ {
+ var text = sr.ReadLine();
+ if (text.Length == 0) continue;
+ if (text.StartsWith("#EXT-X-MEDIA-SEQUENCE"))
+ {
+ string media_sequence = $"#EXT-X-MEDIA-SEQUENCE:{media_sequence_no}";
+ sb.AppendLine(media_sequence);
+ continue;
+ }
+ if (text.StartsWith("#EXTINF") && isFirstEXTINF)
+ {
+ startAppendFileContent = false;
+ continue;
+ }
+ if (text.StartsWith(del_ts_name) && isFirstEXTINF)
+ {
+ isFirstEXTINF = false;
+ startAppendFileContent = true;
+ continue;
+ }
+ if (startAppendFileContent)
+ {
+ sb.AppendLine(text);
+ }
+ }
+ }
+ AppendTsToM3u8( tsRealSecond, ts_name, sb, false);
+ }
+ else
+ {
+ AppendTsToM3u8(tsRealSecond, ts_name, sb);
+ }
+ }
+
+ ///
+ /// 创建ts文件
+ ///
+ /// ts文件路径
+ /// 文件内容
+ public void CreateTsFile(string ts_filepath, byte[] data)
+ {
+ File.Delete(ts_filepath);
+ using (var fileStream = new FileStream(ts_filepath, FileMode.CreateNew, FileAccess.Write))
+ {
+ fileStream.Write(data,0,data.Length);
+ }
+ }
+ }
+}
diff --git a/src/JT1078.Hls/Options/M3U8Option.cs b/src/JT1078.Hls/Options/M3U8Option.cs
new file mode 100644
index 0000000..b35bb77
--- /dev/null
+++ b/src/JT1078.Hls/Options/M3U8Option.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace JT1078.Hls.Options
+{
+ ///
+ /// m3u8配置文件
+ ///
+ public class M3U8Option
+ {
+ ///
+ /// m3u8文件中默认包含的ts文件数
+ ///
+ public int TsFileCapacity { get; set; } = 10;
+ ///
+ /// 每个ts文件的最大时长
+ ///
+ public int TsFileMaxSecond { get; set; } = 10;
+ ///
+ /// 生成的ts的文件数
+ ///
+ public int TsFileCount { get; set; } = 0;
+ ///
+ /// 1078包的时间戳 毫秒
+ ///
+ public ulong TimestampMilliSecond { get; set; } = 0;
+ ///
+ /// 累计时长 如果大于文件时长就存储一个ts文件
+ ///
+ public double AccumulateSeconds { get; set; } = 0;
+ ///
+ /// 是否需要头部,每个ts文件都需要头部,重置为true
+ ///
+ public bool IsNeedFirstHeadler { get; set; } = true;
+ ///
+ /// m3u8文件
+ ///
+ public string M3U8Filepath { get; set; }
+ ///
+ /// hls文件路径
+ ///
+ public string HlsFileDirectory { get; set; }
+ }
+}
diff --git a/src/JT1078.Hls/TSEncoder.cs b/src/JT1078.Hls/TSEncoder.cs
index 4fcdc7c..2b07c7f 100644
--- a/src/JT1078.Hls/TSEncoder.cs
+++ b/src/JT1078.Hls/TSEncoder.cs
@@ -12,6 +12,8 @@ using System.Collections.Concurrent;
using System.Security.Cryptography;
using JT1078.Hls.Descriptors;
using JT1078.Protocol.Extensions;
+using JT1078.Hls.Options;
+using System.Buffers;
[assembly: InternalsVisibleTo("JT1078.Hls.Test")]
@@ -28,12 +30,82 @@ namespace JT1078.Hls
private const int FiexdTSLength = 188;
private const string ServiceProvider = "JTT1078";
private const string ServiceName = "Koike&TK";
- private const int H264DefaultHZ = 90;
- public TSEncoder()
+ private const int H264DefaultHZ = 90;
+
+
+ ArrayPool arrayPool = ArrayPool.Create();
+ byte[] fileData;
+ int fileIndex = 0;
+ private M3U8FileManage m3U8FileManage;
+ public TSEncoder(M3U8FileManage m3U8FileManage)
{
VideoCounter = new Dictionary(StringComparer.OrdinalIgnoreCase);
+ this.m3U8FileManage = m3U8FileManage;
+ fileData = arrayPool.Rent(2500000);
}
private Dictionary VideoCounter;
+ ///
+ /// 创建m3u8文件 和 ts文件
+ ///
+ ///
+ public void CreateM3U8File(JT1078Package jt1078Package) {
+ CombinedTSData(jt1078Package);
+ if (m3U8FileManage.m3U8Option.AccumulateSeconds >= m3U8FileManage.m3U8Option.TsFileMaxSecond) {
+ m3U8FileManage.CreateM3U8File(jt1078Package, fileData.AsSpan().Slice(0,fileIndex).ToArray());
+ arrayPool.Return(fileData);
+ fileData = arrayPool.Rent(2500000);
+ fileIndex = 0;
+ }
+ }
+ ///
+ /// m3u8文件 追加结束标识
+ ///
+ public void AppendM3U8End() {
+ m3U8FileManage.AppendM3U8End();
+ }
+ ///
+ /// 按 设定的时间(默认为10秒)切分ts文件
+ ///
+ ///
+ private void CombinedTSData(JT1078Package jt1078Package) {
+ if (m3U8FileManage.m3U8Option.TimestampMilliSecond == 0)
+ {
+ m3U8FileManage.m3U8Option.TimestampMilliSecond = jt1078Package.Timestamp;
+ }
+ else
+ {
+ int duration = (int)(jt1078Package.Timestamp - m3U8FileManage.m3U8Option.TimestampMilliSecond);
+ m3U8FileManage.m3U8Option.TimestampMilliSecond = jt1078Package.Timestamp;
+ m3U8FileManage.m3U8Option.AccumulateSeconds = m3U8FileManage.m3U8Option.AccumulateSeconds + duration / 1000.0;
+ }
+ if (m3U8FileManage.m3U8Option.IsNeedFirstHeadler)
+ {
+ var sdt = CreateSDT(jt1078Package);
+ sdt.CopyTo(fileData, fileIndex);
+ fileIndex = sdt.Length;
+
+ var pat = CreatePAT(jt1078Package);
+ pat.CopyTo(fileData, fileIndex);
+ fileIndex = fileIndex + pat.Length;
+
+ var pmt = CreatePMT(jt1078Package);
+ pmt.CopyTo(fileData, fileIndex);
+ fileIndex = fileIndex + pmt.Length;
+
+ var pes = CreatePES(jt1078Package, 18888);
+ pes.CopyTo(fileData, fileIndex);
+ fileIndex = fileIndex + pes.Length;
+
+ m3U8FileManage.m3U8Option.IsNeedFirstHeadler = false;
+ }
+ else
+ {
+ var pes = CreatePES(jt1078Package, 18888);
+ pes.CopyTo(fileData, fileIndex);
+ fileIndex = fileIndex + pes.Length;
+ }
+ }
+
//private ConcurrentDictionary AudioCounter = new ConcurrentDictionary();
public byte[] CreateSDT(JT1078Package jt1078Package, int minBufferSize = 188)
{