From b65e3d5ece40cffbc8044c3127c50949999d7231 Mon Sep 17 00:00:00 2001 From: "SmallChi(Koike)" <564952747@qq.com> Date: Sat, 22 Aug 2020 17:12:02 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9m3u8=E7=9A=84=E7=AE=A1?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/JT1078.Flv.Test/JT1078.Flv.Test.csproj | 8 +- src/JT1078.Flv.Test/Libs/libfaac.dll | Bin 143360 -> 0 bytes src/JT1078.Flv/FlvEncoder.cs | 2 +- src/JT1078.Flv/JT1078.Flv.csproj | 2 +- src/JT1078.Hls/M3U8FileManage.cs | 164 ++++++++++++--------- 5 files changed, 95 insertions(+), 81 deletions(-) delete mode 100644 src/JT1078.Flv.Test/Libs/libfaac.dll diff --git a/src/JT1078.Flv.Test/JT1078.Flv.Test.csproj b/src/JT1078.Flv.Test/JT1078.Flv.Test.csproj index 938f334..dfff8a5 100644 --- a/src/JT1078.Flv.Test/JT1078.Flv.Test.csproj +++ b/src/JT1078.Flv.Test/JT1078.Flv.Test.csproj @@ -5,6 +5,7 @@ + @@ -16,10 +17,6 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - - - - @@ -51,9 +48,6 @@ Always - - Always - diff --git a/src/JT1078.Flv.Test/Libs/libfaac.dll b/src/JT1078.Flv.Test/Libs/libfaac.dll deleted file mode 100644 index a67c71f865b60e68c4fac44c46d5b7b13f6ddec8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 143360 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 D*abW` diff --git a/src/JT1078.Flv/FlvEncoder.cs b/src/JT1078.Flv/FlvEncoder.cs index ab933db..2328dfe 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.Flv/JT1078.Flv.csproj b/src/JT1078.Flv/JT1078.Flv.csproj index 2003d3f..2442c56 100644 --- a/src/JT1078.Flv/JT1078.Flv.csproj +++ b/src/JT1078.Flv/JT1078.Flv.csproj @@ -14,7 +14,7 @@ https://github.com/SmallChi/JT1078/blob/master/LICENSE https://github.com/SmallChi/JT1078/blob/master/LICENSE false - 1.0.0-preview6 + 1.0.0-preview7 false true LICENSE diff --git a/src/JT1078.Hls/M3U8FileManage.cs b/src/JT1078.Hls/M3U8FileManage.cs index 909edf3..260bb6c 100644 --- a/src/JT1078.Hls/M3U8FileManage.cs +++ b/src/JT1078.Hls/M3U8FileManage.cs @@ -22,7 +22,6 @@ namespace JT1078.Hls public readonly M3U8Option m3U8Option; ConcurrentDictionary curTsFileInfoDic = new ConcurrentDictionary();//当前文件信息 ConcurrentDictionary> tsFileInfoQueueDic = new ConcurrentDictionary>(); - ConcurrentDictionary TsFirst1078PackageDic = new ConcurrentDictionary(); public M3U8FileManage(M3U8Option m3U8Option, TSEncoder tSEncoder) { @@ -33,46 +32,51 @@ namespace JT1078.Hls /// 生成ts和m3u8文件 /// /// - public void CreateTsData(JT1078Package jt1078Package) { - string key = $"{jt1078Package.SIM}_{jt1078Package.LogicChannelNumber}"; + public void CreateTsData(JT1078Package jt1078Package) + { + string key = jt1078Package.GetKey(); string hlsFileDirectory = m3U8Option.HlsFileDirectory; string m3u8FileName = Path.Combine(hlsFileDirectory, m3U8Option.M3U8FileName); if (!File.Exists(m3u8FileName)) File.Create(m3u8FileName);//创建m3u8文件 - var buff = TSArrayPool.Rent(jt1078Package.Bodies.Length + 1024); TSMessagePackWriter tSMessagePackWriter = new TSMessagePackWriter(buff); - - var curTsFileInfo = CreateTsFileInfo(key, jt1078Package); - if (!curTsFileInfo.IsCreateTsFile) + try { - var pes = tSEncoder.CreatePES(jt1078Package); - tSMessagePackWriter.WriteArray(pes); - CreateTsFile(curTsFileInfo.FileName, tSMessagePackWriter.FlushAndGetArray()); - - curTsFileInfo.Duration = (jt1078Package.Timestamp - curTsFileInfo.TsFirst1078PackageTimeStamp) / 1000.0; - //按设定的时间(默认为10秒)切分ts文件 - if (curTsFileInfo.Duration > m3U8Option.TsFileMaxSecond) + var curTsFileInfo = CreateTsFileInfo(key); + if (!curTsFileInfo.IsCreateTsFile) + { + var pes = tSEncoder.CreatePES(jt1078Package); + tSMessagePackWriter.WriteArray(pes); + CreateTsFile(curTsFileInfo.FileName, tSMessagePackWriter.FlushAndGetArray()); + curTsFileInfo.Duration = (jt1078Package.Timestamp - curTsFileInfo.TsFirst1078PackageTimeStamp) / 1000.0; + //按设定的时间(默认为10秒)切分ts文件 + if (curTsFileInfo.Duration > m3U8Option.TsFileMaxSecond) + { + var tsFileInfoQueue = ManageTsFileInfo(key, curTsFileInfo); + CreateM3U8File(curTsFileInfo, tsFileInfoQueue); + var newTsFileInfo = new TsFileInfo { IsCreateTsFile = true, Duration = 0, TsFileSerialNo = ++curTsFileInfo.TsFileSerialNo }; + curTsFileInfoDic.TryUpdate(key, newTsFileInfo, curTsFileInfo); + } + } + else { - var tsFileInfoQueue = ManageTsFileInfo(key, curTsFileInfo); - CreateM3U8File(key, curTsFileInfo, tsFileInfoQueue); - var newTsFileInfo = new TsFileInfo { IsCreateTsFile = true, Duration = 0, TsFileSerialNo = ++curTsFileInfo.TsFileSerialNo }; - curTsFileInfoDic.TryUpdate(key, newTsFileInfo, curTsFileInfo); + curTsFileInfo.IsCreateTsFile = false; + curTsFileInfo.TsFirst1078PackageTimeStamp = jt1078Package.Timestamp; + curTsFileInfo.FileName = $"{curTsFileInfo.TsFileSerialNo}.ts"; + var sdt = tSEncoder.CreateSDT(jt1078Package); + tSMessagePackWriter.WriteArray(sdt); + var pat = tSEncoder.CreatePAT(jt1078Package); + tSMessagePackWriter.WriteArray(pat); + var pmt = tSEncoder.CreatePMT(jt1078Package); + tSMessagePackWriter.WriteArray(pmt); + var pes = tSEncoder.CreatePES(jt1078Package); + tSMessagePackWriter.WriteArray(pes); + CreateTsFile(curTsFileInfo.FileName, tSMessagePackWriter.FlushAndGetArray()); } } - else { - curTsFileInfo.IsCreateTsFile = false; - curTsFileInfo.TsFirst1078PackageTimeStamp = jt1078Package.Timestamp; - curTsFileInfo.FileName = $"{curTsFileInfo.TsFileSerialNo}.ts"; - - var sdt = tSEncoder.CreateSDT(jt1078Package); - tSMessagePackWriter.WriteArray(sdt); - var pat = tSEncoder.CreatePAT(jt1078Package); - tSMessagePackWriter.WriteArray(pat); - var pmt = tSEncoder.CreatePMT(jt1078Package); - tSMessagePackWriter.WriteArray(pmt); - var pes = tSEncoder.CreatePES(jt1078Package); - tSMessagePackWriter.WriteArray(pes); - CreateTsFile(curTsFileInfo.FileName, tSMessagePackWriter.FlushAndGetArray()); + finally + { + TSArrayPool.Return(buff); } } /// @@ -81,7 +85,8 @@ namespace JT1078.Hls /// /// /// - private Queue ManageTsFileInfo(string key, TsFileInfo curTsFileInfo) { + private Queue ManageTsFileInfo(string key, TsFileInfo curTsFileInfo) + { if (tsFileInfoQueueDic.TryGetValue(key, out var tsFileInfoQueue)) { if (tsFileInfoQueue.Count >= m3U8Option.TsFileCapacity) @@ -103,12 +108,10 @@ namespace JT1078.Hls /// /// 创建M3U8文件 /// - /// /// - private void CreateM3U8File(string key,TsFileInfo curTsFileInfo, Queue tsFileInfoQueue) + private void CreateM3U8File(TsFileInfo curTsFileInfo, Queue tsFileInfoQueue) { //ecode_slice_header error 以非关键帧开始生成的ts,通过ffplay播放会出现报错信息 - string tsFileSerialNo = string.Empty; StringBuilder sb = new StringBuilder(); sb.AppendLine("#EXTM3U");//开始 sb.AppendLine("#EXT-X-VERSION:3");//版本号 @@ -123,9 +126,9 @@ namespace JT1078.Hls sb.AppendLine(tsFileInfo.FileName); } using (FileStream fs = new FileStream(m3U8Option.M3U8FileName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) - using (StreamWriter sw = new StreamWriter(fs)) { - sw.Write(sb.ToString()); + var buffer = Encoding.UTF8.GetBytes(sb.ToString()); + fs.Write(buffer,0, buffer.Length); } } @@ -133,9 +136,9 @@ namespace JT1078.Hls /// 创建TS文件信息 /// /// - /// /// - private TsFileInfo CreateTsFileInfo(string key,JT1078Package jt1078Package) { + private TsFileInfo CreateTsFileInfo(string key) + { if (!curTsFileInfoDic.TryGetValue(key, out var curTsFileInfo)) { curTsFileInfo = new TsFileInfo(); @@ -157,41 +160,58 @@ namespace JT1078.Hls } } + ///// + ///// 添加结束标识 + ///// 直播流用不到 + ///// + ///// + ////public void AppendM3U8End() + ////{ + //// StringBuilder sb = new StringBuilder(); + //// sb.AppendLine("#EXT-X-ENDLIST"); //m3u8文件结束符 表示视频已经结束 有这个标志同时也说明当前流是一个非直播流 + //// //#EXT-X-PLAYLIST-TYPE:VOD/Live //VOD表示当前视频流不是一个直播流,而是点播流(也就是视频的全部ts文件已经生成) + ////} + /// - /// 添加结束标识 - /// 直播流用不到 - /// - /// - //public void AppendM3U8End() - //{ - // StringBuilder sb = new StringBuilder(); - // sb.AppendLine("#EXT-X-ENDLIST"); //m3u8文件结束符 表示视频已经结束 有这个标志同时也说明当前流是一个非直播流 - // //#EXT-X-PLAYLIST-TYPE:VOD/Live //VOD表示当前视频流不是一个直播流,而是点播流(也就是视频的全部ts文件已经生成) - //} - } - /// - /// TS文件信息 - /// - public class TsFileInfo { - /// - /// ts文件名 - /// - public string FileName { get; set; } = "0.ts"; - /// - /// 持续时间 - /// - public double Duration { get; set; } = 0; - /// - /// 当前ts文件序号 - /// - public int TsFileSerialNo { get; set; } = 0; - /// - /// 是否创建ts文件 + /// 停止观看直播时清零数据 /// - public bool IsCreateTsFile { get; set; } = true; + /// + /// + public void Clear(string sim,int channelNo) + { + var key = $"{sim}_{channelNo}"; + curTsFileInfoDic.TryRemove(key, out _); + tsFileInfoQueueDic.TryRemove(key, out _); + var directory = Path.Combine(m3U8Option.HlsFileDirectory, key); + if (Directory.Exists(directory)) Directory.Delete(directory); + } + /// - /// ts文件第一个jt1078包的时间戳 + /// TS文件信息 /// - public ulong TsFirst1078PackageTimeStamp { get; set; } = 0; + internal class TsFileInfo + { + /// + /// ts文件名 + /// + public string FileName { get; set; } = "0.ts"; + /// + /// 持续时间 + /// + public double Duration { get; set; } = 0; + /// + /// 当前ts文件序号 + /// + public int TsFileSerialNo { get; set; } = 0; + /// + /// 是否创建ts文件 + /// + public bool IsCreateTsFile { get; set; } = true; + /// + /// ts文件第一个jt1078包的时间戳 + /// + public ulong TsFirst1078PackageTimeStamp { get; set; } = 0; + } } + }