diff --git a/BililiveRecorder.Cli/Configure/ConfigInstructions.gen.cs b/BililiveRecorder.Cli/Configure/ConfigInstructions.gen.cs index 4041f13..e0caee2 100644 --- a/BililiveRecorder.Cli/Configure/ConfigInstructions.gen.cs +++ b/BililiveRecorder.Cli/Configure/ConfigInstructions.gen.cs @@ -17,6 +17,7 @@ namespace BililiveRecorder.Cli.Configure RecordMode, CuttingMode, CuttingNumber, + CuttingByTitle, RecordDanmaku, RecordDanmakuRaw, RecordDanmakuSuperChat, @@ -56,6 +57,7 @@ namespace BililiveRecorder.Cli.Configure RecordMode, CuttingMode, CuttingNumber, + CuttingByTitle, RecordDanmaku, RecordDanmakuRaw, RecordDanmakuSuperChat, @@ -75,6 +77,7 @@ namespace BililiveRecorder.Cli.Configure GlobalConfig.Add(GlobalConfigProperties.RecordMode, new ConfigInstruction(config => config.HasRecordMode = false, (config, value) => config.RecordMode = value) { Name = "RecordMode", CanBeOptional = true }); GlobalConfig.Add(GlobalConfigProperties.CuttingMode, new ConfigInstruction(config => config.HasCuttingMode = false, (config, value) => config.CuttingMode = value) { Name = "CuttingMode", CanBeOptional = true }); GlobalConfig.Add(GlobalConfigProperties.CuttingNumber, new ConfigInstruction(config => config.HasCuttingNumber = false, (config, value) => config.CuttingNumber = value) { Name = "CuttingNumber", CanBeOptional = true }); + GlobalConfig.Add(GlobalConfigProperties.CuttingByTitle, new ConfigInstruction(config => config.HasCuttingByTitle = false, (config, value) => config.CuttingByTitle = value) { Name = "CuttingByTitle", CanBeOptional = true }); GlobalConfig.Add(GlobalConfigProperties.RecordDanmaku, new ConfigInstruction(config => config.HasRecordDanmaku = false, (config, value) => config.RecordDanmaku = value) { Name = "RecordDanmaku", CanBeOptional = true }); GlobalConfig.Add(GlobalConfigProperties.RecordDanmakuRaw, new ConfigInstruction(config => config.HasRecordDanmakuRaw = false, (config, value) => config.RecordDanmakuRaw = value) { Name = "RecordDanmakuRaw", CanBeOptional = true }); GlobalConfig.Add(GlobalConfigProperties.RecordDanmakuSuperChat, new ConfigInstruction(config => config.HasRecordDanmakuSuperChat = false, (config, value) => config.RecordDanmakuSuperChat = value) { Name = "RecordDanmakuSuperChat", CanBeOptional = true }); @@ -110,6 +113,7 @@ namespace BililiveRecorder.Cli.Configure RoomConfig.Add(RoomConfigProperties.RecordMode, new ConfigInstruction(config => config.HasRecordMode = false, (config, value) => config.RecordMode = value) { Name = "RecordMode", CanBeOptional = true }); RoomConfig.Add(RoomConfigProperties.CuttingMode, new ConfigInstruction(config => config.HasCuttingMode = false, (config, value) => config.CuttingMode = value) { Name = "CuttingMode", CanBeOptional = true }); RoomConfig.Add(RoomConfigProperties.CuttingNumber, new ConfigInstruction(config => config.HasCuttingNumber = false, (config, value) => config.CuttingNumber = value) { Name = "CuttingNumber", CanBeOptional = true }); + RoomConfig.Add(RoomConfigProperties.CuttingByTitle, new ConfigInstruction(config => config.HasCuttingByTitle = false, (config, value) => config.CuttingByTitle = value) { Name = "CuttingByTitle", CanBeOptional = true }); RoomConfig.Add(RoomConfigProperties.RecordDanmaku, new ConfigInstruction(config => config.HasRecordDanmaku = false, (config, value) => config.RecordDanmaku = value) { Name = "RecordDanmaku", CanBeOptional = true }); RoomConfig.Add(RoomConfigProperties.RecordDanmakuRaw, new ConfigInstruction(config => config.HasRecordDanmakuRaw = false, (config, value) => config.RecordDanmakuRaw = value) { Name = "RecordDanmakuRaw", CanBeOptional = true }); RoomConfig.Add(RoomConfigProperties.RecordDanmakuSuperChat, new ConfigInstruction(config => config.HasRecordDanmakuSuperChat = false, (config, value) => config.RecordDanmakuSuperChat = value) { Name = "RecordDanmakuSuperChat", CanBeOptional = true }); diff --git a/BililiveRecorder.Core/Config/V3/Config.gen.cs b/BililiveRecorder.Core/Config/V3/Config.gen.cs index 9240acf..70716bf 100644 --- a/BililiveRecorder.Core/Config/V3/Config.gen.cs +++ b/BililiveRecorder.Core/Config/V3/Config.gen.cs @@ -53,6 +53,14 @@ namespace BililiveRecorder.Core.Config.V3 [JsonProperty(nameof(CuttingNumber)), EditorBrowsable(EditorBrowsableState.Never)] public Optional OptionalCuttingNumber { get => this.GetPropertyValueOptional(nameof(this.CuttingNumber)); set => this.SetPropertyValueOptional(value, nameof(this.CuttingNumber)); } + /// + /// 改标题后自动分段 + /// + public bool CuttingByTitle { get => this.GetPropertyValue(); set => this.SetPropertyValue(value); } + public bool HasCuttingByTitle { get => this.GetPropertyHasValue(nameof(this.CuttingByTitle)); set => this.SetPropertyHasValue(value, nameof(this.CuttingByTitle)); } + [JsonProperty(nameof(CuttingByTitle)), EditorBrowsable(EditorBrowsableState.Never)] + public Optional OptionalCuttingByTitle { get => this.GetPropertyValueOptional(nameof(this.CuttingByTitle)); set => this.SetPropertyValueOptional(value, nameof(this.CuttingByTitle)); } + /// /// 弹幕录制 /// @@ -251,6 +259,14 @@ namespace BililiveRecorder.Core.Config.V3 [JsonProperty(nameof(CuttingNumber)), EditorBrowsable(EditorBrowsableState.Never)] public Optional OptionalCuttingNumber { get => this.GetPropertyValueOptional(nameof(this.CuttingNumber)); set => this.SetPropertyValueOptional(value, nameof(this.CuttingNumber)); } + /// + /// 改标题后自动分段 + /// + public bool CuttingByTitle { get => this.GetPropertyValue(); set => this.SetPropertyValue(value); } + public bool HasCuttingByTitle { get => this.GetPropertyHasValue(nameof(this.CuttingByTitle)); set => this.SetPropertyHasValue(value, nameof(this.CuttingByTitle)); } + [JsonProperty(nameof(CuttingByTitle)), EditorBrowsable(EditorBrowsableState.Never)] + public Optional OptionalCuttingByTitle { get => this.GetPropertyValueOptional(nameof(this.CuttingByTitle)); set => this.SetPropertyValueOptional(value, nameof(this.CuttingByTitle)); } + /// /// 弹幕录制 /// @@ -496,6 +512,8 @@ namespace BililiveRecorder.Core.Config.V3 public uint CuttingNumber => 100; + public bool CuttingByTitle => false; + public bool RecordDanmaku => false; public bool RecordDanmakuRaw => false; diff --git a/BililiveRecorder.Core/Room.cs b/BililiveRecorder.Core/Room.cs index 374d4fb..b84684d 100644 --- a/BililiveRecorder.Core/Room.cs +++ b/BililiveRecorder.Core/Room.cs @@ -669,6 +669,11 @@ retry: this.AutoRecordForThisSession = true; } break; + case nameof(this.Title): + if (this.RoomConfig.CuttingByTitle){ + this.SplitOutput(); + } + break; default: break; } diff --git a/BililiveRecorder.WPF/Controls/PerRoomSettingsDialog.xaml b/BililiveRecorder.WPF/Controls/PerRoomSettingsDialog.xaml index 7c817db..6c81752 100644 --- a/BililiveRecorder.WPF/Controls/PerRoomSettingsDialog.xaml +++ b/BililiveRecorder.WPF/Controls/PerRoomSettingsDialog.xaml @@ -96,6 +96,7 @@ + diff --git a/BililiveRecorder.WPF/Pages/SettingsPage.xaml b/BililiveRecorder.WPF/Pages/SettingsPage.xaml index 0c9779c..523105c 100644 --- a/BililiveRecorder.WPF/Pages/SettingsPage.xaml +++ b/BililiveRecorder.WPF/Pages/SettingsPage.xaml @@ -78,6 +78,9 @@ + + + diff --git a/BililiveRecorder.WPF/Properties/Strings.en.resx b/BililiveRecorder.WPF/Properties/Strings.en.resx index 1aa5cec..00694e8 100644 --- a/BililiveRecorder.WPF/Properties/Strings.en.resx +++ b/BililiveRecorder.WPF/Properties/Strings.en.resx @@ -490,7 +490,10 @@ Only FLV is supported Split recording by video time - Disable + Don't split by file size or video time + + + Split recording by change of live stream title Split recording every diff --git a/BililiveRecorder.WPF/Properties/Strings.ja.resx b/BililiveRecorder.WPF/Properties/Strings.ja.resx index 640849c..8792b36 100644 --- a/BililiveRecorder.WPF/Properties/Strings.ja.resx +++ b/BililiveRecorder.WPF/Properties/Strings.ja.resx @@ -490,7 +490,10 @@ FLV フォーマットのみサポートされています。 録画の長さによって分割する - 自動分割しない + ファイルサイズやビデオの時間によって分割しないでください + + + 配信ルームの名を変更した後に、録画を分割する diff --git a/BililiveRecorder.WPF/Properties/Strings.resx b/BililiveRecorder.WPF/Properties/Strings.resx index af3a9fd..93ad7be 100644 --- a/BililiveRecorder.WPF/Properties/Strings.resx +++ b/BililiveRecorder.WPF/Properties/Strings.resx @@ -490,7 +490,10 @@ 根据视频时间自动分段 - 不自动分段 + 不要根据文件大小/视频时间自动分段 + + + 直播间更改标题后自动分段 diff --git a/BililiveRecorder.WPF/Properties/Strings.zh-Hant.resx b/BililiveRecorder.WPF/Properties/Strings.zh-Hant.resx index eb50b30..4aca231 100644 --- a/BililiveRecorder.WPF/Properties/Strings.zh-Hant.resx +++ b/BililiveRecorder.WPF/Properties/Strings.zh-Hant.resx @@ -457,13 +457,16 @@ 設定 - 依照文件大小自動分段 + 依照檔案大小自動分段 - 依照影片錄製時間自動分段 + 依照影片錄製時長自動分段 - 不自動分段 + 不要根據檔案大小或影片時長拆分錄製 + + + 按直播間標題变更拆分錄製 diff --git a/BililiveRecorder.Web/Models/Config.gen.cs b/BililiveRecorder.Web/Models/Config.gen.cs index 9002606..83b9fff 100644 --- a/BililiveRecorder.Web/Models/Config.gen.cs +++ b/BililiveRecorder.Web/Models/Config.gen.cs @@ -16,6 +16,7 @@ namespace BililiveRecorder.Web.Models public Optional? OptionalRecordMode { get; set; } public Optional? OptionalCuttingMode { get; set; } public Optional? OptionalCuttingNumber { get; set; } + public Optional? OptionalCuttingByTitle { get; set; } public Optional? OptionalRecordDanmaku { get; set; } public Optional? OptionalRecordDanmakuRaw { get; set; } public Optional? OptionalRecordDanmakuSuperChat { get; set; } @@ -31,6 +32,7 @@ namespace BililiveRecorder.Web.Models if (this.OptionalRecordMode.HasValue) config.OptionalRecordMode = this.OptionalRecordMode.Value; if (this.OptionalCuttingMode.HasValue) config.OptionalCuttingMode = this.OptionalCuttingMode.Value; if (this.OptionalCuttingNumber.HasValue) config.OptionalCuttingNumber = this.OptionalCuttingNumber.Value; + if (this.OptionalCuttingByTitle.HasValue) config.OptionalCuttingByTitle = this.OptionalCuttingByTitle.Value; if (this.OptionalRecordDanmaku.HasValue) config.OptionalRecordDanmaku = this.OptionalRecordDanmaku.Value; if (this.OptionalRecordDanmakuRaw.HasValue) config.OptionalRecordDanmakuRaw = this.OptionalRecordDanmakuRaw.Value; if (this.OptionalRecordDanmakuSuperChat.HasValue) config.OptionalRecordDanmakuSuperChat = this.OptionalRecordDanmakuSuperChat.Value; @@ -47,6 +49,7 @@ namespace BililiveRecorder.Web.Models public Optional? OptionalRecordMode { get; set; } public Optional? OptionalCuttingMode { get; set; } public Optional? OptionalCuttingNumber { get; set; } + public Optional? OptionalCuttingByTitle { get; set; } public Optional? OptionalRecordDanmaku { get; set; } public Optional? OptionalRecordDanmakuRaw { get; set; } public Optional? OptionalRecordDanmakuSuperChat { get; set; } @@ -82,6 +85,7 @@ namespace BililiveRecorder.Web.Models if (this.OptionalRecordMode.HasValue) config.OptionalRecordMode = this.OptionalRecordMode.Value; if (this.OptionalCuttingMode.HasValue) config.OptionalCuttingMode = this.OptionalCuttingMode.Value; if (this.OptionalCuttingNumber.HasValue) config.OptionalCuttingNumber = this.OptionalCuttingNumber.Value; + if (this.OptionalCuttingByTitle.HasValue) config.OptionalCuttingByTitle = this.OptionalCuttingByTitle.Value; if (this.OptionalRecordDanmaku.HasValue) config.OptionalRecordDanmaku = this.OptionalRecordDanmaku.Value; if (this.OptionalRecordDanmakuRaw.HasValue) config.OptionalRecordDanmakuRaw = this.OptionalRecordDanmakuRaw.Value; if (this.OptionalRecordDanmakuSuperChat.HasValue) config.OptionalRecordDanmakuSuperChat = this.OptionalRecordDanmakuSuperChat.Value; @@ -124,6 +128,7 @@ namespace BililiveRecorder.Web.Models.Rest public Optional OptionalRecordMode { get; set; } public Optional OptionalCuttingMode { get; set; } public Optional OptionalCuttingNumber { get; set; } + public Optional OptionalCuttingByTitle { get; set; } public Optional OptionalRecordDanmaku { get; set; } public Optional OptionalRecordDanmakuRaw { get; set; } public Optional OptionalRecordDanmakuSuperChat { get; set; } @@ -139,6 +144,7 @@ namespace BililiveRecorder.Web.Models.Rest public Optional OptionalRecordMode { get; set; } public Optional OptionalCuttingMode { get; set; } public Optional OptionalCuttingNumber { get; set; } + public Optional OptionalCuttingByTitle { get; set; } public Optional OptionalRecordDanmaku { get; set; } public Optional OptionalRecordDanmakuRaw { get; set; } public Optional OptionalRecordDanmakuSuperChat { get; set; } @@ -183,6 +189,7 @@ namespace BililiveRecorder.Web.Models.Graphql this.Field(x => x.OptionalRecordMode, type: typeof(HierarchicalOptionalType)); this.Field(x => x.OptionalCuttingMode, type: typeof(HierarchicalOptionalType)); this.Field(x => x.OptionalCuttingNumber, type: typeof(HierarchicalOptionalType)); + this.Field(x => x.OptionalCuttingByTitle, type: typeof(HierarchicalOptionalType)); this.Field(x => x.OptionalRecordDanmaku, type: typeof(HierarchicalOptionalType)); this.Field(x => x.OptionalRecordDanmakuRaw, type: typeof(HierarchicalOptionalType)); this.Field(x => x.OptionalRecordDanmakuSuperChat, type: typeof(HierarchicalOptionalType)); @@ -201,6 +208,7 @@ namespace BililiveRecorder.Web.Models.Graphql this.Field(x => x.OptionalRecordMode, type: typeof(HierarchicalOptionalType)); this.Field(x => x.OptionalCuttingMode, type: typeof(HierarchicalOptionalType)); this.Field(x => x.OptionalCuttingNumber, type: typeof(HierarchicalOptionalType)); + this.Field(x => x.OptionalCuttingByTitle, type: typeof(HierarchicalOptionalType)); this.Field(x => x.OptionalRecordDanmaku, type: typeof(HierarchicalOptionalType)); this.Field(x => x.OptionalRecordDanmakuRaw, type: typeof(HierarchicalOptionalType)); this.Field(x => x.OptionalRecordDanmakuSuperChat, type: typeof(HierarchicalOptionalType)); @@ -240,6 +248,7 @@ namespace BililiveRecorder.Web.Models.Graphql this.Field(x => x.RecordMode); this.Field(x => x.CuttingMode); this.Field(x => x.CuttingNumber); + this.Field(x => x.CuttingByTitle); this.Field(x => x.RecordDanmaku); this.Field(x => x.RecordDanmakuRaw); this.Field(x => x.RecordDanmakuSuperChat); @@ -280,6 +289,7 @@ namespace BililiveRecorder.Web.Models.Graphql this.Field(x => x.OptionalRecordMode, nullable: true, type: typeof(HierarchicalOptionalInputType)); this.Field(x => x.OptionalCuttingMode, nullable: true, type: typeof(HierarchicalOptionalInputType)); this.Field(x => x.OptionalCuttingNumber, nullable: true, type: typeof(HierarchicalOptionalInputType)); + this.Field(x => x.OptionalCuttingByTitle, nullable: true, type: typeof(HierarchicalOptionalInputType)); this.Field(x => x.OptionalRecordDanmaku, nullable: true, type: typeof(HierarchicalOptionalInputType)); this.Field(x => x.OptionalRecordDanmakuRaw, nullable: true, type: typeof(HierarchicalOptionalInputType)); this.Field(x => x.OptionalRecordDanmakuSuperChat, nullable: true, type: typeof(HierarchicalOptionalInputType)); @@ -298,6 +308,7 @@ namespace BililiveRecorder.Web.Models.Graphql this.Field(x => x.OptionalRecordMode, nullable: true, type: typeof(HierarchicalOptionalInputType)); this.Field(x => x.OptionalCuttingMode, nullable: true, type: typeof(HierarchicalOptionalInputType)); this.Field(x => x.OptionalCuttingNumber, nullable: true, type: typeof(HierarchicalOptionalInputType)); + this.Field(x => x.OptionalCuttingByTitle, nullable: true, type: typeof(HierarchicalOptionalInputType)); this.Field(x => x.OptionalRecordDanmaku, nullable: true, type: typeof(HierarchicalOptionalInputType)); this.Field(x => x.OptionalRecordDanmakuRaw, nullable: true, type: typeof(HierarchicalOptionalInputType)); this.Field(x => x.OptionalRecordDanmakuSuperChat, nullable: true, type: typeof(HierarchicalOptionalInputType)); diff --git a/configV3.schema.json b/configV3.schema.json index ee098fa..25a0b62 100644 --- a/configV3.schema.json +++ b/configV3.schema.json @@ -434,6 +434,22 @@ } } }, + "CuttingByTitle": { + "description": "改标题后自动分段\n默认: false", + "markdownDescription": "改标题后自动分段 \n默认: `false `\n\n", + "type": "object", + "additionalProperties": false, + "properties": { + "HasValue": { + "type": "boolean", + "default": true + }, + "Value": { + "type": "boolean", + "default": false + } + } + }, "RecordDanmaku": { "description": "弹幕录制\n默认: false", "markdownDescription": "弹幕录制 \n默认: `false `\n\n", @@ -663,6 +679,22 @@ } } }, + "CuttingByTitle": { + "description": "改标题后自动分段\n默认: false", + "markdownDescription": "改标题后自动分段 \n默认: `false `\n\n", + "type": "object", + "additionalProperties": false, + "properties": { + "HasValue": { + "type": "boolean", + "default": true + }, + "Value": { + "type": "boolean", + "default": false + } + } + }, "RecordDanmaku": { "description": "弹幕录制\n默认: false", "markdownDescription": "弹幕录制 \n默认: `false `\n\n", diff --git a/config_gen/data.ts b/config_gen/data.ts index f245492..cc4b267 100644 --- a/config_gen/data.ts +++ b/config_gen/data.ts @@ -37,6 +37,13 @@ export const data: Array = [ configType: "room", default: 100 }, + { + id: "CuttingByTitle", + name: "改标题后自动分段", + type: "bool", + configType: "room", + default: false + }, { id: "RecordDanmaku", name: "弹幕录制", diff --git a/test/BililiveRecorder.Core.UnitTests/Expectations/PublicApi.HasNoChangesAsync.verified.txt b/test/BililiveRecorder.Core.UnitTests/Expectations/PublicApi.HasNoChangesAsync.verified.txt index 4480862..5226db2 100644 --- a/test/BililiveRecorder.Core.UnitTests/Expectations/PublicApi.HasNoChangesAsync.verified.txt +++ b/test/BililiveRecorder.Core.UnitTests/Expectations/PublicApi.HasNoChangesAsync.verified.txt @@ -74,6 +74,7 @@ namespace BililiveRecorder.Core.Config.V3 { public static readonly BililiveRecorder.Core.Config.V3.DefaultConfig Instance; public string Cookie { get; } + public bool CuttingByTitle { get; } public BililiveRecorder.Core.Config.CuttingMode CuttingMode { get; } public uint CuttingNumber { get; } public bool DanmakuAuthenticateWithStreamerUid { get; } @@ -111,6 +112,7 @@ namespace BililiveRecorder.Core.Config.V3 { public GlobalConfig() { } public string? Cookie { get; set; } + public bool CuttingByTitle { get; set; } public BililiveRecorder.Core.Config.CuttingMode CuttingMode { get; set; } public uint CuttingNumber { get; set; } public bool DanmakuAuthenticateWithStreamerUid { get; set; } @@ -119,6 +121,7 @@ namespace BililiveRecorder.Core.Config.V3 public bool FlvProcessorSplitOnScriptTag { get; set; } public bool FlvWriteMetadata { get; set; } public bool HasCookie { get; set; } + public bool HasCuttingByTitle { get; set; } public bool HasCuttingMode { get; set; } public bool HasCuttingNumber { get; set; } public bool HasDanmakuAuthenticateWithStreamerUid { get; set; } @@ -155,6 +158,8 @@ namespace BililiveRecorder.Core.Config.V3 public bool NetworkTransportUseSystemProxy { get; set; } [Newtonsoft.Json.JsonProperty("Cookie")] public HierarchicalPropertyDefault.Optional OptionalCookie { get; set; } + [Newtonsoft.Json.JsonProperty("CuttingByTitle")] + public HierarchicalPropertyDefault.Optional OptionalCuttingByTitle { get; set; } [Newtonsoft.Json.JsonProperty("CuttingMode")] public HierarchicalPropertyDefault.Optional OptionalCuttingMode { get; set; } [Newtonsoft.Json.JsonProperty("CuttingNumber")] @@ -251,6 +256,7 @@ namespace BililiveRecorder.Core.Config.V3 public RoomConfig() { } public bool AutoRecord { get; set; } public string? Cookie { get; } + public bool CuttingByTitle { get; set; } public BililiveRecorder.Core.Config.CuttingMode CuttingMode { get; set; } public uint CuttingNumber { get; set; } public bool DanmakuAuthenticateWithStreamerUid { get; } @@ -259,6 +265,7 @@ namespace BililiveRecorder.Core.Config.V3 public bool FlvProcessorSplitOnScriptTag { get; set; } public bool FlvWriteMetadata { get; } public bool HasAutoRecord { get; set; } + public bool HasCuttingByTitle { get; set; } public bool HasCuttingMode { get; set; } public bool HasCuttingNumber { get; set; } public bool HasFlvProcessorSplitOnScriptTag { get; set; } @@ -276,6 +283,8 @@ namespace BililiveRecorder.Core.Config.V3 public bool NetworkTransportUseSystemProxy { get; } [Newtonsoft.Json.JsonProperty("AutoRecord")] public HierarchicalPropertyDefault.Optional OptionalAutoRecord { get; set; } + [Newtonsoft.Json.JsonProperty("CuttingByTitle")] + public HierarchicalPropertyDefault.Optional OptionalCuttingByTitle { get; set; } [Newtonsoft.Json.JsonProperty("CuttingMode")] public HierarchicalPropertyDefault.Optional OptionalCuttingMode { get; set; } [Newtonsoft.Json.JsonProperty("CuttingNumber")]