mirror of
https://github.com/BililiveRecorder/BililiveRecorder.git
synced 2024-11-15 19:22:19 +08:00
feat: add option to disable spliting when H264 Annex-B is detected
This commit is contained in:
parent
f48fbf4d38
commit
8b4d467bd5
|
@ -27,6 +27,7 @@ namespace BililiveRecorder.Cli.Configure
|
|||
RecordingQuality,
|
||||
FileNameRecordTemplate,
|
||||
FlvProcessorSplitOnScriptTag,
|
||||
FlvProcessorDisableSplitOnH264AnnexB,
|
||||
FlvWriteMetadata,
|
||||
WebHookUrls,
|
||||
WebHookUrlsV2,
|
||||
|
@ -65,7 +66,8 @@ namespace BililiveRecorder.Cli.Configure
|
|||
RecordDanmakuGuard,
|
||||
SaveStreamCover,
|
||||
RecordingQuality,
|
||||
FlvProcessorSplitOnScriptTag
|
||||
FlvProcessorSplitOnScriptTag,
|
||||
FlvProcessorDisableSplitOnH264AnnexB
|
||||
}
|
||||
public static class ConfigInstructions
|
||||
{
|
||||
|
@ -87,6 +89,7 @@ namespace BililiveRecorder.Cli.Configure
|
|||
GlobalConfig.Add(GlobalConfigProperties.RecordingQuality, new ConfigInstruction<GlobalConfig, string>(config => config.HasRecordingQuality = false, (config, value) => config.RecordingQuality = value) { Name = "RecordingQuality", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.FileNameRecordTemplate, new ConfigInstruction<GlobalConfig, string>(config => config.HasFileNameRecordTemplate = false, (config, value) => config.FileNameRecordTemplate = value) { Name = "FileNameRecordTemplate", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.FlvProcessorSplitOnScriptTag, new ConfigInstruction<GlobalConfig, bool>(config => config.HasFlvProcessorSplitOnScriptTag = false, (config, value) => config.FlvProcessorSplitOnScriptTag = value) { Name = "FlvProcessorSplitOnScriptTag", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.FlvProcessorDisableSplitOnH264AnnexB, new ConfigInstruction<GlobalConfig, bool>(config => config.HasFlvProcessorDisableSplitOnH264AnnexB = false, (config, value) => config.FlvProcessorDisableSplitOnH264AnnexB = value) { Name = "FlvProcessorDisableSplitOnH264AnnexB", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.FlvWriteMetadata, new ConfigInstruction<GlobalConfig, bool>(config => config.HasFlvWriteMetadata = false, (config, value) => config.FlvWriteMetadata = value) { Name = "FlvWriteMetadata", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.WebHookUrls, new ConfigInstruction<GlobalConfig, string>(config => config.HasWebHookUrls = false, (config, value) => config.WebHookUrls = value) { Name = "WebHookUrls", CanBeOptional = true });
|
||||
GlobalConfig.Add(GlobalConfigProperties.WebHookUrlsV2, new ConfigInstruction<GlobalConfig, string>(config => config.HasWebHookUrlsV2 = false, (config, value) => config.WebHookUrlsV2 = value) { Name = "WebHookUrlsV2", CanBeOptional = true });
|
||||
|
@ -122,6 +125,7 @@ namespace BililiveRecorder.Cli.Configure
|
|||
RoomConfig.Add(RoomConfigProperties.SaveStreamCover, new ConfigInstruction<RoomConfig, bool>(config => config.HasSaveStreamCover = false, (config, value) => config.SaveStreamCover = value) { Name = "SaveStreamCover", CanBeOptional = true });
|
||||
RoomConfig.Add(RoomConfigProperties.RecordingQuality, new ConfigInstruction<RoomConfig, string>(config => config.HasRecordingQuality = false, (config, value) => config.RecordingQuality = value) { Name = "RecordingQuality", CanBeOptional = true });
|
||||
RoomConfig.Add(RoomConfigProperties.FlvProcessorSplitOnScriptTag, new ConfigInstruction<RoomConfig, bool>(config => config.HasFlvProcessorSplitOnScriptTag = false, (config, value) => config.FlvProcessorSplitOnScriptTag = value) { Name = "FlvProcessorSplitOnScriptTag", CanBeOptional = true });
|
||||
RoomConfig.Add(RoomConfigProperties.FlvProcessorDisableSplitOnH264AnnexB, new ConfigInstruction<RoomConfig, bool>(config => config.HasFlvProcessorDisableSplitOnH264AnnexB = false, (config, value) => config.FlvProcessorDisableSplitOnH264AnnexB = value) { Name = "FlvProcessorDisableSplitOnH264AnnexB", CanBeOptional = true });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -125,6 +125,14 @@ namespace BililiveRecorder.Core.Config.V3
|
|||
[JsonProperty(nameof(FlvProcessorSplitOnScriptTag)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<bool> OptionalFlvProcessorSplitOnScriptTag { get => this.GetPropertyValueOptional<bool>(nameof(this.FlvProcessorSplitOnScriptTag)); set => this.SetPropertyValueOptional(value, nameof(this.FlvProcessorSplitOnScriptTag)); }
|
||||
|
||||
/// <summary>
|
||||
/// FLV修复-检测到 H264 Annex-B 时禁用修复分段
|
||||
/// </summary>
|
||||
public bool FlvProcessorDisableSplitOnH264AnnexB { get => this.GetPropertyValue<bool>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasFlvProcessorDisableSplitOnH264AnnexB { get => this.GetPropertyHasValue(nameof(this.FlvProcessorDisableSplitOnH264AnnexB)); set => this.SetPropertyHasValue<bool>(value, nameof(this.FlvProcessorDisableSplitOnH264AnnexB)); }
|
||||
[JsonProperty(nameof(FlvProcessorDisableSplitOnH264AnnexB)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<bool> OptionalFlvProcessorDisableSplitOnH264AnnexB { get => this.GetPropertyValueOptional<bool>(nameof(this.FlvProcessorDisableSplitOnH264AnnexB)); set => this.SetPropertyValueOptional(value, nameof(this.FlvProcessorDisableSplitOnH264AnnexB)); }
|
||||
|
||||
/// <summary>
|
||||
/// 录制文件名模板
|
||||
/// </summary>
|
||||
|
@ -339,6 +347,14 @@ namespace BililiveRecorder.Core.Config.V3
|
|||
[JsonProperty(nameof(FlvProcessorSplitOnScriptTag)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<bool> OptionalFlvProcessorSplitOnScriptTag { get => this.GetPropertyValueOptional<bool>(nameof(this.FlvProcessorSplitOnScriptTag)); set => this.SetPropertyValueOptional(value, nameof(this.FlvProcessorSplitOnScriptTag)); }
|
||||
|
||||
/// <summary>
|
||||
/// FLV修复-检测到 H264 Annex-B 时禁用修复分段
|
||||
/// </summary>
|
||||
public bool FlvProcessorDisableSplitOnH264AnnexB { get => this.GetPropertyValue<bool>(); set => this.SetPropertyValue(value); }
|
||||
public bool HasFlvProcessorDisableSplitOnH264AnnexB { get => this.GetPropertyHasValue(nameof(this.FlvProcessorDisableSplitOnH264AnnexB)); set => this.SetPropertyHasValue<bool>(value, nameof(this.FlvProcessorDisableSplitOnH264AnnexB)); }
|
||||
[JsonProperty(nameof(FlvProcessorDisableSplitOnH264AnnexB)), EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public Optional<bool> OptionalFlvProcessorDisableSplitOnH264AnnexB { get => this.GetPropertyValueOptional<bool>(nameof(this.FlvProcessorDisableSplitOnH264AnnexB)); set => this.SetPropertyValueOptional(value, nameof(this.FlvProcessorDisableSplitOnH264AnnexB)); }
|
||||
|
||||
/// <summary>
|
||||
/// 是否在视频文件写入直播信息 metadata
|
||||
/// </summary>
|
||||
|
@ -532,6 +548,8 @@ namespace BililiveRecorder.Core.Config.V3
|
|||
|
||||
public bool FlvProcessorSplitOnScriptTag => false;
|
||||
|
||||
public bool FlvProcessorDisableSplitOnH264AnnexB => false;
|
||||
|
||||
public bool FlvWriteMetadata => true;
|
||||
|
||||
public string WebHookUrls => @"";
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -9,5 +9,10 @@ namespace BililiveRecorder.Flv.Pipeline
|
|||
/// 控制收到 onMetaData 时是否分段
|
||||
/// </summary>
|
||||
public bool SplitOnScriptTag { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 检测到 H264 Annex-B 时禁用修复分段
|
||||
/// </summary>
|
||||
public bool DisableSplitOnH264AnnexB { get; set; } = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,70 @@ namespace BililiveRecorder.Flv.Pipeline.Rules
|
|||
|
||||
private IEnumerable<PipelineAction?> RunPerAction(FlvProcessingContext context, PipelineAction action)
|
||||
{
|
||||
if (this.disableSplitOnH264AnnexB)
|
||||
{
|
||||
var state = context.SessionItems.ContainsKey(ANNEXB_KEY) ? (AnnexBState)context.SessionItems[ANNEXB_KEY] : 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;
|
||||
|
|
|
@ -25,6 +25,7 @@ namespace BililiveRecorder.Web.Models
|
|||
public Optional<bool>? OptionalSaveStreamCover { get; set; }
|
||||
public Optional<string?>? OptionalRecordingQuality { get; set; }
|
||||
public Optional<bool>? OptionalFlvProcessorSplitOnScriptTag { get; set; }
|
||||
public Optional<bool>? OptionalFlvProcessorDisableSplitOnH264AnnexB { get; set; }
|
||||
|
||||
public void ApplyTo(RoomConfig config)
|
||||
{
|
||||
|
@ -41,6 +42,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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,6 +61,7 @@ namespace BililiveRecorder.Web.Models
|
|||
public Optional<string?>? OptionalRecordingQuality { get; set; }
|
||||
public Optional<string?>? OptionalFileNameRecordTemplate { get; set; }
|
||||
public Optional<bool>? OptionalFlvProcessorSplitOnScriptTag { get; set; }
|
||||
public Optional<bool>? OptionalFlvProcessorDisableSplitOnH264AnnexB { get; set; }
|
||||
public Optional<bool>? OptionalFlvWriteMetadata { get; set; }
|
||||
public Optional<string?>? OptionalWebHookUrls { get; set; }
|
||||
public Optional<string?>? OptionalWebHookUrlsV2 { get; set; }
|
||||
|
@ -95,6 +98,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.OptionalWebHookUrls.HasValue) config.OptionalWebHookUrls = this.OptionalWebHookUrls.Value;
|
||||
if (this.OptionalWebHookUrlsV2.HasValue) config.OptionalWebHookUrlsV2 = this.OptionalWebHookUrlsV2.Value;
|
||||
|
@ -137,6 +141,7 @@ namespace BililiveRecorder.Web.Models.Rest
|
|||
public Optional<bool> OptionalSaveStreamCover { get; set; }
|
||||
public Optional<string?> OptionalRecordingQuality { get; set; }
|
||||
public Optional<bool> OptionalFlvProcessorSplitOnScriptTag { get; set; }
|
||||
public Optional<bool> OptionalFlvProcessorDisableSplitOnH264AnnexB { get; set; }
|
||||
}
|
||||
|
||||
public class GlobalConfigDto
|
||||
|
@ -154,6 +159,7 @@ namespace BililiveRecorder.Web.Models.Rest
|
|||
public Optional<string?> OptionalRecordingQuality { get; set; }
|
||||
public Optional<string?> OptionalFileNameRecordTemplate { get; set; }
|
||||
public Optional<bool> OptionalFlvProcessorSplitOnScriptTag { get; set; }
|
||||
public Optional<bool> OptionalFlvProcessorDisableSplitOnH264AnnexB { get; set; }
|
||||
public Optional<bool> OptionalFlvWriteMetadata { get; set; }
|
||||
public Optional<string?> OptionalWebHookUrls { get; set; }
|
||||
public Optional<string?> OptionalWebHookUrlsV2 { get; set; }
|
||||
|
@ -198,6 +204,7 @@ namespace BililiveRecorder.Web.Models.Graphql
|
|||
this.Field(x => x.OptionalSaveStreamCover, type: typeof(HierarchicalOptionalType<bool>));
|
||||
this.Field(x => x.OptionalRecordingQuality, type: typeof(HierarchicalOptionalType<string>));
|
||||
this.Field(x => x.OptionalFlvProcessorSplitOnScriptTag, type: typeof(HierarchicalOptionalType<bool>));
|
||||
this.Field(x => x.OptionalFlvProcessorDisableSplitOnH264AnnexB, type: typeof(HierarchicalOptionalType<bool>));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -218,6 +225,7 @@ namespace BililiveRecorder.Web.Models.Graphql
|
|||
this.Field(x => x.OptionalRecordingQuality, type: typeof(HierarchicalOptionalType<string>));
|
||||
this.Field(x => x.OptionalFileNameRecordTemplate, type: typeof(HierarchicalOptionalType<string>));
|
||||
this.Field(x => x.OptionalFlvProcessorSplitOnScriptTag, type: typeof(HierarchicalOptionalType<bool>));
|
||||
this.Field(x => x.OptionalFlvProcessorDisableSplitOnH264AnnexB, type: typeof(HierarchicalOptionalType<bool>));
|
||||
this.Field(x => x.OptionalFlvWriteMetadata, type: typeof(HierarchicalOptionalType<bool>));
|
||||
this.Field(x => x.OptionalWebHookUrls, type: typeof(HierarchicalOptionalType<string>));
|
||||
this.Field(x => x.OptionalWebHookUrlsV2, type: typeof(HierarchicalOptionalType<string>));
|
||||
|
@ -258,6 +266,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.WebHookUrls);
|
||||
this.Field(x => x.WebHookUrlsV2);
|
||||
|
@ -298,6 +307,7 @@ namespace BililiveRecorder.Web.Models.Graphql
|
|||
this.Field(x => x.OptionalSaveStreamCover, nullable: true, type: typeof(HierarchicalOptionalInputType<bool>));
|
||||
this.Field(x => x.OptionalRecordingQuality, nullable: true, type: typeof(HierarchicalOptionalInputType<string>));
|
||||
this.Field(x => x.OptionalFlvProcessorSplitOnScriptTag, nullable: true, type: typeof(HierarchicalOptionalInputType<bool>));
|
||||
this.Field(x => x.OptionalFlvProcessorDisableSplitOnH264AnnexB, nullable: true, type: typeof(HierarchicalOptionalInputType<bool>));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -318,6 +328,7 @@ namespace BililiveRecorder.Web.Models.Graphql
|
|||
this.Field(x => x.OptionalRecordingQuality, nullable: true, type: typeof(HierarchicalOptionalInputType<string>));
|
||||
this.Field(x => x.OptionalFileNameRecordTemplate, nullable: true, type: typeof(HierarchicalOptionalInputType<string>));
|
||||
this.Field(x => x.OptionalFlvProcessorSplitOnScriptTag, nullable: true, type: typeof(HierarchicalOptionalInputType<bool>));
|
||||
this.Field(x => x.OptionalFlvProcessorDisableSplitOnH264AnnexB, nullable: true, type: typeof(HierarchicalOptionalInputType<bool>));
|
||||
this.Field(x => x.OptionalFlvWriteMetadata, nullable: true, type: typeof(HierarchicalOptionalInputType<bool>));
|
||||
this.Field(x => x.OptionalWebHookUrls, nullable: true, type: typeof(HierarchicalOptionalInputType<string>));
|
||||
this.Field(x => x.OptionalWebHookUrlsV2, nullable: true, type: typeof(HierarchicalOptionalInputType<string>));
|
||||
|
|
|
@ -577,6 +577,22 @@
|
|||
"default": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -822,6 +838,22 @@
|
|||
"default": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -107,6 +107,13 @@ export const data: Array<ConfigEntry> = [
|
|||
configType: "room",
|
||||
default: false
|
||||
},
|
||||
{
|
||||
id: "FlvProcessorDisableSplitOnH264AnnexB",
|
||||
name: "FLV修复-检测到 H264 Annex-B 时禁用修复分段",
|
||||
type: "bool",
|
||||
configType: "room",
|
||||
default: false
|
||||
},
|
||||
{
|
||||
id: "FlvWriteMetadata",
|
||||
name: "是否在视频文件写入直播信息 metadata",
|
||||
|
|
Loading…
Reference in New Issue
Block a user