diff --git a/src/JT1078.Flv/FlvEncoder.cs b/src/JT1078.Flv/FlvEncoder.cs
index 2328dfe..ab933db 100644
--- a/src/JT1078.Flv/FlvEncoder.cs
+++ b/src/JT1078.Flv/FlvEncoder.cs
@@ -41,7 +41,7 @@ namespace JT1078.Flv
readonly H264Decoder h264Decoder = new H264Decoder();
public FlvEncoder(int sampleRate = 8000, int channels = 1, int sampleBit = 16, bool adts = false)
{
- faacEncoder = new FaacEncoder(sampleRate, channels, sampleBit, adts);
+ //faacEncoder = new FaacEncoder(sampleRate, channels, sampleBit, adts);
}
///
diff --git a/src/JT1078.Hls.Test/M3U8_Test.cs b/src/JT1078.Hls.Test/M3U8_Test.cs
index 8d12acf..502be21 100644
--- a/src/JT1078.Hls.Test/M3U8_Test.cs
+++ b/src/JT1078.Hls.Test/M3U8_Test.cs
@@ -20,9 +20,9 @@ namespace JT1078.Hls.Test
{
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");
+ var m3u8_filename = Path.Combine(hls_file_directory, "live.m3u8");
TSEncoder tSEncoder = new TSEncoder();
- var m3u8Manage = new M3U8FileManage(new Options.M3U8Option { HlsFileDirectory = hls_file_directory, M3U8Filepath = m3u8_filepath }, tSEncoder);
+ var m3u8Manage = new M3U8FileManage(new Options.M3U8Option { HlsFileDirectory = hls_file_directory, M3U8FileName = m3u8_filename }, tSEncoder);
var lines = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "JT1078_3.txt"));
foreach (var line in lines)
@@ -34,7 +34,6 @@ namespace JT1078.Hls.Test
if (fullpackage != null)
{
m3u8Manage.CreateTsData(fullpackage);
- m3u8Manage.CreateM3U8File();
}
}
}
diff --git a/src/JT1078.Hls/M3U8FileManage.cs b/src/JT1078.Hls/M3U8FileManage.cs
index e0d3552..97e8336 100644
--- a/src/JT1078.Hls/M3U8FileManage.cs
+++ b/src/JT1078.Hls/M3U8FileManage.cs
@@ -33,25 +33,28 @@ namespace JT1078.Hls
}
public void CreateTsData(JT1078Package jt1078Package) {
+ if (!File.Exists(m3U8Option.M3U8FileName)) File.Create(m3U8Option.M3U8FileName);//创建m3u8文件
string tsFileDirectory = m3U8Option.HlsFileDirectory;
- string tsNewFileName = $"{m3U8Option.TsFileCount}.ts";
- string fileName= Path.Combine(tsFileDirectory, tsNewFileName);
- var buff = TSArrayPool.Rent(jt1078Package.Bodies.Length + 2048);
+ string tsNewFileName = $"{m3U8Option.TsFileSerialNo}.ts";
+ string tsFileName= Path.Combine(tsFileDirectory, tsNewFileName);
+ var buff = TSArrayPool.Rent(jt1078Package.Bodies.Length + 1024);
TSMessagePackWriter tSMessagePackWriter = new TSMessagePackWriter(buff);
- if (TsFirst1078PackageDic.TryGetValue(jt1078Package.SIM, out var firstTimespan))
+ if (TsFirst1078PackageDic.TryGetValue($"{jt1078Package.SIM}_{jt1078Package.LogicChannelNumber}" , out var firstTimespan))
{
- var pes = tSEncoder.CreatePES(jt1078Package, 188);
+ var pes = tSEncoder.CreatePES(jt1078Package);
tSMessagePackWriter.WriteArray(pes);
- CreateTsFile(fileName, tSMessagePackWriter.FlushAndGetArray());
+ CreateTsFile(tsFileName, tSMessagePackWriter.FlushAndGetArray());
if ((jt1078Package.Timestamp - firstTimespan) > 10 * 1000)
{
//按设定的时间(默认为10秒)切分ts文件
- TsFirst1078PackageDic.TryRemove(jt1078Package.SIM, out var _);
- tsFileInfoQueue.Enqueue(new TsFileInfo { FileName= tsNewFileName, Duration= (jt1078Package.Timestamp - firstTimespan)/1000.0 });
- m3U8Option.TsFileCount++;
+ TsFirst1078PackageDic.TryRemove($"{jt1078Package.SIM}_{jt1078Package.LogicChannelNumber}", out var _);
+ var tsFileInfo = new TsFileInfo { FileName = tsNewFileName, Duration = (jt1078Package.Timestamp - firstTimespan) / 1000.0 };
+ CreateM3U8File(tsFileInfo);
+ m3U8Option.TsFileSerialNo++;
}
}
else {
+ if (File.Exists(tsFileName)) File.Delete(tsFileName);
var sdt = tSEncoder.CreateSDT(jt1078Package);
tSMessagePackWriter.WriteArray(sdt);
var pat = tSEncoder.CreatePAT(jt1078Package);
@@ -60,68 +63,54 @@ namespace JT1078.Hls
tSMessagePackWriter.WriteArray(pmt);
var pes = tSEncoder.CreatePES(jt1078Package);
tSMessagePackWriter.WriteArray(pes);
- CreateTsFile(fileName, tSMessagePackWriter.FlushAndGetArray());
- TsFirst1078PackageDic.TryAdd(jt1078Package.SIM, jt1078Package.Timestamp);
+ CreateTsFile(tsFileName, tSMessagePackWriter.FlushAndGetArray());
+ TsFirst1078PackageDic.TryAdd($"{jt1078Package.SIM}_{jt1078Package.LogicChannelNumber}", jt1078Package.Timestamp);
}
}
- public void CreateM3U8File()
+ private void CreateM3U8File(TsFileInfo tsFileInfo)
{
//ecode_slice_header error 以非关键帧开始的报错信息
- if (tsFileInfoQueue.TryDequeue(out var tsFileInfo))
+ string tsFileSerialNo = string.Empty;
+ 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:{m3U8Option.TsFileMaxSecond}");//第一个TS分片的序列号
+ sb.AppendLine($"#EXT-X-MEDIA-SEQUENCE:{(m3U8Option.TsFileSerialNo - m3U8Option.TsFileCapacity > 0 ? (m3U8Option.TsFileSerialNo - m3U8Option.TsFileCapacity) : 0)}"); //默认第一个文件为0
+ Queue fileBody = new Queue();
+ using (FileStream fs = new FileStream(m3U8Option.M3U8FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
+ using (StreamReader sr = new StreamReader(fs))
{
- string firstTsIndex = string.Empty;
- StringBuilder sb = new StringBuilder();
- List fileHeader = new List() {
- "#EXTM3U",//开始
- "#EXT-X-VERSION:3",//版本号
- "#EXT-X-ALLOW-CACHE:NO",//是否允许cache
- $"#EXT-X-TARGETDURATION:{m3U8Option.TsFileMaxSecond}",//第一个TS分片的序列号
- $"#EXT-X-MEDIA-SEQUENCE:firstTsIndex"
- };
- Queue fileBody = new Queue();
- if (!File.Exists(m3U8Option.M3U8Filepath)) File.Create(m3U8Option.M3U8Filepath);
- using(FileStream fs=new FileStream(m3U8Option.M3U8Filepath,FileMode.Open,FileAccess.Read,FileShare.ReadWrite))
- using (StreamReader sr = new StreamReader(fs))
+ while (!sr.EndOfStream)
{
- while (!sr.EndOfStream)
- {
- var text = sr.ReadLine();
- if (text.Length == 0) continue;
- if (fileHeader.Contains(text)) continue;
- if (text.StartsWith("#EXT-X-MEDIA-SEQUENCE")) continue;
- fileBody.Enqueue(text);
- }
- if (fileBody.Count >= m3U8Option.TsFileCapacity * 2)
- {
- var deleteTsFileName_extraInfo = fileBody.Dequeue();
- var deleteTsFileName = fileBody.Dequeue();
- tsDelFileNameQueue.Enqueue(deleteTsFileName);
-
- fileBody.Enqueue($"#EXTINF:{tsFileInfo.Duration},");
- fileBody.Enqueue(tsFileInfo.FileName);
-
- firstTsIndex = fileBody.ElementAt(1).Replace(".ts", "");
- }
- else {
- fileBody.Enqueue($"#EXTINF:{tsFileInfo.Duration},");
- fileBody.Enqueue(tsFileInfo.FileName);
+ var text = sr.ReadLine();
+ if (text.Length == 0) continue;
+ if (sb.ToString().Contains(text.Split(':')[0])) continue;
+ fileBody.Enqueue(text);
+ }
+ if (fileBody.Count >= m3U8Option.TsFileCapacity * 2)
+ {
+ var deleteTsFileName_extraInfo = fileBody.Dequeue();
+ var deleteTsFileName = fileBody.Dequeue();
+ tsDelFileNameQueue.Enqueue(deleteTsFileName);
- firstTsIndex = fileBody.ElementAt(1).Replace(".ts", "");
- }
- fileHeader.ForEach((m) => {
- if (m.Contains("firstTsIndex")) m = m.Replace("firstTsIndex", firstTsIndex);
- sb.AppendLine(m);
- });
- fileBody.ToList().ForEach(m => {
- sb.AppendLine(m);
- });
+ fileBody.Enqueue($"#EXTINF:{tsFileInfo.Duration},");
+ fileBody.Enqueue(tsFileInfo.FileName);
}
- using (FileStream fs = new FileStream(m3U8Option.M3U8Filepath, FileMode.Create,FileAccess.Write, FileShare.ReadWrite))
- using (StreamWriter sw = new StreamWriter(fs))
+ else
{
- sw.Write(sb.ToString());
+ fileBody.Enqueue($"#EXTINF:{tsFileInfo.Duration},");
+ fileBody.Enqueue(tsFileInfo.FileName);
}
+ fileBody.ToList().ForEach(m => {
+ sb.AppendLine(m);
+ });
+ }
+ using (FileStream fs = new FileStream(m3U8Option.M3U8FileName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
+ using (StreamWriter sw = new StreamWriter(fs))
+ {
+ sw.Write(sb.ToString());
}
}
diff --git a/src/JT1078.Hls/Options/M3U8Option.cs b/src/JT1078.Hls/Options/M3U8Option.cs
index 131edb7..3d67e51 100644
--- a/src/JT1078.Hls/Options/M3U8Option.cs
+++ b/src/JT1078.Hls/Options/M3U8Option.cs
@@ -18,13 +18,13 @@ namespace JT1078.Hls.Options
///
public int TsFileMaxSecond { get; set; } = 10;
///
- /// ts文件个数
+ /// 当前ts文件序号
///
- public int TsFileCount { get; set; } = 0;
+ public int TsFileSerialNo { get; set; } = 0;
///
/// m3u8文件
///
- public string M3U8Filepath { get; set; }
+ public string M3U8FileName { get; set; }
///
/// hls文件路径
///
diff --git a/src/JT1078.Hls/TSEncoder.cs b/src/JT1078.Hls/TSEncoder.cs
index 8104cb0..5c73e4a 100644
--- a/src/JT1078.Hls/TSEncoder.cs
+++ b/src/JT1078.Hls/TSEncoder.cs
@@ -139,7 +139,7 @@ namespace JT1078.Hls
TSArrayPool.Return(buffer);
}
}
- public byte[] CreatePES(JT1078Package jt1078Package, int minBufferSize = 188)
+ public byte[] CreatePES(JT1078Package jt1078Package, int minBufferSize = 1024)
{
//将1078一帧的数据拆分成一小段一小段的PES包
byte[] buffer = TSArrayPool.Rent(jt1078Package.Bodies.Length + minBufferSize);