diff --git a/BililiveRecorder.Cli/BililiveRecorder.Cli.csproj b/BililiveRecorder.Cli/BililiveRecorder.Cli.csproj
index b671d53..340a5f7 100644
--- a/BililiveRecorder.Cli/BililiveRecorder.Cli.csproj
+++ b/BililiveRecorder.Cli/BililiveRecorder.Cli.csproj
@@ -33,6 +33,7 @@
+
diff --git a/BililiveRecorder.Cli/Program.cs b/BililiveRecorder.Cli/Program.cs
index eacdb7f..db2bc55 100644
--- a/BililiveRecorder.Cli/Program.cs
+++ b/BililiveRecorder.Cli/Program.cs
@@ -9,6 +9,7 @@ using BililiveRecorder.Core;
using BililiveRecorder.Core.Config;
using BililiveRecorder.Core.Config.V2;
using BililiveRecorder.DependencyInjection;
+using BililiveRecorder.ToolBox;
using Microsoft.Extensions.DependencyInjection;
using Serilog;
using Serilog.Events;
@@ -39,7 +40,8 @@ namespace BililiveRecorder.Cli
var root = new RootCommand("A Stream Recorder For Bilibili Live")
{
cmd_run,
- cmd_portable
+ cmd_portable,
+ new ToolCommand()
};
return root.Invoke(args);
@@ -85,7 +87,8 @@ namespace BililiveRecorder.Cli
var logger = BuildLogger();
Log.Logger = logger;
- var config = new ConfigV2(){
+ var config = new ConfigV2()
+ {
DisableConfigSave = true,
};
diff --git a/BililiveRecorder.Flv/Writer/FlvTagFileWriter.cs b/BililiveRecorder.Flv/Writer/FlvTagFileWriter.cs
index 26ee860..0e66bfe 100644
--- a/BililiveRecorder.Flv/Writer/FlvTagFileWriter.cs
+++ b/BililiveRecorder.Flv/Writer/FlvTagFileWriter.cs
@@ -34,7 +34,7 @@ namespace BililiveRecorder.Flv.Writer
public bool CloseCurrentFile()
{
- if (this.disposedValue)
+ if (this.disposedValue)
throw new ObjectDisposedException(nameof(FlvTagFileWriter));
if (this.stream is null)
@@ -52,6 +52,7 @@ namespace BililiveRecorder.Flv.Writer
if (this.disposedValue)
throw new ObjectDisposedException(nameof(FlvTagFileWriter));
+ System.Diagnostics.Debug.Assert(this.stream is null, "stream is not null");
this.stream?.Dispose();
(this.stream, this.State) = this.targetProvider.CreateOutputStream();
diff --git a/BililiveRecorder.ToolBox/BililiveRecorder.ToolBox.csproj b/BililiveRecorder.ToolBox/BililiveRecorder.ToolBox.csproj
new file mode 100644
index 0000000..2957349
--- /dev/null
+++ b/BililiveRecorder.ToolBox/BililiveRecorder.ToolBox.csproj
@@ -0,0 +1,16 @@
+
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/BililiveRecorder.ToolBox/Commands/Analyze.cs b/BililiveRecorder.ToolBox/Commands/Analyze.cs
new file mode 100644
index 0000000..99131d3
--- /dev/null
+++ b/BililiveRecorder.ToolBox/Commands/Analyze.cs
@@ -0,0 +1,158 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.IO.Pipelines;
+using System.Linq;
+using System.Threading.Tasks;
+using BililiveRecorder.Flv;
+using BililiveRecorder.Flv.Amf;
+using BililiveRecorder.Flv.Grouping;
+using BililiveRecorder.Flv.Parser;
+using BililiveRecorder.Flv.Pipeline;
+using BililiveRecorder.Flv.Writer;
+using Microsoft.Extensions.DependencyInjection;
+using Serilog;
+
+namespace BililiveRecorder.ToolBox.Commands
+{
+ public class AnalyzeRequest : ICommandRequest
+ {
+ public string Input { get; set; } = string.Empty;
+ }
+
+ public class AnalyzeResponse
+ {
+ public string InputPath { get; set; } = string.Empty;
+
+ public bool NeedFix { get; set; }
+ public bool Unrepairable { get; set; }
+
+ public int OutputFileCount { get; set; }
+
+ public int IssueTypeOther { get; set; }
+ public int IssueTypeUnrepairable { get; set; }
+ public int IssueTypeTimestampJump { get; set; }
+ public int IssueTypeDecodingHeader { get; set; }
+ public int IssueTypeRepeatingData { get; set; }
+ }
+
+ public class AnalyzeHandler : ICommandHandler
+ {
+ private static readonly ILogger logger = Log.ForContext();
+
+ public Task Handle(AnalyzeRequest request) => this.Handle(request, null);
+
+ public async Task Handle(AnalyzeRequest request, Func? progress)
+ {
+ var inputPath = Path.GetFullPath(request.Input);
+
+ var memoryStreamProvider = new DefaultMemoryStreamProvider();
+ var tagWriter = new AnalyzeMockFlvTagWriter();
+ var comments = new List();
+ var context = new FlvProcessingContext();
+ var session = new Dictionary