FLV: Refactor ProcessingComment

This commit is contained in:
genteure 2022-06-17 17:42:50 +08:00
parent 97154b5716
commit 46cde4896c
17 changed files with 61 additions and 50 deletions

View File

@ -16,6 +16,7 @@ using BililiveRecorder.Core;
using BililiveRecorder.Core.Config;
using BililiveRecorder.Core.Config.V3;
using BililiveRecorder.DependencyInjection;
using BililiveRecorder.Flv.Pipeline;
using BililiveRecorder.ToolBox;
using BililiveRecorder.Web;
using Microsoft.AspNetCore.Hosting;
@ -409,6 +410,7 @@ namespace BililiveRecorder.Cli
.Enrich.FromLogContext()
.Enrich.WithExceptionDetails()
.Destructure.AsScalar<IPAddress>()
.Destructure.AsScalar<ProcessingComment>()
.Destructure.ByTransforming<Flv.Xml.XmlFlvFile.XmlFlvFileMeta>(x => new
{
x.Version,

View File

@ -13,8 +13,8 @@ namespace BililiveRecorder.Core.ProcessingRules
private const int FLAG_BEFORE = 1;
private const int FLAG_AFTER = 2;
private static readonly ProcessingComment comment_before = new ProcessingComment(CommentType.Logging, "New file before data by split rule");
private static readonly ProcessingComment comment_after = new ProcessingComment(CommentType.Logging, "New file after data by split rule");
private static readonly ProcessingComment comment_before = new ProcessingComment(CommentType.Logging, false, "New file before data by split rule");
private static readonly ProcessingComment comment_after = new ProcessingComment(CommentType.Logging, false, "New file after data by split rule");
public void Run(FlvProcessingContext context, System.Action next)
{

View File

@ -4,22 +4,28 @@ namespace BililiveRecorder.Flv.Pipeline
{
public class ProcessingComment
{
public ProcessingComment(CommentType t, string c)
public ProcessingComment(CommentType type, bool actionRequired, string comment)
{
this.T = t;
this.C = c ?? throw new ArgumentNullException(nameof(c));
this.Type = type;
this.ActionRequired = actionRequired;
this.Comment = comment ?? throw new ArgumentNullException(nameof(comment));
}
/// <summary>
/// Type
/// </summary>
public CommentType T { get; }
public CommentType Type { get; }
/// <summary>
/// Action Required
/// </summary>
public bool ActionRequired { get; }
/// <summary>
/// Comment
/// </summary>
public string C { get; }
public string Comment { get; }
public override string ToString() => $"{this.T} {this.C}";
public override string ToString() => $"({this.Type},{(this.ActionRequired ? "A" : "C")}): {this.Comment}";
}
}

View File

@ -11,8 +11,8 @@ namespace BililiveRecorder.Flv.Pipeline.Rules
/// </summary>
public class HandleDelayedAudioHeaderRule : ISimpleProcessingRule
{
private static readonly ProcessingComment comment1 = new ProcessingComment(CommentType.Unrepairable, "音频数据出现在音频头之前");
private static readonly ProcessingComment comment2 = new ProcessingComment(CommentType.DecodingHeader, "检测到延后收到的音频头");
private static readonly ProcessingComment comment1 = new ProcessingComment(CommentType.Unrepairable, true, "音频数据出现在音频头之前");
private static readonly ProcessingComment comment2 = new ProcessingComment(CommentType.DecodingHeader, true, "检测到延后收到的音频头");
public void Run(FlvProcessingContext context, Action next)
{

View File

@ -9,7 +9,7 @@ namespace BililiveRecorder.Flv.Pipeline.Rules
/// </summary>
public class HandleEndTagRule : ISimpleProcessingRule
{
private static readonly ProcessingComment comment = new ProcessingComment(CommentType.Logging, "因收到 End Tag 分段");
private static readonly ProcessingComment comment = new ProcessingComment(CommentType.Logging, false, "因收到 End Tag 分段");
public void Run(FlvProcessingContext context, Action next)
{

View File

@ -15,8 +15,8 @@ namespace BililiveRecorder.Flv.Pipeline.Rules
private const string VIDEO_HEADER_KEY = "HandleNewHeaderRule_VideoHeader";
private const string AUDIO_HEADER_KEY = "HandleNewHeaderRule_AudioHeader";
private static readonly ProcessingComment MultipleHeaderComment = new ProcessingComment(CommentType.DecodingHeader, "收到了连续多个 Header新建文件");
private static readonly ProcessingComment SplitFileComment = new ProcessingComment(CommentType.DecodingHeader, "因为 Header 问题新建文件");
private static readonly ProcessingComment MultipleHeaderComment = new ProcessingComment(CommentType.DecodingHeader, true, "收到了连续多个 Header新建文件");
private static readonly ProcessingComment SplitFileComment = new ProcessingComment(CommentType.DecodingHeader, true, "因为 Header 问题新建文件");
public void Run(FlvProcessingContext context, Action next)
{

View File

@ -12,7 +12,7 @@ namespace BililiveRecorder.Flv.Pipeline.Rules
{
private const string STORE_KEY = "HandleNewScriptRule_MetaDataReceived";
private const string onMetaData = "onMetaData";
private static readonly ProcessingComment comment_onmetadata = new ProcessingComment(CommentType.OnMetaData, "收到了 onMetaData");
private static readonly ProcessingComment comment_onmetadata = new ProcessingComment(CommentType.OnMetaData, false, "收到了 onMetaData");
public void Run(FlvProcessingContext context, Action next)
{
@ -95,12 +95,12 @@ namespace BililiveRecorder.Flv.Pipeline.Rules
{
// 记录信息,不输出到文件,不对文件进行分段。
var message = $"重复收到 onMetaData, onMetaData 内容: {data?.ToJson() ?? "(null)"}";
context.AddComment(new ProcessingComment(CommentType.OnMetaData, message));
context.AddComment(new ProcessingComment(CommentType.OnMetaData, false, message));
yield return new PipelineLogMessageWithLocationAction(Serilog.Events.LogEventLevel.Warning, "重复收到 onMetaData");
yield break;
}
notOnMetaData:
context.AddComment(new ProcessingComment(CommentType.Logging, "收到了非 onMetaData 的 Script Tag: " + (data?.ToJson() ?? "(null)")));
context.AddComment(new ProcessingComment(CommentType.Logging, false, "收到了非 onMetaData 的 Script Tag: " + (data?.ToJson() ?? "(null)")));
yield break;
}
}

View File

@ -21,7 +21,7 @@ namespace BililiveRecorder.Flv.Pipeline.Rules
private const string QUEUE_KEY = "DeDuplicationQueue";
private static readonly FarmHash64 farmHash64 = new();
private static readonly ProcessingComment comment = new ProcessingComment(CommentType.RepeatingData, "重复数据");
private static readonly ProcessingComment comment = new ProcessingComment(CommentType.RepeatingData, true, "重复数据");
public void Run(FlvProcessingContext context, Action next)
{

View File

@ -42,12 +42,12 @@ namespace BililiveRecorder.Flv.Pipeline.Rules
var diff = currentTimestamp - ts.LastOriginal;
if (diff < 0)
{
context.AddComment(new ProcessingComment(CommentType.TimestampJump, $"时间戳变小, curr: {currentTimestamp}, diff: {diff}"));
context.AddComment(new ProcessingComment(CommentType.TimestampJump, true, $"时间戳变小, curr: {currentTimestamp}, diff: {diff}"));
ts.CurrentOffset = currentTimestamp - ts.NextTimestampTarget;
}
else if (diff > JUMP_THRESHOLD)
{
context.AddComment(new ProcessingComment(CommentType.TimestampJump, $"时间戳间隔过大, curr: {currentTimestamp}, diff: {diff}"));
context.AddComment(new ProcessingComment(CommentType.TimestampJump, true, $"时间戳间隔过大, curr: {currentTimestamp}, diff: {diff}"));
ts.CurrentOffset = currentTimestamp - ts.NextTimestampTarget;
}

View File

@ -12,8 +12,8 @@ namespace BililiveRecorder.Flv.Pipeline.Rules
/// </summary>
public class UpdateTimestampOffsetRule : ISimpleProcessingRule
{
private static readonly ProcessingComment COMMENT_JumpedWithinGOP = new ProcessingComment(CommentType.Unrepairable, "GOP 内音频或视频时间戳不连续");
private static readonly ProcessingComment COMMENT_CantSolve = new ProcessingComment(CommentType.Unrepairable, "出现了无法计算偏移量的音视频偏移");
private static readonly ProcessingComment COMMENT_JumpedWithinGOP = new ProcessingComment(CommentType.Unrepairable, true, "GOP 内音频或视频时间戳不连续");
private static readonly ProcessingComment COMMENT_CantSolve = new ProcessingComment(CommentType.Unrepairable, true, "出现了无法计算偏移量的音视频偏移");
public void Run(FlvProcessingContext context, Action next)
{
@ -145,7 +145,7 @@ namespace BililiveRecorder.Flv.Pipeline.Rules
validOffset:
if (offset != 0)
{
context.AddComment(new ProcessingComment(CommentType.TimestampOffset, $"音视频时间戳偏移, D: {offset}"));
context.AddComment(new ProcessingComment(CommentType.TimestampOffset, true, $"音视频时间戳偏移, D: {offset}"));
foreach (var tag in data.Tags)
if (tag.Type == TagType.Video)

View File

@ -137,25 +137,25 @@ namespace BililiveRecorder.ToolBox.Tool.Analyze
{
var (videoStats, audioStats) = statsRule.GetStats();
var countableComments = comments.Where(x => x.T != CommentType.Logging).ToArray();
var countableComments = comments.Where(x => x.Type != CommentType.Logging).ToArray();
return new AnalyzeResponse
{
InputPath = inputPath,
NeedFix = tagWriter.OutputFileCount != 1 || countableComments.Any(),
Unrepairable = countableComments.Any(x => x.T == CommentType.Unrepairable),
Unrepairable = countableComments.Any(x => x.Type == CommentType.Unrepairable),
OutputFileCount = tagWriter.OutputFileCount,
VideoStats = videoStats,
AudioStats = audioStats,
IssueTypeOther = countableComments.Count(x => x.T == CommentType.Other),
IssueTypeUnrepairable = countableComments.Count(x => x.T == CommentType.Unrepairable),
IssueTypeTimestampJump = countableComments.Count(x => x.T == CommentType.TimestampJump),
IssueTypeTimestampOffset = countableComments.Count(x => x.T == CommentType.TimestampOffset),
IssueTypeDecodingHeader = countableComments.Count(x => x.T == CommentType.DecodingHeader),
IssueTypeRepeatingData = countableComments.Count(x => x.T == CommentType.RepeatingData)
IssueTypeOther = countableComments.Count(x => x.Type == CommentType.Other),
IssueTypeUnrepairable = countableComments.Count(x => x.Type == CommentType.Unrepairable),
IssueTypeTimestampJump = countableComments.Count(x => x.Type == CommentType.TimestampJump),
IssueTypeTimestampOffset = countableComments.Count(x => x.Type == CommentType.TimestampOffset),
IssueTypeDecodingHeader = countableComments.Count(x => x.Type == CommentType.DecodingHeader),
IssueTypeRepeatingData = countableComments.Count(x => x.Type == CommentType.RepeatingData)
};
});

View File

@ -191,7 +191,7 @@ namespace BililiveRecorder.ToolBox.Tool.Fix
{
var (videoStats, audioStats) = statsRule.GetStats();
var countableComments = comments.Where(x => x.T != CommentType.Logging).ToArray();
var countableComments = comments.Where(x => x.Type != CommentType.Logging).ToArray();
return new FixResponse
{
InputPath = inputPath,
@ -199,17 +199,17 @@ namespace BililiveRecorder.ToolBox.Tool.Fix
OutputFileCount = outputPaths.Count,
NeedFix = outputPaths.Count != 1 || countableComments.Any(),
Unrepairable = countableComments.Any(x => x.T == CommentType.Unrepairable),
Unrepairable = countableComments.Any(x => x.Type == CommentType.Unrepairable),
VideoStats = videoStats,
AudioStats = audioStats,
IssueTypeOther = countableComments.Count(x => x.T == CommentType.Other),
IssueTypeUnrepairable = countableComments.Count(x => x.T == CommentType.Unrepairable),
IssueTypeTimestampJump = countableComments.Count(x => x.T == CommentType.TimestampJump),
IssueTypeTimestampOffset = countableComments.Count(x => x.T == CommentType.TimestampOffset),
IssueTypeDecodingHeader = countableComments.Count(x => x.T == CommentType.DecodingHeader),
IssueTypeRepeatingData = countableComments.Count(x => x.T == CommentType.RepeatingData)
IssueTypeOther = countableComments.Count(x => x.Type == CommentType.Other),
IssueTypeUnrepairable = countableComments.Count(x => x.Type == CommentType.Unrepairable),
IssueTypeTimestampJump = countableComments.Count(x => x.Type == CommentType.TimestampJump),
IssueTypeTimestampOffset = countableComments.Count(x => x.Type == CommentType.TimestampOffset),
IssueTypeDecodingHeader = countableComments.Count(x => x.Type == CommentType.DecodingHeader),
IssueTypeRepeatingData = countableComments.Count(x => x.Type == CommentType.RepeatingData)
};
});

View File

@ -11,6 +11,7 @@ using System.Security;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Threading;
using BililiveRecorder.Flv.Pipeline;
using BililiveRecorder.ToolBox;
using Esprima;
using Jint.Runtime;
@ -225,6 +226,7 @@ namespace BililiveRecorder.WPF
.Enrich.FromLogContext()
.Enrich.WithExceptionDetails()
.Destructure.AsScalar<IPAddress>()
.Destructure.AsScalar<ProcessingComment>()
.Destructure.ByTransforming<Flv.Xml.XmlFlvFile.XmlFlvFileMeta>(x => new
{
x.Version,

View File

@ -752,9 +752,10 @@ namespace BililiveRecorder.Flv.Pipeline
}
public class ProcessingComment
{
public ProcessingComment(BililiveRecorder.Flv.Pipeline.CommentType t, string c) { }
public string C { get; }
public BililiveRecorder.Flv.Pipeline.CommentType T { get; }
public ProcessingComment(BililiveRecorder.Flv.Pipeline.CommentType type, bool actionRequired, string comment) { }
public bool ActionRequired { get; }
public string Comment { get; }
public BililiveRecorder.Flv.Pipeline.CommentType Type { get; }
public override string ToString() { }
}
public delegate void ProcessingDelegate(BililiveRecorder.Flv.Pipeline.FlvProcessingContext context);

View File

@ -20,7 +20,7 @@ namespace BililiveRecorder.Flv.Tests.RuleTests
[ExpectationPath("Bad")]
public class IntegratedBadTests : IntegratedTestBase
{
[Theory(Skip = "魔改版,不测试")]
[Theory()]
[Expectation("TestBadSamples")]
[SampleFileTestData("../data/flv/TestData/Bad", "*.xml")]
public async Task TestBadSamples(string path)
@ -35,12 +35,12 @@ namespace BililiveRecorder.Flv.Tests.RuleTests
await RunPipeline(reader, flvTagListWriter, comments).ConfigureAwait(false);
// Assert
comments.RemoveAll(x => x.T == CommentType.Logging);
comments.RemoveAll(x => !x.ActionRequired);
var outputResult = new OutputResult
{
AlternativeHeaders = flvTagListWriter.AlternativeHeaders.Select(x => x.BinaryDataForSerializationUseOnly).ToArray(),
Comments = comments.GroupBy(x => x.T).Select(x => new CommentCount(x.Key, x.Count())).ToArray(),
Comments = comments.GroupBy(x => x.Type).Select(x => new CommentCount(x.Key, x.Count())).ToArray(),
TagCounts = flvTagListWriter.Files.Select(x => x.Count).ToArray()
};

View File

@ -14,7 +14,7 @@ namespace BililiveRecorder.Flv.Tests.RuleTests
[ExpectationPath("Good")]
public class IntegratedGoodTests : IntegratedTestBase
{
[Theory(Skip = "魔改版,不测试")]
[Theory()]
[Expectation("StandardTest")]
[SampleFileTestData("../data/flv/TestData/Good", "*.xml")]
public async Task StrictTestsAsync(string path)
@ -29,7 +29,7 @@ namespace BililiveRecorder.Flv.Tests.RuleTests
await RunPipeline(reader, flvTagListWriter, comments).ConfigureAwait(false);
// Assert
comments.RemoveAll(x => x.T == CommentType.Logging);
comments.RemoveAll(x => !x.ActionRequired);
Assert.Empty(comments);
@ -49,7 +49,7 @@ namespace BililiveRecorder.Flv.Tests.RuleTests
await Verifier.Verify(xmlStr).UseExtension("xml").UseParameters(path);
}
[Theory(Skip = "魔改版,不测试")]
[Theory()]
[Expectation("WithOffsetTest")]
[SampleFileTestData("../data/flv/TestData/Good", "*.xml")]
public async Task StrictWithArtificalOffsetTestsAsync(string path)
@ -74,8 +74,8 @@ namespace BililiveRecorder.Flv.Tests.RuleTests
await RunPipeline(reader, output, comments).ConfigureAwait(false);
// Assert
comments.RemoveAll(x => x.T == CommentType.Logging);
Assert.Equal(CommentType.TimestampJump, Assert.Single(comments).T);
comments.RemoveAll(x => !x.ActionRequired);
Assert.Equal(CommentType.TimestampJump, Assert.Single(comments).Type);
Assert.Empty(output.AlternativeHeaders);

View File

@ -43,7 +43,7 @@ namespace BililiveRecorder.Flv.Tests.RuleTests
await RunPipeline(reader, output, comments).ConfigureAwait(false);
// 忽略 ignore Logging
comments.RemoveAll(x => x.T == CommentType.Logging);
comments.RemoveAll(x => !x.ActionRequired);
// 不应该有任何问题 Shouldn't have any problems
Assert.Empty(comments);
// 不应该有多个 Header Shouldn't have multiple headers