mirror of
https://github.com/BililiveRecorder/BililiveRecorder.git
synced 2024-11-16 11:42:22 +08:00
Fix processing bug
This commit is contained in:
parent
479a205abd
commit
d3a5158093
|
@ -20,6 +20,8 @@ namespace BililiveRecorder.Core.Event
|
|||
public long TotalOutputVideoByteCount { get; set; }
|
||||
public long TotalOutputAudioByteCount { get; set; }
|
||||
|
||||
public long CurrnetFileSize { get; set; }
|
||||
|
||||
public double AddedDuration { get; set; }
|
||||
public double PassedTime { get; set; }
|
||||
public double DuraionRatio { get; set; }
|
||||
|
|
|
@ -7,22 +7,37 @@ namespace BililiveRecorder.Core.ProcessingRules
|
|||
{
|
||||
public class SplitRule : IFullProcessingRule
|
||||
{
|
||||
private static readonly FlvProcessingContext NewFileContext = new FlvProcessingContext(PipelineNewFileAction.Instance, new Dictionary<object, object?>());
|
||||
private static readonly FlvProcessingContext NewFileContext =
|
||||
new FlvProcessingContext(PipelineNewFileAction.Instance, new Dictionary<object, object?>());
|
||||
|
||||
// 0 = false, 1 = true
|
||||
// 0 = none, 1 = after, 2 = before
|
||||
private int splitFlag = 0;
|
||||
|
||||
private const int FLAG_NONE = 0;
|
||||
private const int FLAG_BEFORE = 1;
|
||||
private const int FLAG_AFTER = 2;
|
||||
|
||||
public async Task RunAsync(FlvProcessingContext context, ProcessingDelegate next)
|
||||
{
|
||||
await next(context).ConfigureAwait(false);
|
||||
var flag = Interlocked.Exchange(ref this.splitFlag, FLAG_NONE);
|
||||
|
||||
if (1 == Interlocked.Exchange(ref this.splitFlag, 0))
|
||||
if (FLAG_BEFORE == flag)
|
||||
{
|
||||
await next(NewFileContext).ConfigureAwait(false);
|
||||
context.AddNewFileAtStart();
|
||||
}
|
||||
|
||||
await next(context).ConfigureAwait(false);
|
||||
|
||||
if (FLAG_AFTER == flag)
|
||||
{
|
||||
await next(NewFileContext).ConfigureAwait(false);
|
||||
context.AddNewFileAtEnd();
|
||||
}
|
||||
}
|
||||
|
||||
public void SetSplitFlag() => Interlocked.Exchange(ref this.splitFlag, 1);
|
||||
public void SetSplitBeforeFlag() => Interlocked.Exchange(ref this.splitFlag, FLAG_BEFORE);
|
||||
|
||||
public void SetSplitAfterFlag() => Interlocked.Exchange(ref this.splitFlag, FLAG_AFTER);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,23 +10,34 @@ namespace BililiveRecorder.Core.ProcessingRules
|
|||
{
|
||||
public class StatsRule : ISimpleProcessingRule
|
||||
{
|
||||
public const string SkipStatsKey = nameof(SkipStatsKey);
|
||||
|
||||
public event EventHandler<RecordingStatsEventArgs>? StatsUpdated;
|
||||
|
||||
public long TotalInputVideoByteCount { get; private set; }
|
||||
public long TotalInputAudioByteCount { get; private set; }
|
||||
// 两个值相加可得出总数据量
|
||||
|
||||
public int TotalOutputVideoFrameCount { get; private set; }
|
||||
public int TotalOutputAudioFrameCount { get; private set; }
|
||||
public long TotalOutputVideoByteCount { get; private set; }
|
||||
public long TotalOutputAudioByteCount { get; private set; }
|
||||
|
||||
public long CurrnetFileSize { get; private set; } = 13;
|
||||
|
||||
public int SumOfMaxTimestampOfClosedFiles { get; private set; }
|
||||
public int CurrentFileMaxTimestamp { get; private set; }
|
||||
|
||||
public DateTimeOffset LastWriteTime { get; private set; }
|
||||
|
||||
public async Task RunAsync(FlvProcessingContext context, Func<Task> next)
|
||||
public Task RunAsync(FlvProcessingContext context, Func<Task> next)
|
||||
{
|
||||
if (context.LocalItems.ContainsKey(SkipStatsKey))
|
||||
return next();
|
||||
else
|
||||
return this.RunCoreAsync(context, next);
|
||||
}
|
||||
|
||||
private async Task RunCoreAsync(FlvProcessingContext context, Func<Task> next)
|
||||
{
|
||||
var e = new RecordingStatsEventArgs();
|
||||
|
||||
|
@ -60,8 +71,6 @@ namespace BililiveRecorder.Core.ProcessingRules
|
|||
}
|
||||
}
|
||||
|
||||
var maxTimestampBeforeCalc = this.CurrentFileMaxTimestamp;
|
||||
|
||||
foreach (var item in groups)
|
||||
{
|
||||
if (item is null)
|
||||
|
@ -70,7 +79,6 @@ namespace BililiveRecorder.Core.ProcessingRules
|
|||
CalcStats(e, item);
|
||||
}
|
||||
|
||||
e.AddedDuration = (this.CurrentFileMaxTimestamp - maxTimestampBeforeCalc) / 1000d;
|
||||
var now = DateTimeOffset.UtcNow;
|
||||
e.PassedTime = (now - this.LastWriteTime).TotalSeconds;
|
||||
this.LastWriteTime = now;
|
||||
|
@ -88,10 +96,17 @@ namespace BililiveRecorder.Core.ProcessingRules
|
|||
e.TotalOutputVideoByteCount = this.TotalOutputVideoByteCount += e.OutputVideoByteCount = dataActions.Sum(x => x.Tags.Where(x => x.Type == TagType.Video).Sum(x => (x.Nalus == null ? x.Size : (5 + x.Nalus.Sum(n => n.FullSize + 4))) + (11 + 4)));
|
||||
e.TotalOutputAudioByteCount = this.TotalOutputAudioByteCount += e.OutputAudioByteCount = dataActions.Sum(x => x.Tags.Where(x => x.Type == TagType.Audio).Sum(x => x.Size + (11 + 4)));
|
||||
|
||||
var lastTags = dataActions[dataActions.Count - 1].Tags;
|
||||
if (lastTags.Count > 0)
|
||||
this.CurrentFileMaxTimestamp = e.FileMaxTimestamp = lastTags[lastTags.Count - 1].Timestamp;
|
||||
e.CurrnetFileSize = this.CurrnetFileSize += e.OutputVideoByteCount + e.OutputAudioByteCount;
|
||||
|
||||
foreach (var action in dataActions)
|
||||
{
|
||||
var tags = action.Tags;
|
||||
if (tags.Count > 0)
|
||||
{
|
||||
e.AddedDuration += (tags[tags.Count - 1].Timestamp - tags[0].Timestamp) / 1000d;
|
||||
this.CurrentFileMaxTimestamp = e.FileMaxTimestamp = tags[tags.Count - 1].Timestamp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
e.SessionMaxTimestamp = this.SumOfMaxTimestampOfClosedFiles + this.CurrentFileMaxTimestamp;
|
||||
|
@ -101,6 +116,7 @@ namespace BililiveRecorder.Core.ProcessingRules
|
|||
{
|
||||
this.SumOfMaxTimestampOfClosedFiles += this.CurrentFileMaxTimestamp;
|
||||
this.CurrentFileMaxTimestamp = 0;
|
||||
this.CurrnetFileSize = 13;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,8 +79,8 @@ namespace BililiveRecorder.Core.Recording
|
|||
this.statsRule.StatsUpdated += this.StatsRule_StatsUpdated;
|
||||
|
||||
this.pipeline = builder
|
||||
.Add(this.splitFileRule)
|
||||
.Add(this.statsRule)
|
||||
.Add(this.splitFileRule)
|
||||
.AddDefault()
|
||||
.AddRemoveFillerData()
|
||||
.Build();
|
||||
|
@ -111,7 +111,7 @@ namespace BililiveRecorder.Core.Recording
|
|||
public event EventHandler<RecordFileClosedEventArgs>? RecordFileClosed;
|
||||
public event EventHandler? RecordSessionEnded;
|
||||
|
||||
public void SplitOutput() => this.splitFileRule.SetSplitFlag();
|
||||
public void SplitOutput() => this.splitFileRule.SetSplitBeforeFlag();
|
||||
|
||||
public void RequestStop() => this.cts.Cancel();
|
||||
|
||||
|
@ -252,10 +252,11 @@ namespace BililiveRecorder.Core.Recording
|
|||
|
||||
private async Task RecordingLoopAsync()
|
||||
{
|
||||
if (this.reader is null) return;
|
||||
if (this.writer is null) return;
|
||||
try
|
||||
{
|
||||
if (this.reader is null) return;
|
||||
if (this.writer is null) return;
|
||||
|
||||
while (!this.ct.IsCancellationRequested)
|
||||
{
|
||||
var group = await this.reader.ReadGroupAsync(this.ct).ConfigureAwait(false);
|
||||
|
@ -383,12 +384,16 @@ namespace BililiveRecorder.Core.Recording
|
|||
|
||||
private void StatsRule_StatsUpdated(object sender, RecordingStatsEventArgs e)
|
||||
{
|
||||
if (this.room.RoomConfig.CuttingMode == Config.V2.CuttingMode.ByTime)
|
||||
switch (this.room.RoomConfig.CuttingMode)
|
||||
{
|
||||
if (e.FileMaxTimestamp > (this.room.RoomConfig.CuttingNumber * (60 * 1000)))
|
||||
{
|
||||
this.splitFileRule.SetSplitFlag();
|
||||
}
|
||||
case Config.V2.CuttingMode.ByTime:
|
||||
if (e.FileMaxTimestamp > this.room.RoomConfig.CuttingNumber * (60u * 1000u))
|
||||
this.splitFileRule.SetSplitBeforeFlag();
|
||||
break;
|
||||
case Config.V2.CuttingMode.BySize:
|
||||
if ((e.CurrnetFileSize + (e.OutputVideoByteCount * 1.1) + e.OutputAudioByteCount) / (1024d * 1024d) > this.room.RoomConfig.CuttingNumber)
|
||||
this.splitFileRule.SetSplitBeforeFlag();
|
||||
break;
|
||||
}
|
||||
|
||||
RecordingStats?.Invoke(this, e);
|
||||
|
@ -411,15 +416,7 @@ namespace BililiveRecorder.Core.Recording
|
|||
this.OnNewFile = onNewFile ?? throw new ArgumentNullException(nameof(onNewFile));
|
||||
}
|
||||
|
||||
public bool ShouldCreateNewFile(Stream outputStream, IList<Tag> tags)
|
||||
{
|
||||
if (this.room.RoomConfig.CuttingMode == Config.V2.CuttingMode.BySize)
|
||||
{
|
||||
var pendingSize = tags.Sum(x => (x.Nalus == null ? x.Size : (5 + x.Nalus.Sum(n => n.FullSize + 4))) + (11 + 4));
|
||||
return (outputStream.Length + pendingSize) > (this.room.RoomConfig.CuttingNumber * (1024 * 1024));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public bool ShouldCreateNewFile(Stream outputStream, IList<Tag> tags) => false;
|
||||
|
||||
public (Stream stream, object state) CreateOutputStream()
|
||||
{
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.CommandLine;
|
||||
using System.CommandLine.Invocation;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.ExceptionServices;
|
||||
using System.Security;
|
||||
|
@ -29,6 +30,8 @@ namespace BililiveRecorder.WPF
|
|||
static Program()
|
||||
{
|
||||
levelSwitchGlobal = new LoggingLevelSwitch(Serilog.Events.LogEventLevel.Debug);
|
||||
if (Debugger.IsAttached)
|
||||
levelSwitchGlobal.MinimumLevel = Serilog.Events.LogEventLevel.Verbose;
|
||||
levelSwitchConsole = new LoggingLevelSwitch(Serilog.Events.LogEventLevel.Error);
|
||||
logger = BuildLogger();
|
||||
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
||||
|
@ -144,9 +147,13 @@ namespace BililiveRecorder.WPF
|
|||
.Enrich.WithThreadName()
|
||||
.Enrich.FromLogContext()
|
||||
.Enrich.WithExceptionDetails()
|
||||
.WriteTo.Debug()
|
||||
.WriteTo.Console(levelSwitch: levelSwitchConsole)
|
||||
.WriteTo.Sink<WpfLogEventSink>(Serilog.Events.LogEventLevel.Debug) // TODO level
|
||||
#if DEBUG
|
||||
.WriteTo.Debug()
|
||||
.WriteTo.Sink<WpfLogEventSink>(Serilog.Events.LogEventLevel.Debug)
|
||||
#else
|
||||
.WriteTo.Sink<WpfLogEventSink>(Serilog.Events.LogEventLevel.Information)
|
||||
#endif
|
||||
.WriteTo.File(new CompactJsonFormatter(), "./logs/bilirec.txt", shared: true, rollingInterval: RollingInterval.Day)
|
||||
.WriteTo.Sentry(o =>
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Block a user