mirror of
https://github.com/BililiveRecorder/BililiveRecorder.git
synced 2024-11-16 19:57:27 +08:00
Core: Improve recording stability
This commit is contained in:
parent
2e353da446
commit
539b0b95a4
|
@ -23,8 +23,6 @@ namespace BililiveRecorder.Core.Recording
|
|||
|
||||
public override void SplitOutput() { }
|
||||
|
||||
public override void RequestStop() => this.cts.Cancel();
|
||||
|
||||
protected override void StartRecordingLoop(Stream stream)
|
||||
{
|
||||
var (fullPath, relativePath) = this.CreateFileName();
|
||||
|
@ -79,10 +77,8 @@ namespace BililiveRecorder.Core.Recording
|
|||
}
|
||||
finally
|
||||
{
|
||||
this.logger.Debug("录制退出");
|
||||
|
||||
this.timer.Stop();
|
||||
this.cts.Cancel();
|
||||
this.RequestStop();
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -104,10 +100,12 @@ namespace BililiveRecorder.Core.Recording
|
|||
this.logger.Warning(ex, "Error calling OnRecordFileClosed");
|
||||
}
|
||||
|
||||
stream.Dispose();
|
||||
file.Dispose();
|
||||
stream.Dispose();
|
||||
|
||||
this.OnRecordSessionEnded(EventArgs.Empty);
|
||||
|
||||
this.logger.Debug("录制退出");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ namespace BililiveRecorder.Core.Recording
|
|||
protected readonly IApiClient apiClient;
|
||||
|
||||
protected bool started = false;
|
||||
protected bool timeoutTriggered = false;
|
||||
|
||||
private readonly object fillerStatsLock = new object();
|
||||
protected int fillerDownloadedBytes;
|
||||
|
@ -85,6 +86,18 @@ namespace BililiveRecorder.Core.Recording
|
|||
this.fillerStatsLastTrigger = DateTimeOffset.UtcNow;
|
||||
this.durationSinceNoDataReceived = TimeSpan.Zero;
|
||||
|
||||
this.ct.Register(state => Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
if (((WeakReference<Stream>)state).TryGetTarget(out var weakStream))
|
||||
weakStream.Dispose();
|
||||
}
|
||||
catch (Exception)
|
||||
{ }
|
||||
}), state: new WeakReference<Stream>(stream), useSynchronizationContext: false);
|
||||
|
||||
this.StartRecordingLoop(stream);
|
||||
}
|
||||
|
||||
|
@ -118,8 +131,9 @@ namespace BililiveRecorder.Core.Recording
|
|||
Mbps = mbps
|
||||
});
|
||||
|
||||
if (this.durationSinceNoDataReceived.TotalMilliseconds > this.room.RoomConfig.TimingWatchdogTimeout)
|
||||
if ((!this.timeoutTriggered) && (this.durationSinceNoDataReceived.TotalMilliseconds > this.room.RoomConfig.TimingWatchdogTimeout))
|
||||
{
|
||||
this.timeoutTriggered = true;
|
||||
this.logger.Warning("直播服务器未断开连接但停止发送直播数据,将会主动断开连接");
|
||||
this.RequestStop();
|
||||
}
|
||||
|
|
|
@ -111,6 +111,7 @@ namespace BililiveRecorder.Core.Recording
|
|||
{
|
||||
const int minimumBufferSize = 1024;
|
||||
this.timer.Start();
|
||||
|
||||
Exception? exception = null;
|
||||
try
|
||||
{
|
||||
|
@ -188,15 +189,15 @@ namespace BililiveRecorder.Core.Recording
|
|||
}
|
||||
finally
|
||||
{
|
||||
this.logger.Debug("录制退出");
|
||||
|
||||
this.reader?.Dispose();
|
||||
this.reader = null;
|
||||
this.writer?.Dispose();
|
||||
this.writer = null;
|
||||
this.cts.Cancel();
|
||||
this.RequestStop();
|
||||
|
||||
this.OnRecordSessionEnded(EventArgs.Empty);
|
||||
|
||||
this.logger.Debug("录制退出");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -127,7 +127,7 @@ namespace BililiveRecorder.Core
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.logger.Write(ex is ExecutionRejectedException ? LogEventLevel.Debug : LogEventLevel.Warning, ex, "尝试开始录制时出错");
|
||||
this.logger.Write(ex is ExecutionRejectedException ? LogEventLevel.Verbose : LogEventLevel.Warning, ex, "尝试开始录制时出错");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ namespace BililiveRecorder.Core
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.logger.Write(ex is ExecutionRejectedException ? LogEventLevel.Debug : LogEventLevel.Warning, ex, "刷新房间信息时出错");
|
||||
this.logger.Write(ex is ExecutionRejectedException ? LogEventLevel.Verbose : LogEventLevel.Warning, ex, "刷新房间信息时出错");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -220,13 +220,13 @@ namespace BililiveRecorder.Core
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.logger.Write(ex is ExecutionRejectedException ? LogEventLevel.Debug : LogEventLevel.Warning, ex, "启动录制出错");
|
||||
this.logger.Write(ex is ExecutionRejectedException ? LogEventLevel.Verbose : LogEventLevel.Warning, ex, "启动录制出错");
|
||||
|
||||
this.recordTask = null;
|
||||
this.OnPropertyChanged(nameof(this.Recording));
|
||||
|
||||
// 请求直播流出错时的重试逻辑
|
||||
_ = Task.Run(async () => await this.RestartAfterRecordTaskFailedAsync().ConfigureAwait(false));
|
||||
_ = Task.Run(this.RestartAfterRecordTaskFailedAsync);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -253,6 +253,11 @@ namespace BililiveRecorder.Core
|
|||
{
|
||||
await Task.Delay((int)this.RoomConfig.TimingStreamRetry, this.ct).ConfigureAwait(false);
|
||||
}
|
||||
catch (TaskCanceledException)
|
||||
{
|
||||
// 房间已经被删除
|
||||
return;
|
||||
}
|
||||
finally
|
||||
{
|
||||
this.recordRetryDelaySemaphoreSlim.Release();
|
||||
|
@ -266,12 +271,10 @@ namespace BililiveRecorder.Core
|
|||
if (this.Streaming && this.AutoRecordForThisSession)
|
||||
this.CreateAndStartNewRecordTask();
|
||||
}
|
||||
catch (TaskCanceledException) { }
|
||||
catch (ExecutionRejectedException) { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.logger.Write(LogEventLevel.Warning, ex, "重试开始录制时出错");
|
||||
_ = Task.Run(async () => await this.RestartAfterRecordTaskFailedAsync().ConfigureAwait(false));
|
||||
this.logger.Write(ex is ExecutionRejectedException ? LogEventLevel.Verbose : LogEventLevel.Warning, ex, "重试开始录制时出错");
|
||||
_ = Task.Run(this.RestartAfterRecordTaskFailedAsync);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -282,14 +285,21 @@ namespace BililiveRecorder.Core
|
|||
try
|
||||
{
|
||||
if (delay)
|
||||
try
|
||||
{
|
||||
await Task.Delay((int)this.RoomConfig.TimingDanmakuRetry, this.ct).ConfigureAwait(false);
|
||||
}
|
||||
catch (TaskCanceledException)
|
||||
{
|
||||
// 房间已被删除
|
||||
return;
|
||||
}
|
||||
|
||||
await this.danmakuClient.ConnectAsync(this.RoomConfig.RoomId, this.ct).ConfigureAwait(false);
|
||||
}
|
||||
catch (TaskCanceledException) { }
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.logger.Write(ex is ExecutionRejectedException ? LogEventLevel.Debug : LogEventLevel.Warning, ex, "连接弹幕服务器时出错");
|
||||
this.logger.Write(ex is ExecutionRejectedException ? LogEventLevel.Verbose : LogEventLevel.Warning, ex, "连接弹幕服务器时出错");
|
||||
|
||||
if (!this.ct.IsCancellationRequested)
|
||||
this.StartDamakuConnection();
|
||||
|
@ -357,13 +367,23 @@ namespace BililiveRecorder.Core
|
|||
_ = Task.Run(async () =>
|
||||
{
|
||||
// 录制结束退出后的重试逻辑
|
||||
// 比 RestartAfterRecordTaskFailedAsync 少了等待时间
|
||||
|
||||
if (!this.Streaming || !this.AutoRecordForThisSession)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
await this.FetchRoomInfoAsync().ConfigureAwait(false);
|
||||
|
||||
if (this.Streaming && this.AutoRecordForThisSession)
|
||||
this.CreateAndStartNewRecordTask();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.logger.Write(LogEventLevel.Warning, ex, "重试开始录制时出错");
|
||||
_ = Task.Run(this.RestartAfterRecordTaskFailedAsync);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -423,6 +443,8 @@ namespace BililiveRecorder.Core
|
|||
{
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
// 定时主动检查不需要错误重试
|
||||
|
||||
await this.FetchRoomInfoAsync().ConfigureAwait(false);
|
||||
|
||||
if (this.Streaming && this.AutoRecordForThisSession && this.RoomConfig.AutoRecord)
|
||||
|
|
Loading…
Reference in New Issue
Block a user