fix: timestamp processing with h264 annex b (#627)

* fix: timestamp processing with h264 annex b

* fix: mark comment as no action required

* enable logging for tool commands
This commit is contained in:
Genteure 2024-12-01 19:28:19 +08:00 committed by GitHub
parent 9859c32a23
commit 19c529c259
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 59 additions and 12 deletions

View File

@ -1,7 +1,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.CommandLine; using System.CommandLine;
using System.CommandLine.Builder;
using System.CommandLine.NamingConventionBinder; using System.CommandLine.NamingConventionBinder;
using System.CommandLine.Parsing;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
@ -119,7 +121,41 @@ namespace BililiveRecorder.Cli
} }
} }
return root.Invoke(args); var builder = new CommandLineBuilder(root);
builder.AddMiddleware(async (context, next) =>
{
var isToolCommand = false;
var tct = typeof(ToolCommand);
var cr = context.ParseResult.CommandResult;
while (cr is not null)
{
if (cr.Command.GetType() == tct)
{
isToolCommand = true;
break;
}
cr = cr.Parent as CommandResult;
}
cr = null;
if (isToolCommand)
{
// hack to enable logging for tool commands
using var logger = BuildLogger(LogEventLevel.Fatal, LogEventLevel.Verbose);
Log.Logger = logger;
await next(context);
return;
}
else
{
await next(context);
}
});
builder.UseDefaults();
var parser = builder.Build();
return parser.Invoke(args);
} }
private static async Task<int> RunConfigModeAsync(RunModeArguments args) private static async Task<int> RunConfigModeAsync(RunModeArguments args)

View File

@ -17,7 +17,7 @@ namespace BililiveRecorder.Flv.Pipeline.Rules
private const string AUDIO_HEADER_KEY = "HandleNewHeaderRule_AudioHeader"; private const string AUDIO_HEADER_KEY = "HandleNewHeaderRule_AudioHeader";
private const string ANNEXB_KEY = "HandleNewHeaderRule_AnnexB"; private const string ANNEXB_KEY = "HandleNewHeaderRule_AnnexB";
private enum AnnexBState public enum AnnexBState
{ {
Unknown, Unknown,
Pending, Pending,
@ -26,8 +26,8 @@ namespace BililiveRecorder.Flv.Pipeline.Rules
private static readonly ProcessingComment MultipleHeaderComment = new ProcessingComment(CommentType.DecodingHeader, true, "收到了连续多个 Header新建文件"); private static readonly ProcessingComment MultipleHeaderComment = new ProcessingComment(CommentType.DecodingHeader, true, "收到了连续多个 Header新建文件");
private static readonly ProcessingComment SplitFileComment = new ProcessingComment(CommentType.DecodingHeader, true, "因为 Header 问题新建文件"); private static readonly ProcessingComment SplitFileComment = new ProcessingComment(CommentType.DecodingHeader, true, "因为 Header 问题新建文件");
private static readonly ProcessingComment AnnexBCommentFirst = new ProcessingComment(CommentType.DecodingHeader, true, "检测到一次 AnnexB 格式"); private static readonly ProcessingComment AnnexBCommentFirst = new ProcessingComment(CommentType.DecodingHeader, false, "检测到一次 AnnexB 格式");
private static readonly ProcessingComment AnnexBComment = new ProcessingComment(CommentType.DecodingHeader, true, "检测到 AnnexB 格式,不再切割文件"); private static readonly ProcessingComment AnnexBComment = new ProcessingComment(CommentType.DecodingHeader, false, "检测到 AnnexB 格式,不再切割文件");
private readonly bool disableSplitOnH264AnnexB; private readonly bool disableSplitOnH264AnnexB;
@ -42,12 +42,18 @@ namespace BililiveRecorder.Flv.Pipeline.Rules
next(); next();
} }
public static AnnexBState GetAnnexBState(FlvProcessingContext context)
{
if (context.SessionItems.TryGetValue(ANNEXB_KEY, out var annexBStateObj))
return annexBStateObj is AnnexBState annexBState ? annexBState : AnnexBState.Unknown;
return AnnexBState.Unknown;
}
private IEnumerable<PipelineAction?> RunPerAction(FlvProcessingContext context, PipelineAction action) private IEnumerable<PipelineAction?> RunPerAction(FlvProcessingContext context, PipelineAction action)
{ {
if (this.disableSplitOnH264AnnexB) if (this.disableSplitOnH264AnnexB)
{ {
context.SessionItems.TryGetValue(ANNEXB_KEY, out var annexBStateObj); var state = GetAnnexBState(context);
var state = annexBStateObj is AnnexBState annexBState ? annexBState : AnnexBState.Unknown;
if (state == AnnexBState.IsAnnexB) if (state == AnnexBState.IsAnnexB)
{ {
@ -56,6 +62,7 @@ namespace BililiveRecorder.Flv.Pipeline.Rules
yield break; yield break;
} }
// 检测 Annex B 格式
if (action is PipelineDataAction data) if (action is PipelineDataAction data)
{ {
var annexb = false; var annexb = false;

View File

@ -95,13 +95,17 @@ namespace BililiveRecorder.Flv.Pipeline.Rules
s.Tag.Timestamp = ts.NextTimestampTarget; s.Tag.Timestamp = ts.NextTimestampTarget;
// ts.Reset(); // ts.Reset();
} }
else if (action is PipelineHeaderAction h) // Header Tag 时间戳永远为 0 else if (action is PipelineHeaderAction h)
{ {
if (h.VideoHeader != null) var annexBState = HandleNewHeaderRule.GetAnnexBState(context);
h.VideoHeader.Timestamp = 0; if (annexBState != HandleNewHeaderRule.AnnexBState.IsAnnexB)
if (h.AudioHeader != null) {
h.AudioHeader.Timestamp = 0; // Header Tag 时间戳重设到 0
ts.Reset(); if (h.VideoHeader != null)
h.VideoHeader.Timestamp = 0;
if (h.AudioHeader != null)
h.AudioHeader.Timestamp = 0;
}
} }
} }
} }