FLV: Disconnect stream when continuous duplicated data is detected

This commit is contained in:
genteure 2022-07-24 21:44:58 +08:00
parent fae7000d05
commit f9f0dec794
6 changed files with 39 additions and 9 deletions

View File

@ -187,9 +187,9 @@ namespace BililiveRecorder.Core.Recording
}
this.ioDiskStopwatch.Reset();
if (this.context.Actions.Any(x => x is PipelineDisconnectAction))
if (this.context.Actions.FirstOrDefault(x => x is PipelineDisconnectAction) is PipelineDisconnectAction disconnectAction)
{
this.logger.Information("根据修复逻辑的要求结束录制");
this.logger.Information("修复系统断开录制:{Reason}", disconnectAction.Reason);
break;
}
}

View File

@ -2,8 +2,13 @@ namespace BililiveRecorder.Flv.Pipeline.Actions
{
public class PipelineDisconnectAction : PipelineAction
{
public static readonly PipelineDisconnectAction Instance = new PipelineDisconnectAction();
public string Reason { get; set; } = string.Empty;
public override PipelineAction Clone() => Instance;
public PipelineDisconnectAction(string reason)
{
this.Reason = reason;
}
public override PipelineAction Clone() => new PipelineDisconnectAction(reason: this.Reason);
}
}

View File

@ -45,7 +45,7 @@ namespace BililiveRecorder.Flv.Pipeline.Rules
if (shouldReportError)
{
context.AddComment(comment1);
yield return PipelineDisconnectAction.Instance;
yield return new PipelineDisconnectAction("直播音频数据中间出现音频头");
yield return PipelineNewFileAction.Instance;
yield return null;
yield break;

View File

@ -19,6 +19,7 @@ namespace BililiveRecorder.Flv.Pipeline.Rules
{
private const int MAX_HISTORY = 16;
private const string QUEUE_KEY = "DeDuplicationQueue";
private const string DUPLICATED_COUNT_KEY = "DuplicatedFlvDataCount";
private static readonly FarmHash64 farmHash64 = new();
private static readonly ProcessingComment comment = new ProcessingComment(CommentType.RepeatingData, true, "重复数据");
@ -75,6 +76,27 @@ namespace BililiveRecorder.Flv.Pipeline.Rules
{
// 重复数据
context.AddComment(comment);
// 判断连续收到的重复数据数量
if (context.SessionItems.ContainsKey(DUPLICATED_COUNT_KEY) && context.SessionItems[DUPLICATED_COUNT_KEY] is int count)
{
count += 1;
}
else
{
count = 1;
}
const int DisconnectOnDuplicatedDataCount = 10;
if (count > DisconnectOnDuplicatedDataCount)
{
yield return new PipelineDisconnectAction($"连续收到了 {DisconnectOnDuplicatedDataCount} 段重复数据");
context.SessionItems.Remove(DUPLICATED_COUNT_KEY);
}
else
{
context.SessionItems[DUPLICATED_COUNT_KEY] = count;
}
}
else
{
@ -84,11 +106,14 @@ namespace BililiveRecorder.Flv.Pipeline.Rules
while (hashHistory.Count > MAX_HISTORY)
hashHistory.Dequeue();
context.SessionItems.Remove(DUPLICATED_COUNT_KEY);
yield return action;
}
}
else
{
yield return action;
}
}
}
}

View File

@ -45,7 +45,7 @@ namespace BililiveRecorder.Flv.Pipeline.Rules
if (data.Tags.Where(x => x.Type == TagType.Audio).Any2(ref IsNextTimestampSmaller.Instance) || data.Tags.Where(x => x.Type == TagType.Video).Any2(ref IsNextTimestampSmaller.Instance))
{
// 音频或视频自身就有问题,没救了
yield return PipelineDisconnectAction.Instance;
yield return new PipelineDisconnectAction("GOP 内音频或视频时间戳不连续");
context.AddComment(COMMENT_JumpedWithinGOP);
yield break;
}
@ -157,7 +157,7 @@ namespace BililiveRecorder.Flv.Pipeline.Rules
invalidOffset:
context.AddComment(COMMENT_CantSolve);
yield return PipelineDisconnectAction.Instance;
yield return new PipelineDisconnectAction("出现无法计算的音视频时间戳错位");
yield break;
}
}

View File

@ -653,8 +653,8 @@ namespace BililiveRecorder.Flv.Pipeline.Actions
}
public class PipelineDisconnectAction : BililiveRecorder.Flv.Pipeline.Actions.PipelineAction
{
public static readonly BililiveRecorder.Flv.Pipeline.Actions.PipelineDisconnectAction Instance;
public PipelineDisconnectAction() { }
public PipelineDisconnectAction(string reason) { }
public string Reason { get; set; }
public override BililiveRecorder.Flv.Pipeline.Actions.PipelineAction Clone() { }
}
public class PipelineEndAction : BililiveRecorder.Flv.Pipeline.Actions.PipelineAction