From d7c03f4736c8cdd63fadc97722c25036757ba7a1 Mon Sep 17 00:00:00 2001 From: Genteure Date: Fri, 22 Nov 2024 21:55:20 +0800 Subject: [PATCH] feat: add option to disable spliting when H264 Annex-B is detected (#614) * feat: add option to disable spliting when H264 Annex-B is detected * add wpf ui toggles * chore: remove public api check for flv * fix warning unboxing a possibly null value * fix cli tool help text * feat(wpf): add disable split on h264annexb option for toolbox --- .../Configure/ConfigInstructions.gen.cs | 4 + BililiveRecorder.Core/Config/V3/Config.gen.cs | 18 + .../Recording/StandardRecordTask.cs | 3 +- .../Pipeline/ProcessingPipelineSettings.cs | 5 + .../Pipeline/Rules/HandleNewHeaderRule.cs | 80 ++ BililiveRecorder.ToolBox/ToolCommand.cs | 4 +- .../Controls/PerRoomSettingsDialog.xaml | 5 + BililiveRecorder.WPF/Pages/SettingsPage.xaml | 1 + .../Pages/ToolboxAutoFixPage.xaml | 1 + .../Pages/ToolboxAutoFixPage.xaml.cs | 12 +- BililiveRecorder.Web/Models/Config.gen.cs | 11 + configV3.schema.json | 32 + config_gen/data.ts | 7 + .../PublicApi.HasNoChangesAsync.verified.txt | 904 ------------------ test/BililiveRecorder.Flv.Tests/PublicApi.cs | 18 - .../VerifyConfig.cs | 2 +- 16 files changed, 179 insertions(+), 928 deletions(-) delete mode 100644 test/BililiveRecorder.Flv.Tests/Expectations/PublicApi.HasNoChangesAsync.verified.txt delete mode 100644 test/BililiveRecorder.Flv.Tests/PublicApi.cs diff --git a/BililiveRecorder.Cli/Configure/ConfigInstructions.gen.cs b/BililiveRecorder.Cli/Configure/ConfigInstructions.gen.cs index f8d8df5..bae8a43 100644 --- a/BililiveRecorder.Cli/Configure/ConfigInstructions.gen.cs +++ b/BililiveRecorder.Cli/Configure/ConfigInstructions.gen.cs @@ -27,6 +27,7 @@ namespace BililiveRecorder.Cli.Configure RecordingQuality, FileNameRecordTemplate, FlvProcessorSplitOnScriptTag, + FlvProcessorDisableSplitOnH264AnnexB, FlvWriteMetadata, TitleFilterPatterns, WebHookUrls, @@ -67,6 +68,7 @@ namespace BililiveRecorder.Cli.Configure SaveStreamCover, RecordingQuality, FlvProcessorSplitOnScriptTag, + FlvProcessorDisableSplitOnH264AnnexB, TitleFilterPatterns } public static class ConfigInstructions @@ -89,6 +91,7 @@ namespace BililiveRecorder.Cli.Configure GlobalConfig.Add(GlobalConfigProperties.RecordingQuality, new ConfigInstruction(config => config.HasRecordingQuality = false, (config, value) => config.RecordingQuality = value) { Name = "RecordingQuality", CanBeOptional = true }); GlobalConfig.Add(GlobalConfigProperties.FileNameRecordTemplate, new ConfigInstruction(config => config.HasFileNameRecordTemplate = false, (config, value) => config.FileNameRecordTemplate = value) { Name = "FileNameRecordTemplate", CanBeOptional = true }); GlobalConfig.Add(GlobalConfigProperties.FlvProcessorSplitOnScriptTag, new ConfigInstruction(config => config.HasFlvProcessorSplitOnScriptTag = false, (config, value) => config.FlvProcessorSplitOnScriptTag = value) { Name = "FlvProcessorSplitOnScriptTag", CanBeOptional = true }); + GlobalConfig.Add(GlobalConfigProperties.FlvProcessorDisableSplitOnH264AnnexB, new ConfigInstruction(config => config.HasFlvProcessorDisableSplitOnH264AnnexB = false, (config, value) => config.FlvProcessorDisableSplitOnH264AnnexB = value) { Name = "FlvProcessorDisableSplitOnH264AnnexB", CanBeOptional = true }); GlobalConfig.Add(GlobalConfigProperties.FlvWriteMetadata, new ConfigInstruction(config => config.HasFlvWriteMetadata = false, (config, value) => config.FlvWriteMetadata = value) { Name = "FlvWriteMetadata", CanBeOptional = true }); GlobalConfig.Add(GlobalConfigProperties.TitleFilterPatterns, new ConfigInstruction(config => config.HasTitleFilterPatterns = false, (config, value) => config.TitleFilterPatterns = value) { Name = "TitleFilterPatterns", CanBeOptional = true }); GlobalConfig.Add(GlobalConfigProperties.WebHookUrls, new ConfigInstruction(config => config.HasWebHookUrls = false, (config, value) => config.WebHookUrls = value) { Name = "WebHookUrls", CanBeOptional = true }); @@ -125,6 +128,7 @@ namespace BililiveRecorder.Cli.Configure RoomConfig.Add(RoomConfigProperties.SaveStreamCover, new ConfigInstruction(config => config.HasSaveStreamCover = false, (config, value) => config.SaveStreamCover = value) { Name = "SaveStreamCover", CanBeOptional = true }); RoomConfig.Add(RoomConfigProperties.RecordingQuality, new ConfigInstruction(config => config.HasRecordingQuality = false, (config, value) => config.RecordingQuality = value) { Name = "RecordingQuality", CanBeOptional = true }); RoomConfig.Add(RoomConfigProperties.FlvProcessorSplitOnScriptTag, new ConfigInstruction(config => config.HasFlvProcessorSplitOnScriptTag = false, (config, value) => config.FlvProcessorSplitOnScriptTag = value) { Name = "FlvProcessorSplitOnScriptTag", CanBeOptional = true }); + RoomConfig.Add(RoomConfigProperties.FlvProcessorDisableSplitOnH264AnnexB, new ConfigInstruction(config => config.HasFlvProcessorDisableSplitOnH264AnnexB = false, (config, value) => config.FlvProcessorDisableSplitOnH264AnnexB = value) { Name = "FlvProcessorDisableSplitOnH264AnnexB", CanBeOptional = true }); RoomConfig.Add(RoomConfigProperties.TitleFilterPatterns, new ConfigInstruction(config => config.HasTitleFilterPatterns = false, (config, value) => config.TitleFilterPatterns = value) { Name = "TitleFilterPatterns", CanBeOptional = true }); } } diff --git a/BililiveRecorder.Core/Config/V3/Config.gen.cs b/BililiveRecorder.Core/Config/V3/Config.gen.cs index 3272834..690601d 100644 --- a/BililiveRecorder.Core/Config/V3/Config.gen.cs +++ b/BililiveRecorder.Core/Config/V3/Config.gen.cs @@ -125,6 +125,14 @@ namespace BililiveRecorder.Core.Config.V3 [JsonProperty(nameof(FlvProcessorSplitOnScriptTag)), EditorBrowsable(EditorBrowsableState.Never)] public Optional OptionalFlvProcessorSplitOnScriptTag { get => this.GetPropertyValueOptional(nameof(this.FlvProcessorSplitOnScriptTag)); set => this.SetPropertyValueOptional(value, nameof(this.FlvProcessorSplitOnScriptTag)); } + /// + /// FLV修复-检测到 H264 Annex-B 时禁用修复分段 + /// + public bool FlvProcessorDisableSplitOnH264AnnexB { get => this.GetPropertyValue(); set => this.SetPropertyValue(value); } + public bool HasFlvProcessorDisableSplitOnH264AnnexB { get => this.GetPropertyHasValue(nameof(this.FlvProcessorDisableSplitOnH264AnnexB)); set => this.SetPropertyHasValue(value, nameof(this.FlvProcessorDisableSplitOnH264AnnexB)); } + [JsonProperty(nameof(FlvProcessorDisableSplitOnH264AnnexB)), EditorBrowsable(EditorBrowsableState.Never)] + public Optional OptionalFlvProcessorDisableSplitOnH264AnnexB { get => this.GetPropertyValueOptional(nameof(this.FlvProcessorDisableSplitOnH264AnnexB)); set => this.SetPropertyValueOptional(value, nameof(this.FlvProcessorDisableSplitOnH264AnnexB)); } + /// /// 不录制的标题匹配正则 /// @@ -347,6 +355,14 @@ namespace BililiveRecorder.Core.Config.V3 [JsonProperty(nameof(FlvProcessorSplitOnScriptTag)), EditorBrowsable(EditorBrowsableState.Never)] public Optional OptionalFlvProcessorSplitOnScriptTag { get => this.GetPropertyValueOptional(nameof(this.FlvProcessorSplitOnScriptTag)); set => this.SetPropertyValueOptional(value, nameof(this.FlvProcessorSplitOnScriptTag)); } + /// + /// FLV修复-检测到 H264 Annex-B 时禁用修复分段 + /// + public bool FlvProcessorDisableSplitOnH264AnnexB { get => this.GetPropertyValue(); set => this.SetPropertyValue(value); } + public bool HasFlvProcessorDisableSplitOnH264AnnexB { get => this.GetPropertyHasValue(nameof(this.FlvProcessorDisableSplitOnH264AnnexB)); set => this.SetPropertyHasValue(value, nameof(this.FlvProcessorDisableSplitOnH264AnnexB)); } + [JsonProperty(nameof(FlvProcessorDisableSplitOnH264AnnexB)), EditorBrowsable(EditorBrowsableState.Never)] + public Optional OptionalFlvProcessorDisableSplitOnH264AnnexB { get => this.GetPropertyValueOptional(nameof(this.FlvProcessorDisableSplitOnH264AnnexB)); set => this.SetPropertyValueOptional(value, nameof(this.FlvProcessorDisableSplitOnH264AnnexB)); } + /// /// 是否在视频文件写入直播信息 metadata /// @@ -548,6 +564,8 @@ namespace BililiveRecorder.Core.Config.V3 public bool FlvProcessorSplitOnScriptTag => false; + public bool FlvProcessorDisableSplitOnH264AnnexB => false; + public bool FlvWriteMetadata => true; public string TitleFilterPatterns => @""; diff --git a/BililiveRecorder.Core/Recording/StandardRecordTask.cs b/BililiveRecorder.Core/Recording/StandardRecordTask.cs index 13f5b33..81c745d 100644 --- a/BililiveRecorder.Core/Recording/StandardRecordTask.cs +++ b/BililiveRecorder.Core/Recording/StandardRecordTask.cs @@ -64,7 +64,8 @@ namespace BililiveRecorder.Core.Recording this.pipeline = builder .ConfigureServices(services => services.AddSingleton(new ProcessingPipelineSettings { - SplitOnScriptTag = room.RoomConfig.FlvProcessorSplitOnScriptTag + SplitOnScriptTag = room.RoomConfig.FlvProcessorSplitOnScriptTag, + DisableSplitOnH264AnnexB = room.RoomConfig.FlvProcessorDisableSplitOnH264AnnexB, })) .AddRule(this.statsRule) .AddRule(this.splitFileRule) diff --git a/BililiveRecorder.Flv/Pipeline/ProcessingPipelineSettings.cs b/BililiveRecorder.Flv/Pipeline/ProcessingPipelineSettings.cs index c29e17c..1afebf8 100644 --- a/BililiveRecorder.Flv/Pipeline/ProcessingPipelineSettings.cs +++ b/BililiveRecorder.Flv/Pipeline/ProcessingPipelineSettings.cs @@ -9,5 +9,10 @@ namespace BililiveRecorder.Flv.Pipeline /// 控制收到 onMetaData 时是否分段 /// public bool SplitOnScriptTag { get; set; } = false; + + /// + /// 检测到 H264 Annex-B 时禁用修复分段 + /// + public bool DisableSplitOnH264AnnexB { get; set; } = false; } } diff --git a/BililiveRecorder.Flv/Pipeline/Rules/HandleNewHeaderRule.cs b/BililiveRecorder.Flv/Pipeline/Rules/HandleNewHeaderRule.cs index ef3627e..020f694 100644 --- a/BililiveRecorder.Flv/Pipeline/Rules/HandleNewHeaderRule.cs +++ b/BililiveRecorder.Flv/Pipeline/Rules/HandleNewHeaderRule.cs @@ -15,9 +15,26 @@ namespace BililiveRecorder.Flv.Pipeline.Rules { private const string VIDEO_HEADER_KEY = "HandleNewHeaderRule_VideoHeader"; private const string AUDIO_HEADER_KEY = "HandleNewHeaderRule_AudioHeader"; + private const string ANNEXB_KEY = "HandleNewHeaderRule_AnnexB"; + + private enum AnnexBState + { + Unknown, + Pending, + IsAnnexB, + } 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 AnnexBCommentFirst = new ProcessingComment(CommentType.DecodingHeader, true, "检测到一次 AnnexB 格式"); + private static readonly ProcessingComment AnnexBComment = new ProcessingComment(CommentType.DecodingHeader, true, "检测到 AnnexB 格式,不再切割文件"); + + private readonly bool disableSplitOnH264AnnexB; + + public HandleNewHeaderRule(ProcessingPipelineSettings? processingPipelineSettings) + { + this.disableSplitOnH264AnnexB = processingPipelineSettings?.DisableSplitOnH264AnnexB ?? false; + } public void Run(FlvProcessingContext context, Action next) { @@ -27,8 +44,71 @@ namespace BililiveRecorder.Flv.Pipeline.Rules private IEnumerable RunPerAction(FlvProcessingContext context, PipelineAction action) { + if (this.disableSplitOnH264AnnexB) + { + context.SessionItems.TryGetValue(ANNEXB_KEY, out var annexBStateObj); + var state = annexBStateObj is AnnexBState annexBState ? annexBState : AnnexBState.Unknown; + + if (state == AnnexBState.IsAnnexB) + { + // 如果已经检测到 Annex B 格式则不再切割文件 + yield return action; + yield break; + } + + if (action is PipelineDataAction data) + { + var annexb = false; + + for (var i = 0; i < data.Tags.Count; i++) + { + var tag = data.Tags[i]; + if (tag.IsKeyframeData()) + { + // Check nalu + if (tag.Nalus is { } nalus) + { + bool sps = false, pps = false; + foreach (var nalu in nalus) + { + if (nalu.Type == H264NaluType.Sps) + sps = true; + if (nalu.Type == H264NaluType.Pps) + pps = true; + } + annexb = sps && pps; + } + + break; + } + } + + if (annexb) + { + if (state == AnnexBState.Unknown) + { + context.SessionItems[ANNEXB_KEY] = AnnexBState.Pending; + context.AddComment(AnnexBCommentFirst); + } + else + { + context.SessionItems[ANNEXB_KEY] = AnnexBState.IsAnnexB; + context.AddComment(AnnexBComment); + } + } + + yield return action; + yield break; + } // if (action is PipelineDataAction data) + } // if (this.disableSplitOnH264AnnexB) + if (action is PipelineHeaderAction header) { + if (this.disableSplitOnH264AnnexB) + { + context.SessionItems.Remove(ANNEXB_KEY); + } + // 从 Session Items 里取上次写入的 Header var lastVideoHeader = context.SessionItems.ContainsKey(VIDEO_HEADER_KEY) ? context.SessionItems[VIDEO_HEADER_KEY] as Tag : null; var lastAudioHeader = context.SessionItems.ContainsKey(AUDIO_HEADER_KEY) ? context.SessionItems[AUDIO_HEADER_KEY] as Tag : null; diff --git a/BililiveRecorder.ToolBox/ToolCommand.cs b/BililiveRecorder.ToolBox/ToolCommand.cs index b99c0dd..1b18d15 100644 --- a/BililiveRecorder.ToolBox/ToolCommand.cs +++ b/BililiveRecorder.ToolBox/ToolCommand.cs @@ -22,14 +22,14 @@ namespace BililiveRecorder.ToolBox this.RegisterCommand("analyze", null, c => { c.Add(new Argument("input", "example: input.flv")); - c.Add(new Option(name: "pipeline-settings", parseArgument: this.ParseProcessingPipelineSettings)); + c.Add(new Option(name: "--pipeline-settings", parseArgument: this.ParseProcessingPipelineSettings)); }); this.RegisterCommand("fix", null, c => { c.Add(new Argument("input", "example: input.flv")); c.Add(new Argument("output-base", "example: output.flv")); - c.Add(new Option(name: "pipeline-settings", parseArgument: this.ParseProcessingPipelineSettings)); + c.Add(new Option(name: "--pipeline-settings", parseArgument: this.ParseProcessingPipelineSettings)); }); this.RegisterCommand("export", null, c => diff --git a/BililiveRecorder.WPF/Controls/PerRoomSettingsDialog.xaml b/BililiveRecorder.WPF/Controls/PerRoomSettingsDialog.xaml index ea0a3c7..c510829 100644 --- a/BililiveRecorder.WPF/Controls/PerRoomSettingsDialog.xaml +++ b/BililiveRecorder.WPF/Controls/PerRoomSettingsDialog.xaml @@ -68,6 +68,11 @@ + + + + + diff --git a/BililiveRecorder.WPF/Pages/SettingsPage.xaml b/BililiveRecorder.WPF/Pages/SettingsPage.xaml index 5c801ec..45ecc28 100644 --- a/BililiveRecorder.WPF/Pages/SettingsPage.xaml +++ b/BililiveRecorder.WPF/Pages/SettingsPage.xaml @@ -56,6 +56,7 @@ + diff --git a/BililiveRecorder.WPF/Pages/ToolboxAutoFixPage.xaml b/BililiveRecorder.WPF/Pages/ToolboxAutoFixPage.xaml index 68686a4..8ef3eee 100644 --- a/BililiveRecorder.WPF/Pages/ToolboxAutoFixPage.xaml +++ b/BililiveRecorder.WPF/Pages/ToolboxAutoFixPage.xaml @@ -62,6 +62,7 @@ + diff --git a/BililiveRecorder.WPF/Pages/ToolboxAutoFixPage.xaml.cs b/BililiveRecorder.WPF/Pages/ToolboxAutoFixPage.xaml.cs index 28b5415..83e222b 100644 --- a/BililiveRecorder.WPF/Pages/ToolboxAutoFixPage.xaml.cs +++ b/BililiveRecorder.WPF/Pages/ToolboxAutoFixPage.xaml.cs @@ -113,7 +113,8 @@ namespace BililiveRecorder.WPF.Pages OutputBase = output_path, PipelineSettings = new Flv.Pipeline.ProcessingPipelineSettings { - SplitOnScriptTag = this.settings.SplitOnScriptTag + SplitOnScriptTag = this.settings.SplitOnScriptTag, + DisableSplitOnH264AnnexB = this.settings.DisableSplitOnH264AnnexB, } }; @@ -193,7 +194,8 @@ namespace BililiveRecorder.WPF.Pages Input = inputPath, PipelineSettings = new Flv.Pipeline.ProcessingPipelineSettings { - SplitOnScriptTag = this.settings.SplitOnScriptTag + SplitOnScriptTag = this.settings.SplitOnScriptTag, + DisableSplitOnH264AnnexB = this.settings.DisableSplitOnH264AnnexB, } }; @@ -350,6 +352,7 @@ namespace BililiveRecorder.WPF.Pages public sealed class AutoFixSettings : INotifyPropertyChanged { private bool splitOnScriptTag; + private bool disableSplitOnH264AnnexB; public event PropertyChangedEventHandler? PropertyChanged; private bool SetField(ref T location, T value, [CallerMemberName] string propertyName = "") @@ -365,6 +368,11 @@ namespace BililiveRecorder.WPF.Pages /// FLV修复-检测到可能缺少数据时分段 /// public bool SplitOnScriptTag { get => this.splitOnScriptTag; set => this.SetField(ref this.splitOnScriptTag, value); } + + /// + /// FLV修复-检测到 H264 Annex-B 时禁用修复分段 + /// + public bool DisableSplitOnH264AnnexB { get => this.disableSplitOnH264AnnexB; set => this.SetField(ref this.disableSplitOnH264AnnexB, value); } } } } diff --git a/BililiveRecorder.Web/Models/Config.gen.cs b/BililiveRecorder.Web/Models/Config.gen.cs index bbbc248..a010a98 100644 --- a/BililiveRecorder.Web/Models/Config.gen.cs +++ b/BililiveRecorder.Web/Models/Config.gen.cs @@ -25,6 +25,7 @@ namespace BililiveRecorder.Web.Models public Optional? OptionalSaveStreamCover { get; set; } public Optional? OptionalRecordingQuality { get; set; } public Optional? OptionalFlvProcessorSplitOnScriptTag { get; set; } + public Optional? OptionalFlvProcessorDisableSplitOnH264AnnexB { get; set; } public Optional? OptionalTitleFilterPatterns { get; set; } public void ApplyTo(RoomConfig config) @@ -42,6 +43,7 @@ namespace BililiveRecorder.Web.Models if (this.OptionalSaveStreamCover.HasValue) config.OptionalSaveStreamCover = this.OptionalSaveStreamCover.Value; if (this.OptionalRecordingQuality.HasValue) config.OptionalRecordingQuality = this.OptionalRecordingQuality.Value; if (this.OptionalFlvProcessorSplitOnScriptTag.HasValue) config.OptionalFlvProcessorSplitOnScriptTag = this.OptionalFlvProcessorSplitOnScriptTag.Value; + if (this.OptionalFlvProcessorDisableSplitOnH264AnnexB.HasValue) config.OptionalFlvProcessorDisableSplitOnH264AnnexB = this.OptionalFlvProcessorDisableSplitOnH264AnnexB.Value; if (this.OptionalTitleFilterPatterns.HasValue) config.OptionalTitleFilterPatterns = this.OptionalTitleFilterPatterns.Value; } } @@ -61,6 +63,7 @@ namespace BililiveRecorder.Web.Models public Optional? OptionalRecordingQuality { get; set; } public Optional? OptionalFileNameRecordTemplate { get; set; } public Optional? OptionalFlvProcessorSplitOnScriptTag { get; set; } + public Optional? OptionalFlvProcessorDisableSplitOnH264AnnexB { get; set; } public Optional? OptionalFlvWriteMetadata { get; set; } public Optional? OptionalTitleFilterPatterns { get; set; } public Optional? OptionalWebHookUrls { get; set; } @@ -98,6 +101,7 @@ namespace BililiveRecorder.Web.Models if (this.OptionalRecordingQuality.HasValue) config.OptionalRecordingQuality = this.OptionalRecordingQuality.Value; if (this.OptionalFileNameRecordTemplate.HasValue) config.OptionalFileNameRecordTemplate = this.OptionalFileNameRecordTemplate.Value; if (this.OptionalFlvProcessorSplitOnScriptTag.HasValue) config.OptionalFlvProcessorSplitOnScriptTag = this.OptionalFlvProcessorSplitOnScriptTag.Value; + if (this.OptionalFlvProcessorDisableSplitOnH264AnnexB.HasValue) config.OptionalFlvProcessorDisableSplitOnH264AnnexB = this.OptionalFlvProcessorDisableSplitOnH264AnnexB.Value; if (this.OptionalFlvWriteMetadata.HasValue) config.OptionalFlvWriteMetadata = this.OptionalFlvWriteMetadata.Value; if (this.OptionalTitleFilterPatterns.HasValue) config.OptionalTitleFilterPatterns = this.OptionalTitleFilterPatterns.Value; if (this.OptionalWebHookUrls.HasValue) config.OptionalWebHookUrls = this.OptionalWebHookUrls.Value; @@ -141,6 +145,7 @@ namespace BililiveRecorder.Web.Models.Rest public Optional OptionalSaveStreamCover { get; set; } public Optional OptionalRecordingQuality { get; set; } public Optional OptionalFlvProcessorSplitOnScriptTag { get; set; } + public Optional OptionalFlvProcessorDisableSplitOnH264AnnexB { get; set; } public Optional OptionalTitleFilterPatterns { get; set; } } @@ -159,6 +164,7 @@ namespace BililiveRecorder.Web.Models.Rest public Optional OptionalRecordingQuality { get; set; } public Optional OptionalFileNameRecordTemplate { get; set; } public Optional OptionalFlvProcessorSplitOnScriptTag { get; set; } + public Optional OptionalFlvProcessorDisableSplitOnH264AnnexB { get; set; } public Optional OptionalFlvWriteMetadata { get; set; } public Optional OptionalTitleFilterPatterns { get; set; } public Optional OptionalWebHookUrls { get; set; } @@ -204,6 +210,7 @@ namespace BililiveRecorder.Web.Models.Graphql this.Field(x => x.OptionalSaveStreamCover, type: typeof(HierarchicalOptionalType)); this.Field(x => x.OptionalRecordingQuality, type: typeof(HierarchicalOptionalType)); this.Field(x => x.OptionalFlvProcessorSplitOnScriptTag, type: typeof(HierarchicalOptionalType)); + this.Field(x => x.OptionalFlvProcessorDisableSplitOnH264AnnexB, type: typeof(HierarchicalOptionalType)); this.Field(x => x.OptionalTitleFilterPatterns, type: typeof(HierarchicalOptionalType)); } } @@ -225,6 +232,7 @@ namespace BililiveRecorder.Web.Models.Graphql this.Field(x => x.OptionalRecordingQuality, type: typeof(HierarchicalOptionalType)); this.Field(x => x.OptionalFileNameRecordTemplate, type: typeof(HierarchicalOptionalType)); this.Field(x => x.OptionalFlvProcessorSplitOnScriptTag, type: typeof(HierarchicalOptionalType)); + this.Field(x => x.OptionalFlvProcessorDisableSplitOnH264AnnexB, type: typeof(HierarchicalOptionalType)); this.Field(x => x.OptionalFlvWriteMetadata, type: typeof(HierarchicalOptionalType)); this.Field(x => x.OptionalTitleFilterPatterns, type: typeof(HierarchicalOptionalType)); this.Field(x => x.OptionalWebHookUrls, type: typeof(HierarchicalOptionalType)); @@ -266,6 +274,7 @@ namespace BililiveRecorder.Web.Models.Graphql this.Field(x => x.RecordingQuality); this.Field(x => x.FileNameRecordTemplate); this.Field(x => x.FlvProcessorSplitOnScriptTag); + this.Field(x => x.FlvProcessorDisableSplitOnH264AnnexB); this.Field(x => x.FlvWriteMetadata); this.Field(x => x.TitleFilterPatterns); this.Field(x => x.WebHookUrls); @@ -307,6 +316,7 @@ namespace BililiveRecorder.Web.Models.Graphql this.Field(x => x.OptionalSaveStreamCover, nullable: true, type: typeof(HierarchicalOptionalInputType)); this.Field(x => x.OptionalRecordingQuality, nullable: true, type: typeof(HierarchicalOptionalInputType)); this.Field(x => x.OptionalFlvProcessorSplitOnScriptTag, nullable: true, type: typeof(HierarchicalOptionalInputType)); + this.Field(x => x.OptionalFlvProcessorDisableSplitOnH264AnnexB, nullable: true, type: typeof(HierarchicalOptionalInputType)); this.Field(x => x.OptionalTitleFilterPatterns, nullable: true, type: typeof(HierarchicalOptionalInputType)); } } @@ -328,6 +338,7 @@ namespace BililiveRecorder.Web.Models.Graphql this.Field(x => x.OptionalRecordingQuality, nullable: true, type: typeof(HierarchicalOptionalInputType)); this.Field(x => x.OptionalFileNameRecordTemplate, nullable: true, type: typeof(HierarchicalOptionalInputType)); this.Field(x => x.OptionalFlvProcessorSplitOnScriptTag, nullable: true, type: typeof(HierarchicalOptionalInputType)); + this.Field(x => x.OptionalFlvProcessorDisableSplitOnH264AnnexB, nullable: true, type: typeof(HierarchicalOptionalInputType)); this.Field(x => x.OptionalFlvWriteMetadata, nullable: true, type: typeof(HierarchicalOptionalInputType)); this.Field(x => x.OptionalTitleFilterPatterns, nullable: true, type: typeof(HierarchicalOptionalInputType)); this.Field(x => x.OptionalWebHookUrls, nullable: true, type: typeof(HierarchicalOptionalInputType)); diff --git a/configV3.schema.json b/configV3.schema.json index 5b25b08..2710f26 100644 --- a/configV3.schema.json +++ b/configV3.schema.json @@ -578,6 +578,22 @@ } } }, + "FlvProcessorDisableSplitOnH264AnnexB": { + "description": "FLV修复-检测到 H264 Annex-B 时禁用修复分段\n默认: false", + "markdownDescription": "FLV修复-检测到 H264 Annex-B 时禁用修复分段 \n默认: `false `\n\n", + "type": "object", + "additionalProperties": false, + "properties": { + "HasValue": { + "type": "boolean", + "default": true + }, + "Value": { + "type": "boolean", + "default": false + } + } + }, "TitleFilterPatterns": { "description": "不录制的标题匹配正则\n默认: ", "markdownDescription": "不录制的标题匹配正则 \n默认: ` `\n\n", @@ -839,6 +855,22 @@ } } }, + "FlvProcessorDisableSplitOnH264AnnexB": { + "description": "FLV修复-检测到 H264 Annex-B 时禁用修复分段\n默认: false", + "markdownDescription": "FLV修复-检测到 H264 Annex-B 时禁用修复分段 \n默认: `false `\n\n", + "type": "object", + "additionalProperties": false, + "properties": { + "HasValue": { + "type": "boolean", + "default": true + }, + "Value": { + "type": "boolean", + "default": false + } + } + }, "TitleFilterPatterns": { "description": "不录制的标题匹配正则\n默认: ", "markdownDescription": "不录制的标题匹配正则 \n默认: ` `\n\n", diff --git a/config_gen/data.ts b/config_gen/data.ts index eddf8b8..7fae6fc 100644 --- a/config_gen/data.ts +++ b/config_gen/data.ts @@ -107,6 +107,13 @@ export const data: Array = [ configType: "room", default: false }, + { + id: "FlvProcessorDisableSplitOnH264AnnexB", + name: "FLV修复-检测到 H264 Annex-B 时禁用修复分段", + type: "bool", + configType: "room", + default: false + }, { id: "FlvWriteMetadata", name: "是否在视频文件写入直播信息 metadata", diff --git a/test/BililiveRecorder.Flv.Tests/Expectations/PublicApi.HasNoChangesAsync.verified.txt b/test/BililiveRecorder.Flv.Tests/Expectations/PublicApi.HasNoChangesAsync.verified.txt deleted file mode 100644 index 154bb3b..0000000 --- a/test/BililiveRecorder.Flv.Tests/Expectations/PublicApi.HasNoChangesAsync.verified.txt +++ /dev/null @@ -1,904 +0,0 @@ -namespace BililiveRecorder.DependencyInjection -{ - public static class DependencyInjectionExtensions - { - public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddFlv(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) { } - } -} -namespace BililiveRecorder.Flv.Amf -{ - public class AmfException : System.Exception - { - public AmfException() { } - public AmfException(string message) { } - protected AmfException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public AmfException(string message, System.Exception innerException) { } - } - [Newtonsoft.Json.JsonConverter(typeof(JsonSubTypes.JsonSubtypes), new object[] { - "Type"})] - [Newtonsoft.Json.JsonObject(MemberSerialization=Newtonsoft.Json.MemberSerialization.OptIn)] - public interface IScriptDataValue - { - [Newtonsoft.Json.JsonProperty] - BililiveRecorder.Flv.Amf.ScriptDataType Type { get; } - void WriteTo(System.IO.Stream stream); - } - [System.Diagnostics.DebuggerDisplay("AmfBoolean, {Value}")] - public class ScriptDataBoolean : BililiveRecorder.Flv.Amf.IScriptDataValue - { - public ScriptDataBoolean() { } - public BililiveRecorder.Flv.Amf.ScriptDataType Type { get; } - [Newtonsoft.Json.JsonProperty] - public bool Value { get; set; } - public override bool Equals(object? obj) { } - public override int GetHashCode() { } - public void WriteTo(System.IO.Stream stream) { } - public static bool op_Implicit(BililiveRecorder.Flv.Amf.ScriptDataBoolean boolean) { } - public static BililiveRecorder.Flv.Amf.ScriptDataBoolean op_Implicit(bool boolean) { } - public static bool operator !=(BililiveRecorder.Flv.Amf.ScriptDataBoolean left, BililiveRecorder.Flv.Amf.ScriptDataBoolean right) { } - public static bool operator ==(BililiveRecorder.Flv.Amf.ScriptDataBoolean left, BililiveRecorder.Flv.Amf.ScriptDataBoolean right) { } - } - [System.Diagnostics.DebuggerDisplay("AmfDate, {Value}")] - public class ScriptDataDate : BililiveRecorder.Flv.Amf.IScriptDataValue - { - public ScriptDataDate() { } - public ScriptDataDate(System.DateTimeOffset value) { } - public ScriptDataDate(double dateTime, short localDateTimeOffset) { } - public BililiveRecorder.Flv.Amf.ScriptDataType Type { get; } - [Newtonsoft.Json.JsonProperty] - public System.DateTimeOffset Value { get; set; } - public override bool Equals(object? obj) { } - public override int GetHashCode() { } - public void WriteTo(System.IO.Stream stream) { } - public static System.DateTimeOffset op_Implicit(BililiveRecorder.Flv.Amf.ScriptDataDate date) { } - public static System.DateTime op_Implicit(BililiveRecorder.Flv.Amf.ScriptDataDate date) { } - public static BililiveRecorder.Flv.Amf.ScriptDataDate op_Implicit(System.DateTime date) { } - public static BililiveRecorder.Flv.Amf.ScriptDataDate op_Implicit(System.DateTimeOffset date) { } - public static bool operator !=(BililiveRecorder.Flv.Amf.ScriptDataDate left, BililiveRecorder.Flv.Amf.ScriptDataDate right) { } - public static bool operator ==(BililiveRecorder.Flv.Amf.ScriptDataDate left, BililiveRecorder.Flv.Amf.ScriptDataDate right) { } - } - [System.Diagnostics.DebuggerDisplay("AmfEcmaArray, Count = {Count}")] - [System.Diagnostics.DebuggerTypeProxy(typeof(BililiveRecorder.Flv.Amf.AmfDictionaryDebugView))] - public class ScriptDataEcmaArray : BililiveRecorder.Flv.Amf.IScriptDataValue, System.Collections.Generic.ICollection>, System.Collections.Generic.IDictionary, System.Collections.Generic.IEnumerable>, System.Collections.Generic.IReadOnlyCollection>, System.Collections.Generic.IReadOnlyDictionary, System.Collections.IEnumerable - { - public ScriptDataEcmaArray() { } - public int Count { get; } - public bool IsReadOnly { get; } - public BililiveRecorder.Flv.Amf.IScriptDataValue this[string key] { get; set; } - public System.Collections.Generic.ICollection Keys { get; } - public BililiveRecorder.Flv.Amf.ScriptDataType Type { get; } - [Newtonsoft.Json.JsonProperty] - public System.Collections.Generic.Dictionary Value { get; set; } - public System.Collections.Generic.ICollection Values { get; } - public void Add(System.Collections.Generic.KeyValuePair item) { } - public void Add(string key, BililiveRecorder.Flv.Amf.IScriptDataValue value) { } - public void Clear() { } - public bool Contains(System.Collections.Generic.KeyValuePair item) { } - public bool ContainsKey(string key) { } - public void CopyTo(System.Collections.Generic.KeyValuePair[] array, int arrayIndex) { } - public System.Collections.Generic.IEnumerator> GetEnumerator() { } - public bool Remove(System.Collections.Generic.KeyValuePair item) { } - public bool Remove(string key) { } - public bool TryGetValue(string key, [System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)] out BililiveRecorder.Flv.Amf.IScriptDataValue value) { } - public void WriteTo(System.IO.Stream stream) { } - public static System.Collections.Generic.Dictionary op_Implicit(BililiveRecorder.Flv.Amf.ScriptDataEcmaArray ecmaArray) { } - public static BililiveRecorder.Flv.Amf.ScriptDataEcmaArray op_Implicit(BililiveRecorder.Flv.Amf.ScriptDataObject @object) { } - public static BililiveRecorder.Flv.Amf.ScriptDataEcmaArray op_Implicit(System.Collections.Generic.Dictionary ecmaArray) { } - } - [System.Diagnostics.DebuggerDisplay("AmfLongString, {Value}")] - public class ScriptDataLongString : BililiveRecorder.Flv.Amf.IScriptDataValue - { - public ScriptDataLongString() { } - public BililiveRecorder.Flv.Amf.ScriptDataType Type { get; } - [Newtonsoft.Json.JsonProperty(Required=Newtonsoft.Json.Required.Always)] - public string Value { get; set; } - public override bool Equals(object? obj) { } - public override int GetHashCode() { } - public void WriteTo(System.IO.Stream stream) { } - public static string op_Implicit(BililiveRecorder.Flv.Amf.ScriptDataLongString @string) { } - public static BililiveRecorder.Flv.Amf.ScriptDataLongString op_Implicit(BililiveRecorder.Flv.Amf.ScriptDataString @string) { } - public static BililiveRecorder.Flv.Amf.ScriptDataLongString op_Implicit(string @string) { } - public static bool operator !=(BililiveRecorder.Flv.Amf.ScriptDataLongString left, BililiveRecorder.Flv.Amf.ScriptDataLongString right) { } - public static bool operator ==(BililiveRecorder.Flv.Amf.ScriptDataLongString left, BililiveRecorder.Flv.Amf.ScriptDataLongString right) { } - } - [System.Diagnostics.DebuggerDisplay("AmfNull")] - public class ScriptDataNull : BililiveRecorder.Flv.Amf.IScriptDataValue - { - public ScriptDataNull() { } - public BililiveRecorder.Flv.Amf.ScriptDataType Type { get; } - public override bool Equals(object? obj) { } - public override int GetHashCode() { } - public void WriteTo(System.IO.Stream stream) { } - public static bool operator !=(BililiveRecorder.Flv.Amf.ScriptDataNull left, BililiveRecorder.Flv.Amf.ScriptDataNull right) { } - public static bool operator ==(BililiveRecorder.Flv.Amf.ScriptDataNull left, BililiveRecorder.Flv.Amf.ScriptDataNull right) { } - } - [System.Diagnostics.DebuggerDisplay("AmfNumber, {Value}")] - public class ScriptDataNumber : BililiveRecorder.Flv.Amf.IScriptDataValue - { - public ScriptDataNumber() { } - public BililiveRecorder.Flv.Amf.ScriptDataType Type { get; } - [Newtonsoft.Json.JsonProperty] - public double Value { get; set; } - public override bool Equals(object? obj) { } - public override int GetHashCode() { } - public void WriteTo(System.IO.Stream stream) { } - public static int op_Explicit(BililiveRecorder.Flv.Amf.ScriptDataNumber number) { } - public static BililiveRecorder.Flv.Amf.ScriptDataNumber op_Explicit(int number) { } - public static double op_Implicit(BililiveRecorder.Flv.Amf.ScriptDataNumber number) { } - public static BililiveRecorder.Flv.Amf.ScriptDataNumber op_Implicit(double number) { } - public static bool operator !=(BililiveRecorder.Flv.Amf.ScriptDataNumber left, BililiveRecorder.Flv.Amf.ScriptDataNumber right) { } - public static bool operator ==(BililiveRecorder.Flv.Amf.ScriptDataNumber left, BililiveRecorder.Flv.Amf.ScriptDataNumber right) { } - } - [System.Diagnostics.DebuggerDisplay("AmfObject, Count = {Count}")] - [System.Diagnostics.DebuggerTypeProxy(typeof(BililiveRecorder.Flv.Amf.AmfDictionaryDebugView))] - public class ScriptDataObject : BililiveRecorder.Flv.Amf.IScriptDataValue, System.Collections.Generic.ICollection>, System.Collections.Generic.IDictionary, System.Collections.Generic.IEnumerable>, System.Collections.Generic.IReadOnlyCollection>, System.Collections.Generic.IReadOnlyDictionary, System.Collections.IEnumerable - { - public ScriptDataObject() { } - public int Count { get; } - public bool IsReadOnly { get; } - public BililiveRecorder.Flv.Amf.IScriptDataValue this[string key] { get; set; } - public System.Collections.Generic.ICollection Keys { get; } - public BililiveRecorder.Flv.Amf.ScriptDataType Type { get; } - [Newtonsoft.Json.JsonProperty] - public System.Collections.Generic.Dictionary Value { get; set; } - public System.Collections.Generic.ICollection Values { get; } - public void Add(System.Collections.Generic.KeyValuePair item) { } - public void Add(string key, BililiveRecorder.Flv.Amf.IScriptDataValue value) { } - public void Clear() { } - public bool Contains(System.Collections.Generic.KeyValuePair item) { } - public bool ContainsKey(string key) { } - public void CopyTo(System.Collections.Generic.KeyValuePair[] array, int arrayIndex) { } - public System.Collections.Generic.IEnumerator> GetEnumerator() { } - public bool Remove(System.Collections.Generic.KeyValuePair item) { } - public bool Remove(string key) { } - public bool TryGetValue(string key, [System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)] out BililiveRecorder.Flv.Amf.IScriptDataValue value) { } - public void WriteTo(System.IO.Stream stream) { } - public static BililiveRecorder.Flv.Amf.ScriptDataObject op_Implicit(BililiveRecorder.Flv.Amf.ScriptDataEcmaArray ecmaArray) { } - public static System.Collections.Generic.Dictionary op_Implicit(BililiveRecorder.Flv.Amf.ScriptDataObject @object) { } - public static BililiveRecorder.Flv.Amf.ScriptDataObject op_Implicit(System.Collections.Generic.Dictionary @object) { } - } - [System.Diagnostics.DebuggerDisplay("AmfReference, {Value}")] - public class ScriptDataReference : BililiveRecorder.Flv.Amf.IScriptDataValue - { - public ScriptDataReference() { } - public BililiveRecorder.Flv.Amf.ScriptDataType Type { get; } - [Newtonsoft.Json.JsonProperty] - public ushort Value { get; set; } - public override bool Equals(object? obj) { } - public override int GetHashCode() { } - public void WriteTo(System.IO.Stream stream) { } - public static ushort op_Implicit(BililiveRecorder.Flv.Amf.ScriptDataReference reference) { } - public static BililiveRecorder.Flv.Amf.ScriptDataReference op_Implicit(ushort number) { } - public static bool operator !=(BililiveRecorder.Flv.Amf.ScriptDataReference left, BililiveRecorder.Flv.Amf.ScriptDataReference right) { } - public static bool operator ==(BililiveRecorder.Flv.Amf.ScriptDataReference left, BililiveRecorder.Flv.Amf.ScriptDataReference right) { } - } - [System.Diagnostics.DebuggerDisplay("AmfStrictArray, Count = {Count}")] - [System.Diagnostics.DebuggerTypeProxy(typeof(BililiveRecorder.Flv.Amf.AmfCollectionDebugView))] - public class ScriptDataStrictArray : BililiveRecorder.Flv.Amf.IScriptDataValue, System.Collections.Generic.ICollection, System.Collections.Generic.IEnumerable, System.Collections.Generic.IList, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IReadOnlyList, System.Collections.IEnumerable - { - public ScriptDataStrictArray() { } - public int Count { get; } - public bool IsReadOnly { get; } - public BililiveRecorder.Flv.Amf.IScriptDataValue this[int index] { get; set; } - public BililiveRecorder.Flv.Amf.ScriptDataType Type { get; } - [Newtonsoft.Json.JsonProperty] - public System.Collections.Generic.List Value { get; set; } - public void Add(BililiveRecorder.Flv.Amf.IScriptDataValue item) { } - public void Clear() { } - public bool Contains(BililiveRecorder.Flv.Amf.IScriptDataValue item) { } - public void CopyTo(BililiveRecorder.Flv.Amf.IScriptDataValue[] array, int arrayIndex) { } - public System.Collections.Generic.IEnumerator GetEnumerator() { } - public int IndexOf(BililiveRecorder.Flv.Amf.IScriptDataValue item) { } - public void Insert(int index, BililiveRecorder.Flv.Amf.IScriptDataValue item) { } - public bool Remove(BililiveRecorder.Flv.Amf.IScriptDataValue item) { } - public void RemoveAt(int index) { } - public void WriteTo(System.IO.Stream stream) { } - public static System.Collections.Generic.List op_Implicit(BililiveRecorder.Flv.Amf.ScriptDataStrictArray strictArray) { } - public static BililiveRecorder.Flv.Amf.ScriptDataStrictArray op_Implicit(System.Collections.Generic.List values) { } - } - [System.Diagnostics.DebuggerDisplay("AmfString, {Value}")] - public class ScriptDataString : BililiveRecorder.Flv.Amf.IScriptDataValue - { - public ScriptDataString() { } - public BililiveRecorder.Flv.Amf.ScriptDataType Type { get; } - [Newtonsoft.Json.JsonProperty(Required=Newtonsoft.Json.Required.Always)] - public string Value { get; set; } - public override bool Equals(object? obj) { } - public override int GetHashCode() { } - public void WriteTo(System.IO.Stream stream) { } - public static BililiveRecorder.Flv.Amf.ScriptDataString op_Implicit(BililiveRecorder.Flv.Amf.ScriptDataLongString @string) { } - public static string op_Implicit(BililiveRecorder.Flv.Amf.ScriptDataString @string) { } - public static BililiveRecorder.Flv.Amf.ScriptDataString op_Implicit(string @string) { } - public static bool operator !=(BililiveRecorder.Flv.Amf.ScriptDataString left, BililiveRecorder.Flv.Amf.ScriptDataString right) { } - public static bool operator ==(BililiveRecorder.Flv.Amf.ScriptDataString left, BililiveRecorder.Flv.Amf.ScriptDataString right) { } - } - [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] - public enum ScriptDataType : byte - { - Number = 0, - Boolean = 1, - String = 2, - Object = 3, - MovieClip = 4, - Null = 5, - Undefined = 6, - Reference = 7, - EcmaArray = 8, - ObjectEndMarker = 9, - StrictArray = 10, - Date = 11, - LongString = 12, - } - [System.Diagnostics.DebuggerDisplay("AmfUndefined")] - public class ScriptDataUndefined : BililiveRecorder.Flv.Amf.IScriptDataValue - { - public ScriptDataUndefined() { } - public BililiveRecorder.Flv.Amf.ScriptDataType Type { get; } - public override bool Equals(object? obj) { } - public override int GetHashCode() { } - public void WriteTo(System.IO.Stream stream) { } - public static bool operator !=(BililiveRecorder.Flv.Amf.ScriptDataUndefined left, BililiveRecorder.Flv.Amf.ScriptDataUndefined right) { } - public static bool operator ==(BililiveRecorder.Flv.Amf.ScriptDataUndefined left, BililiveRecorder.Flv.Amf.ScriptDataUndefined right) { } - } - public class ScriptTagBody : System.Xml.Serialization.IXmlSerializable - { - public ScriptTagBody() { } - public ScriptTagBody(System.Collections.Generic.List values) { } - public System.Collections.Generic.List Values { get; set; } - public byte[] ToBytes() { } - public string ToJson() { } - public void WriteTo(System.IO.Stream stream) { } - public static BililiveRecorder.Flv.Amf.ScriptTagBody Parse(BililiveRecorder.Flv.Parser.BigEndianBinaryReader binaryReader) { } - public static BililiveRecorder.Flv.Amf.ScriptTagBody Parse(byte[] bytes) { } - public static BililiveRecorder.Flv.Amf.ScriptTagBody Parse(System.IO.Stream stream) { } - public static BililiveRecorder.Flv.Amf.ScriptTagBody Parse(string json) { } - public static BililiveRecorder.Flv.Amf.IScriptDataValue ParseValue(BililiveRecorder.Flv.Parser.BigEndianBinaryReader binaryReader) { } - } - public static class ScriptTagBodyExtensions - { - public static BililiveRecorder.Flv.Amf.ScriptDataEcmaArray? GetMetadataValue(this BililiveRecorder.Flv.Amf.ScriptTagBody body) { } - } -} -namespace BililiveRecorder.Flv -{ - public class DefaultMemoryStreamProvider : BililiveRecorder.Flv.IMemoryStreamProvider - { - public DefaultMemoryStreamProvider() { } - public System.IO.MemoryStream CreateMemoryStream(string tag) { } - } - public class FileClosedEventArgs : System.EventArgs - { - public FileClosedEventArgs() { } - public double Duration { get; set; } - public long FileSize { get; set; } - public object? State { get; set; } - } - public sealed class H264Nalu - { - public H264Nalu(int startPosition, uint fullSize, BililiveRecorder.Flv.H264NaluType type) { } - [System.Xml.Serialization.XmlAttribute] - public uint FullSize { get; set; } - [System.Xml.Serialization.XmlAttribute] - public string? NaluHash { get; set; } - [System.Xml.Serialization.XmlAttribute] - public int StartPosition { get; set; } - [System.Xml.Serialization.XmlAttribute] - public BililiveRecorder.Flv.H264NaluType Type { get; set; } - public static bool TryParseNalu(System.IO.Stream data, [System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out System.Collections.Generic.List? h264Nalus) { } - public static bool TryParseNaluType(byte firstByte, out BililiveRecorder.Flv.H264NaluType h264NaluType) { } - } - public enum H264NaluType : byte - { - Unspecified0 = 0, - CodedSliceOfANonIdrPicture = 1, - CodedSliceDataPartitionA = 2, - CodedSliceDataPartitionB = 3, - CodedSliceDataPartitionC = 4, - CodedSliceOfAnIdrPicture = 5, - Sei = 6, - Sps = 7, - Pps = 8, - AccessUnitDelimiter = 9, - EndOfSequence = 10, - EndOfStream = 11, - FillerData = 12, - SpsExtension = 13, - PrefixNalUnit = 14, - SubsetSps = 15, - DepthParameterSet = 16, - Reserved17 = 17, - Reserved18 = 18, - SliceLayerWithoutPartitioning = 19, - SliceLayerExtension20 = 20, - SliceLayerExtension21 = 21, - Reserved22 = 22, - Reserved23 = 23, - Unspecified24 = 24, - Unspecified25 = 25, - Unspecified23 = 23, - Unspecified27 = 27, - Unspecified28 = 28, - Unspecified29 = 29, - Unspecified30 = 30, - Unspecified31 = 31, - } - public interface IFlvProcessingContextWriter : System.IDisposable - { - System.Action? BeforeScriptTagRewrite { get; set; } - System.Action? BeforeScriptTagWrite { get; set; } - event System.EventHandler FileClosed; - System.Threading.Tasks.Task WriteAsync(BililiveRecorder.Flv.Pipeline.FlvProcessingContext context); - } - public interface IFlvTagReader : System.IDisposable - { - System.Threading.Tasks.Task PeekTagAsync(System.Threading.CancellationToken token); - System.Threading.Tasks.Task ReadTagAsync(System.Threading.CancellationToken token); - } - public interface IFlvTagWriter : System.IDisposable - { - long FileSize { get; } - object? State { get; } - bool CloseCurrentFile(); - System.Threading.Tasks.Task CreateNewFile(); - System.Threading.Tasks.Task OverwriteMetadata(BililiveRecorder.Flv.Amf.ScriptTagBody metadata); - System.Threading.Tasks.Task WriteAccompanyingTextLog(double lastTagDuration, string message); - System.Threading.Tasks.Task WriteTag(BililiveRecorder.Flv.Tag tag); - } - public interface IFlvWriterTargetProvider - { - System.IO.Stream CreateAccompanyingTextLogStream(); - [return: System.Runtime.CompilerServices.TupleElementNames(new string[] { - "stream", - "state"})] - System.ValueTuple CreateOutputStream(); - } - public interface IGroupingRule - { - bool CanAppendWith(BililiveRecorder.Flv.Tag tag, System.Collections.Generic.List tags); - bool CanStartWith(BililiveRecorder.Flv.Tag tag); - BililiveRecorder.Flv.Pipeline.Actions.PipelineAction CreatePipelineAction(System.Collections.Generic.List tags); - } - public interface IMemoryStreamProvider - { - System.IO.MemoryStream CreateMemoryStream(string tag); - } - public interface ITagGroupReader : System.IDisposable - { - System.Threading.Tasks.Task ReadGroupAsync(System.Threading.CancellationToken token); - } - public interface ITwoInputFunction - { - TOut Eval(TIn a, TIn b); - } - public static class LinqExtensions - { - public static bool Any2(this System.Collections.Generic.IEnumerable source, System.Func predicate) { } - public static bool Any2(this System.Collections.Generic.IEnumerable source, ref TFunction function) - where TFunction : BililiveRecorder.Flv.ITwoInputFunction { } - } - public static class LinqFunctions - { - public static BililiveRecorder.Flv.LinqFunctions.CountAudioTagsStruct CountAudioTags; - public static BililiveRecorder.Flv.LinqFunctions.CountVideoTagsStruct CountVideoTags; - public static BililiveRecorder.Flv.LinqFunctions.SumSizeOfAudioDataStruct SumSizeOfAudioData; - public static BililiveRecorder.Flv.LinqFunctions.SumSizeOfNaluStruct SumSizeOfNalu; - public static BililiveRecorder.Flv.LinqFunctions.SumSizeOfTagByPropertyStruct SumSizeOfTagByProperty; - public static BililiveRecorder.Flv.LinqFunctions.SumSizeOfTagByPropertyOrNaluStruct SumSizeOfTagByPropertyOrNalu; - public static BililiveRecorder.Flv.LinqFunctions.SumSizeOfVideoDataStruct SumSizeOfVideoData; - public static BililiveRecorder.Flv.LinqFunctions.SumSizeOfVideoDataByNaluStruct SumSizeOfVideoDataByNalu; - public static BililiveRecorder.Flv.LinqFunctions.TagIsAudioStruct TagIsAudio; - public static BililiveRecorder.Flv.LinqFunctions.TagIsDataStruct TagIsData; - public static BililiveRecorder.Flv.LinqFunctions.TagIsHeaderStruct TagIsHeader; - public static BililiveRecorder.Flv.LinqFunctions.TagIsVideoStruct TagIsVideo; - public readonly struct CountAudioTagsStruct : StructLinq.IFunction, StructLinq.IInFunction - { - public int Eval(BililiveRecorder.Flv.Pipeline.Actions.PipelineDataAction element) { } - public int Eval(in BililiveRecorder.Flv.Pipeline.Actions.PipelineDataAction element) { } - } - public readonly struct CountVideoTagsStruct : StructLinq.IFunction, StructLinq.IInFunction - { - public int Eval(BililiveRecorder.Flv.Pipeline.Actions.PipelineDataAction element) { } - public int Eval(in BililiveRecorder.Flv.Pipeline.Actions.PipelineDataAction element) { } - } - public readonly struct SumSizeOfAudioDataStruct : StructLinq.IFunction, StructLinq.IInFunction - { - public long Eval(BililiveRecorder.Flv.Pipeline.Actions.PipelineDataAction element) { } - public long Eval(in BililiveRecorder.Flv.Pipeline.Actions.PipelineDataAction element) { } - } - public readonly struct SumSizeOfNaluStruct : StructLinq.IFunction, StructLinq.IInFunction - { - public long Eval(BililiveRecorder.Flv.H264Nalu element) { } - public long Eval(in BililiveRecorder.Flv.H264Nalu element) { } - } - public readonly struct SumSizeOfTagByPropertyOrNaluStruct : StructLinq.IFunction, StructLinq.IInFunction - { - public long Eval(BililiveRecorder.Flv.Tag element) { } - public long Eval(in BililiveRecorder.Flv.Tag element) { } - } - public readonly struct SumSizeOfTagByPropertyStruct : StructLinq.IFunction, StructLinq.IInFunction - { - public long Eval(BililiveRecorder.Flv.Tag element) { } - public long Eval(in BililiveRecorder.Flv.Tag element) { } - } - public readonly struct SumSizeOfVideoDataByNaluStruct : StructLinq.IFunction, StructLinq.IInFunction - { - public long Eval(BililiveRecorder.Flv.Pipeline.Actions.PipelineDataAction element) { } - public long Eval(in BililiveRecorder.Flv.Pipeline.Actions.PipelineDataAction element) { } - } - public readonly struct SumSizeOfVideoDataStruct : StructLinq.IFunction, StructLinq.IInFunction - { - public long Eval(BililiveRecorder.Flv.Pipeline.Actions.PipelineDataAction element) { } - public long Eval(in BililiveRecorder.Flv.Pipeline.Actions.PipelineDataAction element) { } - } - public readonly struct TagIsAudioStruct : StructLinq.IFunction, StructLinq.IInFunction - { - public bool Eval(BililiveRecorder.Flv.Tag element) { } - public bool Eval(in BililiveRecorder.Flv.Tag element) { } - } - public readonly struct TagIsDataStruct : StructLinq.IFunction, StructLinq.IInFunction - { - public bool Eval(BililiveRecorder.Flv.Tag element) { } - public bool Eval(in BililiveRecorder.Flv.Tag element) { } - } - public readonly struct TagIsHeaderStruct : StructLinq.IFunction, StructLinq.IInFunction - { - public bool Eval(BililiveRecorder.Flv.Tag element) { } - public bool Eval(in BililiveRecorder.Flv.Tag element) { } - } - public readonly struct TagIsVideoStruct : StructLinq.IFunction, StructLinq.IInFunction - { - public bool Eval(BililiveRecorder.Flv.Tag element) { } - public bool Eval(in BililiveRecorder.Flv.Tag element) { } - } - } - [System.Diagnostics.DebuggerDisplay("{DebuggerDisplay,nq}")] - public sealed class Tag : System.ICloneable - { - public Tag() { } - [System.Xml.Serialization.XmlIgnore] - public System.IO.MemoryStream? BinaryData { get; set; } - [System.Xml.Serialization.XmlElement("BinaryData")] - public string? BinaryDataForSerializationUseOnly { get; set; } - [System.Xml.Serialization.XmlAttribute] - public string? DataHash { get; set; } - [System.Xml.Serialization.XmlElement] - public BililiveRecorder.Flv.TagExtraData? ExtraData { get; set; } - [System.ComponentModel.DefaultValue(BililiveRecorder.Flv.TagFlag.None)] - [System.Xml.Serialization.XmlAttribute] - public BililiveRecorder.Flv.TagFlag Flag { get; set; } - [System.Xml.Serialization.XmlIgnore] - public long Index { get; set; } - [System.Xml.Serialization.XmlElement] - public System.Collections.Generic.List? Nalus { get; set; } - [System.Xml.Serialization.XmlElement] - public BililiveRecorder.Flv.Amf.ScriptTagBody? ScriptData { get; set; } - [System.Xml.Serialization.XmlAttribute] - public uint Size { get; set; } - [System.Xml.Serialization.XmlAttribute] - public int Timestamp { get; set; } - [System.Xml.Serialization.XmlAttribute] - public BililiveRecorder.Flv.TagType Type { get; set; } - public BililiveRecorder.Flv.Tag Clone() { } - public BililiveRecorder.Flv.Tag Clone(BililiveRecorder.Flv.IMemoryStreamProvider? provider = null) { } - public bool ShouldSerializeBinaryDataForSerializationUseOnly() { } - public bool ShouldSerializeNalus() { } - public bool ShouldSerializeScriptData() { } - public override string ToString() { } - public string? UpdateDataHash() { } - public BililiveRecorder.Flv.TagExtraData? UpdateExtraData() { } - } - public static class TagExtentions - { - public static bool IsData(this BililiveRecorder.Flv.Tag tag) { } - public static bool IsEnd(this BililiveRecorder.Flv.Tag tag) { } - public static bool IsHeader(this BililiveRecorder.Flv.Tag tag) { } - public static bool IsKeyframeData(this BililiveRecorder.Flv.Tag tag) { } - public static bool IsNonKeyframeData(this BililiveRecorder.Flv.Tag tag) { } - public static bool IsScript(this BililiveRecorder.Flv.Tag tag) { } - public static System.Threading.Tasks.Task WriteTo(this BililiveRecorder.Flv.Tag tag, System.IO.Stream target, int timestamp, BililiveRecorder.Flv.IMemoryStreamProvider? memoryStreamProvider = null) { } - } - public sealed class TagExtraData - { - public TagExtraData() { } - [System.Xml.Serialization.XmlAttribute] - public int CompositionTime { get; set; } - [System.Xml.Serialization.XmlAttribute] - public int FinalTime { get; set; } - [System.Xml.Serialization.XmlAttribute] - public string FirstBytes { get; set; } - public bool ShouldSerializeCompositionTime() { } - public bool ShouldSerializeFinalTime() { } - } - [System.Flags] - public enum TagFlag - { - None = 0, - Header = 1, - Keyframe = 2, - End = 4, - } - public enum TagType - { - Unknown = 0, - Audio = 8, - Video = 9, - Script = 18, - } -} -namespace BililiveRecorder.Flv.Grouping.Rules -{ - public class DataGroupingRule : BililiveRecorder.Flv.IGroupingRule - { - public DataGroupingRule() { } - public bool CanAppendWith(BililiveRecorder.Flv.Tag tag, System.Collections.Generic.List tags) { } - public bool CanStartWith(BililiveRecorder.Flv.Tag tag) { } - public BililiveRecorder.Flv.Pipeline.Actions.PipelineAction CreatePipelineAction(System.Collections.Generic.List tags) { } - } - public class EndGroupingRule : BililiveRecorder.Flv.IGroupingRule - { - public EndGroupingRule() { } - public bool CanAppendWith(BililiveRecorder.Flv.Tag tag, System.Collections.Generic.List tags) { } - public bool CanStartWith(BililiveRecorder.Flv.Tag tag) { } - public BililiveRecorder.Flv.Pipeline.Actions.PipelineAction CreatePipelineAction(System.Collections.Generic.List tags) { } - } - public class HeaderGroupingRule : BililiveRecorder.Flv.IGroupingRule - { - public HeaderGroupingRule() { } - public bool CanAppendWith(BililiveRecorder.Flv.Tag tag, System.Collections.Generic.List tags) { } - public bool CanStartWith(BililiveRecorder.Flv.Tag tag) { } - public BililiveRecorder.Flv.Pipeline.Actions.PipelineAction CreatePipelineAction(System.Collections.Generic.List tags) { } - } - public class ScriptGroupingRule : BililiveRecorder.Flv.IGroupingRule - { - public ScriptGroupingRule() { } - public bool CanAppendWith(BililiveRecorder.Flv.Tag tag, System.Collections.Generic.List tags) { } - public bool CanStartWith(BililiveRecorder.Flv.Tag tag) { } - public BililiveRecorder.Flv.Pipeline.Actions.PipelineAction CreatePipelineAction(System.Collections.Generic.List tags) { } - } -} -namespace BililiveRecorder.Flv.Grouping -{ - public class TagGroupReader : BililiveRecorder.Flv.ITagGroupReader, System.IDisposable - { - public TagGroupReader(BililiveRecorder.Flv.IFlvTagReader tagReader) { } - public TagGroupReader(BililiveRecorder.Flv.IFlvTagReader flvTagReader, bool leaveOpen = false) { } - public System.Collections.Generic.IList GroupingRules { get; } - public BililiveRecorder.Flv.IFlvTagReader TagReader { get; } - public void Dispose() { } - protected virtual void Dispose(bool disposing) { } - public System.Threading.Tasks.Task ReadGroupAsync(System.Threading.CancellationToken token) { } - } -} -namespace BililiveRecorder.Flv.Parser -{ - public class BigEndianBinaryReader : System.IO.BinaryReader - { - public BigEndianBinaryReader(System.IO.Stream input) { } - public BigEndianBinaryReader(System.IO.Stream input, System.Text.Encoding encoding) { } - public BigEndianBinaryReader(System.IO.Stream input, System.Text.Encoding encoding, bool leaveOpen) { } - public override System.IO.Stream BaseStream { get; } - public override void Close() { } - protected override void Dispose(bool disposing) { } - public override bool Equals(object? obj) { } - protected override void FillBuffer(int numBytes) { } - public override int GetHashCode() { } - public override int PeekChar() { } - public override int Read() { } - public override int Read(byte[] buffer, int index, int count) { } - public override int Read(char[] buffer, int index, int count) { } - public override bool ReadBoolean() { } - public override byte ReadByte() { } - public override byte[] ReadBytes(int count) { } - public override char ReadChar() { } - public override char[] ReadChars(int count) { } - public override decimal ReadDecimal() { } - public override double ReadDouble() { } - public override short ReadInt16() { } - public override int ReadInt32() { } - public override long ReadInt64() { } - public override sbyte ReadSByte() { } - public override float ReadSingle() { } - public override string ReadString() { } - public override ushort ReadUInt16() { } - public override uint ReadUInt32() { } - public override ulong ReadUInt64() { } - public override string? ToString() { } - } - public class FlvException : System.Exception - { - public FlvException() { } - public FlvException(string message) { } - protected FlvException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public FlvException(string message, System.Exception innerException) { } - } - public class FlvTagPipeReader : BililiveRecorder.Flv.IFlvTagReader, System.IDisposable - { - public FlvTagPipeReader(System.IO.Pipelines.PipeReader reader, BililiveRecorder.Flv.IMemoryStreamProvider memoryStreamProvider, Serilog.ILogger? logger = null) { } - public FlvTagPipeReader(System.IO.Pipelines.PipeReader reader, BililiveRecorder.Flv.IMemoryStreamProvider memoryStreamProvider, bool skipData = false, Serilog.ILogger? logger = null) { } - public FlvTagPipeReader(System.IO.Pipelines.PipeReader reader, BililiveRecorder.Flv.IMemoryStreamProvider memoryStreamProvider, bool skipData = false, bool leaveOpen = false, Serilog.ILogger? logger = null) { } - public System.IO.Pipelines.PipeReader Reader { get; } - public void Dispose() { } - public System.Threading.Tasks.Task PeekTagAsync(System.Threading.CancellationToken token) { } - public System.Threading.Tasks.Task ReadTagAsync(System.Threading.CancellationToken token) { } - } - public class NotFlvFileException : BililiveRecorder.Flv.Parser.FlvException - { - public NotFlvFileException() { } - public NotFlvFileException(string message) { } - protected NotFlvFileException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public NotFlvFileException(string message, System.Exception innerException) { } - } - public class UnknownFlvTagTypeException : BililiveRecorder.Flv.Parser.FlvException - { - public UnknownFlvTagTypeException() { } - public UnknownFlvTagTypeException(string message) { } - protected UnknownFlvTagTypeException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public UnknownFlvTagTypeException(string message, System.Exception innerException) { } - } - public class UnsupportedCodecException : BililiveRecorder.Flv.Parser.FlvException - { - public UnsupportedCodecException() { } - public UnsupportedCodecException(string message) { } - protected UnsupportedCodecException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } - public UnsupportedCodecException(string message, System.Exception innerException) { } - } -} -namespace BililiveRecorder.Flv.Pipeline.Actions -{ - public abstract class PipelineAction - { - protected PipelineAction() { } - public string Name { get; } - public abstract BililiveRecorder.Flv.Pipeline.Actions.PipelineAction Clone(); - } - public class PipelineDataAction : BililiveRecorder.Flv.Pipeline.Actions.PipelineAction - { - public PipelineDataAction(System.Collections.Generic.IReadOnlyList tags) { } - public System.Collections.Generic.IReadOnlyList Tags { get; set; } - public override BililiveRecorder.Flv.Pipeline.Actions.PipelineAction Clone() { } - } - public class PipelineDisconnectAction : BililiveRecorder.Flv.Pipeline.Actions.PipelineAction - { - 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 - { - public PipelineEndAction(BililiveRecorder.Flv.Tag tag) { } - public BililiveRecorder.Flv.Tag Tag { get; set; } - public override BililiveRecorder.Flv.Pipeline.Actions.PipelineAction Clone() { } - } - public class PipelineHeaderAction : BililiveRecorder.Flv.Pipeline.Actions.PipelineAction - { - public PipelineHeaderAction(System.Collections.Generic.IReadOnlyList allTags) { } - public System.Collections.Generic.IReadOnlyList AllTags { get; set; } - public BililiveRecorder.Flv.Tag? AudioHeader { get; set; } - public BililiveRecorder.Flv.Tag? VideoHeader { get; set; } - public override BililiveRecorder.Flv.Pipeline.Actions.PipelineAction Clone() { } - } - public class PipelineLogMessageWithLocationAction : BililiveRecorder.Flv.Pipeline.Actions.PipelineAction - { - public PipelineLogMessageWithLocationAction(string message) { } - public string Message { get; } - public override BililiveRecorder.Flv.Pipeline.Actions.PipelineAction Clone() { } - } - public class PipelineNewFileAction : BililiveRecorder.Flv.Pipeline.Actions.PipelineAction - { - public static readonly BililiveRecorder.Flv.Pipeline.Actions.PipelineNewFileAction Instance; - public PipelineNewFileAction() { } - public override BililiveRecorder.Flv.Pipeline.Actions.PipelineAction Clone() { } - } - public class PipelineScriptAction : BililiveRecorder.Flv.Pipeline.Actions.PipelineAction - { - public PipelineScriptAction(BililiveRecorder.Flv.Tag tag) { } - public BililiveRecorder.Flv.Tag Tag { get; set; } - public override BililiveRecorder.Flv.Pipeline.Actions.PipelineAction Clone() { } - } -} -namespace BililiveRecorder.Flv.Pipeline -{ - public enum CommentType - { - Other = 0, - Logging = 1, - Unrepairable = 2, - TimestampJump = 3, - TimestampOffset = 4, - DecodingHeader = 5, - RepeatingData = 6, - OnMetaData = 7, - } - public class FlvProcessingContext - { - public FlvProcessingContext() { } - public FlvProcessingContext(BililiveRecorder.Flv.Pipeline.Actions.PipelineAction data, System.Collections.Generic.IDictionary sessionItems) { } - public System.Collections.Generic.List Actions { get; set; } - public System.Collections.Generic.List Comments { get; } - public System.Collections.Generic.IDictionary LocalItems { get; } - public System.Collections.Generic.IDictionary SessionItems { get; } - public void Reset(BililiveRecorder.Flv.Pipeline.Actions.PipelineAction action, System.Collections.Generic.IDictionary sessionItems) { } - public void Reset(System.Collections.Generic.List actions, System.Collections.Generic.IDictionary sessionItems) { } - } - public static class FlvProcessingContextExtensions - { - public static void AddComment(this BililiveRecorder.Flv.Pipeline.FlvProcessingContext context, BililiveRecorder.Flv.Pipeline.ProcessingComment comment) { } - public static bool PerActionRun(this BililiveRecorder.Flv.Pipeline.FlvProcessingContext context, System.Func> func) { } - } - public interface IFullProcessingRule : BililiveRecorder.Flv.Pipeline.IProcessingRule - { - void Run(BililiveRecorder.Flv.Pipeline.FlvProcessingContext context, BililiveRecorder.Flv.Pipeline.ProcessingDelegate next); - } - public interface IProcessingPipelineBuilder - { - Microsoft.Extensions.DependencyInjection.IServiceCollection ServiceCollection { get; } - BililiveRecorder.Flv.Pipeline.IProcessingPipelineBuilder AddRule(System.Func rule); - BililiveRecorder.Flv.Pipeline.ProcessingDelegate Build(); - } - public static class IProcessingPipelineBuilderExtensions - { - public static BililiveRecorder.Flv.Pipeline.IProcessingPipelineBuilder AddDefaultRules(this BililiveRecorder.Flv.Pipeline.IProcessingPipelineBuilder builder) { } - public static BililiveRecorder.Flv.Pipeline.IProcessingPipelineBuilder AddRemoveFillerDataRule(this BililiveRecorder.Flv.Pipeline.IProcessingPipelineBuilder builder) { } - public static BililiveRecorder.Flv.Pipeline.IProcessingPipelineBuilder AddRule(this BililiveRecorder.Flv.Pipeline.IProcessingPipelineBuilder builder) - where T : BililiveRecorder.Flv.Pipeline.IProcessingRule { } - public static BililiveRecorder.Flv.Pipeline.IProcessingPipelineBuilder AddRule(this BililiveRecorder.Flv.Pipeline.IProcessingPipelineBuilder builder, T instance) - where T : BililiveRecorder.Flv.Pipeline.IProcessingRule { } - public static BililiveRecorder.Flv.Pipeline.IProcessingPipelineBuilder ConfigureServices(this BililiveRecorder.Flv.Pipeline.IProcessingPipelineBuilder builder, System.Action configure) { } - } - public interface IProcessingRule { } - public interface ISimpleProcessingRule : BililiveRecorder.Flv.Pipeline.IProcessingRule - { - void Run(BililiveRecorder.Flv.Pipeline.FlvProcessingContext context, System.Action next); - } - public class ProcessingComment - { - 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); - public class ProcessingPipelineBuilder : BililiveRecorder.Flv.Pipeline.IProcessingPipelineBuilder - { - public ProcessingPipelineBuilder() { } - public ProcessingPipelineBuilder(Microsoft.Extensions.DependencyInjection.IServiceCollection servicesCollection) { } - public Microsoft.Extensions.DependencyInjection.IServiceCollection ServiceCollection { get; } - public BililiveRecorder.Flv.Pipeline.IProcessingPipelineBuilder AddRule(System.Func rule) { } - public BililiveRecorder.Flv.Pipeline.ProcessingDelegate Build() { } - } - public class ProcessingPipelineSettings - { - public ProcessingPipelineSettings() { } - public bool SplitOnScriptTag { get; set; } - } -} -namespace BililiveRecorder.Flv.Pipeline.Rules -{ - public class FfmpegDetectionRule : BililiveRecorder.Flv.Pipeline.IProcessingRule, BililiveRecorder.Flv.Pipeline.ISimpleProcessingRule - { - public FfmpegDetectionRule() { } - public bool EndTagDetected { get; } - public bool LavfEncoderDetected { get; } - public void Run(BililiveRecorder.Flv.Pipeline.FlvProcessingContext context, System.Action next) { } - } - public class HandleDelayedAudioHeaderRule : BililiveRecorder.Flv.Pipeline.IProcessingRule, BililiveRecorder.Flv.Pipeline.ISimpleProcessingRule - { - public HandleDelayedAudioHeaderRule() { } - public void Run(BililiveRecorder.Flv.Pipeline.FlvProcessingContext context, System.Action next) { } - } - public class HandleEndTagRule : BililiveRecorder.Flv.Pipeline.IProcessingRule, BililiveRecorder.Flv.Pipeline.ISimpleProcessingRule - { - public HandleEndTagRule() { } - public void Run(BililiveRecorder.Flv.Pipeline.FlvProcessingContext context, System.Action next) { } - } - public class HandleNewHeaderRule : BililiveRecorder.Flv.Pipeline.IProcessingRule, BililiveRecorder.Flv.Pipeline.ISimpleProcessingRule - { - public HandleNewHeaderRule() { } - public void Run(BililiveRecorder.Flv.Pipeline.FlvProcessingContext context, System.Action next) { } - } - public class HandleNewScriptRule : BililiveRecorder.Flv.Pipeline.IProcessingRule, BililiveRecorder.Flv.Pipeline.ISimpleProcessingRule - { - public HandleNewScriptRule(BililiveRecorder.Flv.Pipeline.ProcessingPipelineSettings? processingPipelineSettings) { } - public void Run(BililiveRecorder.Flv.Pipeline.FlvProcessingContext context, System.Action next) { } - } - public class RemoveDuplicatedChunkRule : BililiveRecorder.Flv.Pipeline.IProcessingRule, BililiveRecorder.Flv.Pipeline.ISimpleProcessingRule - { - public RemoveDuplicatedChunkRule() { } - public void Run(BililiveRecorder.Flv.Pipeline.FlvProcessingContext context, System.Action next) { } - } - public class RemoveFillerDataRule : BililiveRecorder.Flv.Pipeline.IProcessingRule, BililiveRecorder.Flv.Pipeline.ISimpleProcessingRule - { - public RemoveFillerDataRule() { } - public void Run(BililiveRecorder.Flv.Pipeline.FlvProcessingContext context, System.Action next) { } - } - public class UpdateTimestampJumpRule : BililiveRecorder.Flv.Pipeline.IProcessingRule, BililiveRecorder.Flv.Pipeline.ISimpleProcessingRule - { - public UpdateTimestampJumpRule() { } - public void Run(BililiveRecorder.Flv.Pipeline.FlvProcessingContext context, System.Action next) { } - } - public class UpdateTimestampOffsetRule : BililiveRecorder.Flv.Pipeline.IProcessingRule, BililiveRecorder.Flv.Pipeline.ISimpleProcessingRule - { - public UpdateTimestampOffsetRule() { } - public void Run(BililiveRecorder.Flv.Pipeline.FlvProcessingContext context, System.Action next) { } - } -} -namespace BililiveRecorder.Flv.Writer -{ - public class FlvProcessingContextWriter : BililiveRecorder.Flv.IFlvProcessingContextWriter, System.IDisposable - { - public FlvProcessingContextWriter(BililiveRecorder.Flv.IFlvTagWriter tagWriter, bool allowMissingHeader, bool disableKeyframes, Serilog.ILogger? logger) { } - public System.Action? BeforeScriptTagRewrite { get; set; } - public System.Action? BeforeScriptTagWrite { get; set; } - public event System.EventHandler? FileClosed; - public void Dispose() { } - protected virtual void Dispose(bool disposing) { } - public System.Threading.Tasks.Task WriteAsync(BililiveRecorder.Flv.Pipeline.FlvProcessingContext context) { } - } - public class FlvTagFileWriter : BililiveRecorder.Flv.IFlvTagWriter, System.IDisposable - { - public FlvTagFileWriter(BililiveRecorder.Flv.IFlvWriterTargetProvider targetProvider, BililiveRecorder.Flv.IMemoryStreamProvider memoryStreamProvider, Serilog.ILogger? logger) { } - public long FileSize { get; } - public object? State { get; } - public bool CloseCurrentFile() { } - public System.Threading.Tasks.Task CreateNewFile() { } - public void Dispose() { } - protected virtual void Dispose(bool disposing) { } - public System.Threading.Tasks.Task OverwriteMetadata(BililiveRecorder.Flv.Amf.ScriptTagBody metadata) { } - public System.Threading.Tasks.Task WriteAccompanyingTextLog(double lastTagDuration, string message) { } - public System.Threading.Tasks.Task WriteTag(BililiveRecorder.Flv.Tag tag) { } - } - public class FlvTagListWriter : BililiveRecorder.Flv.IFlvTagWriter, System.IDisposable - { - public FlvTagListWriter() { } - [System.Runtime.CompilerServices.TupleElementNames(new string[] { - "lastTagDuration", - "message"})] - public System.Collections.Generic.List> AccompanyingTextLogs { get; } - public long FileSize { get; } - public System.Collections.Generic.List> Files { get; } - public object? State { get; } - public bool CloseCurrentFile() { } - public System.Threading.Tasks.Task CreateNewFile() { } - public void Dispose() { } - public System.Threading.Tasks.Task OverwriteMetadata(BililiveRecorder.Flv.Amf.ScriptTagBody metadata) { } - public System.Threading.Tasks.Task WriteAccompanyingTextLog(double lastTagDuration, string message) { } - public System.Threading.Tasks.Task WriteTag(BililiveRecorder.Flv.Tag tag) { } - } -} -namespace BililiveRecorder.Flv.Xml -{ - public class FlvTagListReader : BililiveRecorder.Flv.IFlvTagReader, System.IDisposable - { - public FlvTagListReader(System.Collections.Generic.IReadOnlyList tags) { } - public void Dispose() { } - public System.Threading.Tasks.Task PeekTagAsync(System.Threading.CancellationToken token) { } - public System.Threading.Tasks.Task ReadTagAsync(System.Threading.CancellationToken token) { } - } - [System.Xml.Serialization.XmlRoot("BililiveRecorderFlv")] - public class XmlFlvFile - { - public XmlFlvFile() { } - public BililiveRecorder.Flv.Xml.XmlFlvFile.XmlFlvFileMeta? Meta { get; set; } - public System.Collections.Generic.List Tags { get; set; } - public static System.Xml.Serialization.XmlSerializer Serializer { get; } - public class XmlFlvFileMeta - { - public XmlFlvFileMeta() { } - [System.Xml.Serialization.XmlIgnore] - public System.DateTimeOffset ExportTime { get; set; } - [System.Xml.Serialization.XmlElement("ExportTime")] - public string ExportTimeForXml { get; set; } - [System.Xml.Serialization.XmlIgnore] - public System.DateTimeOffset FileCreationTime { get; set; } - [System.Xml.Serialization.XmlElement("FileCreationTime")] - public string FileCreationTimeForXml { get; set; } - [System.Xml.Serialization.XmlIgnore] - public System.DateTimeOffset FileModificationTime { get; set; } - [System.Xml.Serialization.XmlElement("FileModificationTime")] - public string FileModificationTimeForXml { get; set; } - public long FileSize { get; set; } - public string? Version { get; set; } - } - } -} diff --git a/test/BililiveRecorder.Flv.Tests/PublicApi.cs b/test/BililiveRecorder.Flv.Tests/PublicApi.cs deleted file mode 100644 index 1a76778..0000000 --- a/test/BililiveRecorder.Flv.Tests/PublicApi.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Threading.Tasks; -using PublicApiGenerator; -using VerifyXunit; -using Xunit; - -namespace BililiveRecorder.Flv.Tests -{ - [UsesVerify] - public class PublicApi - { - [Fact] - public Task HasNoChangesAsync() - { - var publicApi = typeof(Tag).Assembly.GeneratePublicApi(new ApiGeneratorOptions { ExcludeAttributes = new[] { "System.Runtime.Versioning.TargetFrameworkAttribute" } }); - return Verifier.Verify(publicApi); - } - } -} diff --git a/test/BililiveRecorder.Flv.Tests/VerifyConfig.cs b/test/BililiveRecorder.Flv.Tests/VerifyConfig.cs index 9786533..1c76fbf 100644 --- a/test/BililiveRecorder.Flv.Tests/VerifyConfig.cs +++ b/test/BililiveRecorder.Flv.Tests/VerifyConfig.cs @@ -15,7 +15,7 @@ namespace BililiveRecorder.Flv.Tests { Verifier.DerivePathInfo((string sourceFile, string projectDirectory, Type type, MethodInfo method) => { - if (type != typeof(PublicApi) && type != typeof(TestData)) + if (type != typeof(TestData)) projectDirectory = Path.Combine(projectDirectory, "..", "data", "flv"); return Expectations.Initialize(sourceFile, projectDirectory, type, method);