feat: add support for recording mode fallback
Some checks failed
Build and Test / test (ubuntu-latest) (push) Has been cancelled
Build and Test / test (windows-latest) (push) Has been cancelled
Build and Test / build_wpf (push) Has been cancelled
Build and Test / build_cli (any) (push) Has been cancelled
Build and Test / build_cli (linux-arm) (push) Has been cancelled
Build and Test / build_cli (linux-arm64) (push) Has been cancelled
Build and Test / build_cli (linux-x64) (push) Has been cancelled
Build and Test / build_cli (osx-arm64) (push) Has been cancelled
Build and Test / build_cli (osx-x64) (push) Has been cancelled
Build and Test / build_cli (win-x64) (push) Has been cancelled
Build and Test / build_docker (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled

This commit is contained in:
genteure 2024-12-01 19:44:46 +08:00
parent 19c529c259
commit 2dd898ecd1
5 changed files with 24 additions and 7 deletions

View File

@ -39,5 +39,7 @@ namespace BililiveRecorder.Core
void StopRecord(); void StopRecord();
void SplitOutput(); void SplitOutput();
Task RefreshRoomInfoAsync(); Task RefreshRoomInfoAsync();
void MarkNextRecordShouldUseRawMode();
} }
} }

View File

@ -1,7 +1,9 @@
using BililiveRecorder.Core.Config;
namespace BililiveRecorder.Core.Recording namespace BililiveRecorder.Core.Recording
{ {
internal interface IRecordTaskFactory internal interface IRecordTaskFactory
{ {
IRecordTask CreateRecordTask(IRoom room); IRecordTask CreateRecordTask(IRoom room, RecordMode? recordModeOverride = null);
} }
} }

View File

@ -21,10 +21,14 @@ namespace BililiveRecorder.Core.Recording
this.factoryStandard = ActivatorUtilities.CreateFactory(typeof(StandardRecordTask), new[] { typeof(IRoom) }); this.factoryStandard = ActivatorUtilities.CreateFactory(typeof(StandardRecordTask), new[] { typeof(IRoom) });
} }
public IRecordTask CreateRecordTask(IRoom room) public IRecordTask CreateRecordTask(IRoom room, RecordMode? recordModeOverride = null)
{ {
var recordMode = room.RoomConfig.RecordMode; var recordMode = room.RoomConfig.RecordMode;
this.logger.Debug("Create record task with mode {RecordMode} for room {RoomId}", recordMode, room.RoomConfig.RoomId); if (recordModeOverride.HasValue)
{
recordMode = recordModeOverride.Value;
}
this.logger.Debug("Create record task with mode {RecordMode} for room {RoomId}, override: {Override}", recordMode, room.RoomConfig.RoomId, recordModeOverride);
return recordMode switch return recordMode switch
{ {
RecordMode.RawData => (IRecordTask)this.factoryRawData(this.serviceProvider, new[] { room }), RecordMode.RawData => (IRecordTask)this.factoryRawData(this.serviceProvider, new[] { room }),

View File

@ -203,8 +203,8 @@ namespace BililiveRecorder.Core.Recording
catch (UnsupportedCodecException ex) catch (UnsupportedCodecException ex)
{ {
// 直播流不是 H.264 // 直播流不是 H.264
this.logger.Warning(ex, "不支持此直播流的视频编码格式(只支持 H.264本场直播不再自动启动录制。"); this.logger.Warning(ex, "不支持此直播流的视频编码格式(只支持 H.264下次录制会尝试使用原始模式录制");
this.room.StopRecord(); // 停止自动重试 this.room.MarkNextRecordShouldUseRawMode();
} }
catch (OperationCanceledException ex) catch (OperationCanceledException ex)
{ {

View File

@ -8,6 +8,7 @@ using System.Text.RegularExpressions;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using BililiveRecorder.Core.Api; using BililiveRecorder.Core.Api;
using BililiveRecorder.Core.Config;
using BililiveRecorder.Core.Config.V3; using BililiveRecorder.Core.Config.V3;
using BililiveRecorder.Core.Danmaku; using BililiveRecorder.Core.Danmaku;
using BililiveRecorder.Core.Event; using BililiveRecorder.Core.Event;
@ -54,6 +55,7 @@ namespace BililiveRecorder.Core
private bool danmakuConnected; private bool danmakuConnected;
private bool streaming; private bool streaming;
private bool autoRecordForThisSession = true; private bool autoRecordForThisSession = true;
private bool nextRecordShouldUseRawMode = false;
private IRecordTask? recordTask; private IRecordTask? recordTask;
private DateTimeOffset danmakuClientConnectTime; private DateTimeOffset danmakuClientConnectTime;
@ -229,6 +231,11 @@ namespace BililiveRecorder.Core
} }
} }
public void MarkNextRecordShouldUseRawMode()
{
this.nextRecordShouldUseRawMode = true;
}
private static readonly TimeSpan TitleRegexMatchTimeout = TimeSpan.FromSeconds(0.5); private static readonly TimeSpan TitleRegexMatchTimeout = TimeSpan.FromSeconds(0.5);
/// <exception cref="ArgumentException" /> /// <exception cref="ArgumentException" />
@ -277,7 +284,9 @@ namespace BililiveRecorder.Core
this.logger.Warning(ex, "检查标题是否匹配跳过录制正则表达式时出错"); this.logger.Warning(ex, "检查标题是否匹配跳过录制正则表达式时出错");
} }
var task = this.recordTaskFactory.CreateRecordTask(this); var task = this.recordTaskFactory.CreateRecordTask(this, this.nextRecordShouldUseRawMode ? RecordMode.RawData : null);
this.nextRecordShouldUseRawMode = false;
task.IOStats += this.RecordTask_IOStats; task.IOStats += this.RecordTask_IOStats;
task.RecordingStats += this.RecordTask_RecordingStats; task.RecordingStats += this.RecordTask_RecordingStats;
task.RecordFileOpening += this.RecordTask_RecordFileOpening; task.RecordFileOpening += this.RecordTask_RecordFileOpening;
@ -516,7 +525,7 @@ namespace BililiveRecorder.Core
{ {
const int MAX_ATTEMPT = 3; const int MAX_ATTEMPT = 3;
var attempt = 0; var attempt = 0;
retry: retry:
try try
{ {
var coverUrl = this.RawBilibiliApiJsonData?["room_info"]?["cover"]?.ToObject<string>(); var coverUrl = this.RawBilibiliApiJsonData?["room_info"]?["cover"]?.ToObject<string>();