소스 검색

优化一下hls测试,还需要重构

tags/v1.1.0
waterliu99 4 년 전
부모
커밋
0aa2cc52e4
2개의 변경된 파일118개의 추가작업 그리고 32개의 파일을 삭제
  1. +25
    -0
      src/JT1078.Hls.Test/M3U8Config.cs
  2. +93
    -32
      src/JT1078.Hls.Test/TS_Package_Test.cs

+ 25
- 0
src/JT1078.Hls.Test/M3U8Config.cs 파일 보기

@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace JT1078.Hls.Test
{
/// <summary>
/// m3u8配置文件
/// </summary>
public class M3U8Config
{
/// <summary>
/// m3u8文件中包含的ts文件数
/// </summary>
public int TsFileCount { get; set; } = 10;
/// <summary>
/// 每个ts文件的最大时长
/// </summary>
public int TsFileMaxSecond { get; set; } = 10;
/// <summary>
/// m3u8文件中第一个ts文件序号
/// </summary>
public int FirstTsSerialNo { get; set; } = 0;
}
}

+ 93
- 32
src/JT1078.Hls.Test/TS_Package_Test.cs 파일 보기

@@ -4,6 +4,7 @@ using JT1078.Hls.MessagePack;
using JT1078.Protocol;
using JT1078.Protocol.Extensions;
using System;
using System.Buffers;
using System.Buffers.Binary;
using System.Collections;
using System.Collections.Generic;
@@ -19,6 +20,7 @@ namespace JT1078.Hls.Test
/// </summary>
public class TS_Package_Test
{

[Fact]
public void ToBufferTest1()
{
@@ -174,10 +176,9 @@ namespace JT1078.Hls.Test
{
try
{
int file_count = 10;
int file_max_second = 10;
int first_serialno = 0;
double file_real_second = 10;
ArrayPool<byte> arrayPool = ArrayPool<byte>.Create();
M3U8Config m3U8Config = new M3U8Config();
double file_real_second = m3U8Config.TsFileMaxSecond;

var lines = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "JT1078_3.txt"));
bool isNeedFirstHeadler = true;
@@ -185,11 +186,13 @@ namespace JT1078.Hls.Test
ulong init_seconds = 0;
int duration = 0;
int temp_seconds = 0;
int accu_seconds = 0;

var m3u8Filepath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "index.m3u8");
AppendM3U8Start(m3u8Filepath, m3U8Config.TsFileMaxSecond, m3U8Config.FirstTsSerialNo);

var fileData= arrayPool.Rent(18888888);

var m3u8Filepath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", "JT1078_HLS.m3u8");
AppendM3U8Start(m3u8Filepath, file_max_second, first_serialno);
byte[] fileData = new byte[1888888888];
int fileIndex = 0;
foreach (var line in lines)
{
@@ -199,21 +202,25 @@ namespace JT1078.Hls.Test
JT1078Package fullpackage = JT1078Serializer.Merge(package);
if (fullpackage != null)
{
if (temp_seconds / 1000>= file_max_second) {
file_real_second = temp_seconds / 1000.0;//秒
//生成一个文件
var file_name = $"JT1078_{first_serialno}.ts";
var ts_filepath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", file_name);
CreateTsFile(ts_filepath, fileData);
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(AppDomain.CurrentDomain.BaseDirectory, "H264", ts_name);
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(AppDomain.CurrentDomain.BaseDirectory, "H264",$"{media_sequence_no}.ts");
//更新m3u8文件
AppendTSFile(m3u8Filepath, file_real_second, file_name);
//删除最早一个文件
var del_file_name = $"JT1078_{first_serialno- file_count}.ts";
var del_ts_filepath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "H264", del_file_name);
DeleteTsFile(del_ts_filepath);
fileData = new byte[1888888888];
temp_seconds = 0;
first_serialno = first_serialno + 1;
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)
@@ -223,7 +230,7 @@ namespace JT1078.Hls.Test
else {
duration =(int)( fullpackage.Timestamp - init_seconds);
init_seconds = fullpackage.Timestamp;
temp_seconds = Convert.ToInt32(temp_seconds) + duration;
accu_seconds = Convert.ToInt32(accu_seconds) + duration;
}

if (isNeedFirstHeadler)
@@ -260,21 +267,75 @@ namespace JT1078.Hls.Test
}
}

private void DeleteTsFile(string tsFilepath) {
if (File.Exists(tsFilepath)) File.Delete(tsFilepath);
}
private void CreateTsFile(string tsFilepath, byte[] data) {
using (var fileStream = new FileStream(tsFilepath, FileMode.OpenOrCreate, FileAccess.Write))
private void CreateTsFile(string ts_filepath, byte[] data) {
using (var fileStream = new FileStream(ts_filepath, FileMode.OpenOrCreate, FileAccess.Write))
{
fileStream.Write(data);
}
}

private void AppendTSFile(string filepath,double tsRealSecond, string tsName) {
/// <summary>
///
/// </summary>
/// <param name="filepath"></param>
/// <param name="tsRealSecond"></param>
/// <param name="count"></param>
/// <param name="tsName"></param>
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);
}
}
}
AppendM3u8(m3u8_filepath, tsRealSecond, ts_name, sb, false);
}
else {
AppendM3u8(m3u8_filepath, tsRealSecond, ts_name, sb);
}
}
/// <summary>
/// m3u8追加ts文件
/// </summary>
/// <param name="filepath"></param>
/// <param name="tsRealSecond"></param>
/// <param name="tsName"></param>
/// <param name="sb"></param>
private void AppendM3u8(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(filepath))
using (StreamWriter sw = new StreamWriter(m3u8_filepath, isAppend))
{
sw.WriteLine(sb);
}
@@ -289,7 +350,7 @@ namespace JT1078.Hls.Test

sb.AppendLine($"#EXT-X-TARGETDURATION:{fileMaxSecond}");//每个分片TS的最大的时长
sb.AppendLine($"#EXT-X-MEDIA-SEQUENCE:{firstTSSerialno}");//第一个TS分片的序列号
using (StreamWriter sw = new StreamWriter(filepath))
using (StreamWriter sw = new StreamWriter(filepath,true))
{
sw.WriteLine(sb);
}
@@ -302,7 +363,7 @@ namespace JT1078.Hls.Test
StringBuilder sb = new StringBuilder();
sb.AppendLine("#EXT-X-ENDLIST"); //m3u8文件结束符 表示视频已经结束 有这个标志同时也说明当前流是一个非直播流
//#EXT-X-PLAYLIST-TYPE:VOD/Live //VOD表示当前视频流不是一个直播流,而是点播流(也就是视频的全部ts文件已经生成)
using (StreamWriter sw = new StreamWriter(filepath))
using (StreamWriter sw = new StreamWriter(filepath,true))
{
sw.WriteLine(sb);
}


불러오는 중...
취소
저장