2020-12-21 19:08:44 +08:00
|
|
|
using System;
|
2021-01-04 16:24:36 +08:00
|
|
|
using System.Collections.Generic;
|
2021-02-23 18:03:37 +08:00
|
|
|
using System.CommandLine;
|
|
|
|
using System.CommandLine.Invocation;
|
|
|
|
using System.IO;
|
2020-01-05 23:47:38 +08:00
|
|
|
using System.Linq;
|
|
|
|
using System.Threading;
|
|
|
|
using BililiveRecorder.Core;
|
2021-02-23 18:03:37 +08:00
|
|
|
using BililiveRecorder.Core.Config;
|
2021-01-04 16:24:36 +08:00
|
|
|
using BililiveRecorder.Core.Config.V2;
|
2021-02-08 16:51:19 +08:00
|
|
|
using BililiveRecorder.DependencyInjection;
|
2021-04-14 23:46:24 +08:00
|
|
|
using BililiveRecorder.ToolBox;
|
2021-02-08 16:51:19 +08:00
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
2021-02-23 18:03:37 +08:00
|
|
|
using Serilog;
|
2021-05-02 22:24:57 +08:00
|
|
|
using Serilog.Core;
|
2021-02-23 18:03:37 +08:00
|
|
|
using Serilog.Events;
|
|
|
|
using Serilog.Exceptions;
|
2021-05-02 22:24:57 +08:00
|
|
|
using Serilog.Formatting.Compact;
|
2020-01-05 23:47:38 +08:00
|
|
|
|
|
|
|
namespace BililiveRecorder.Cli
|
|
|
|
{
|
2020-12-21 19:08:44 +08:00
|
|
|
internal class Program
|
2020-01-05 23:47:38 +08:00
|
|
|
{
|
2021-01-26 20:06:00 +08:00
|
|
|
private static int Main(string[] args)
|
2021-02-23 18:03:37 +08:00
|
|
|
{
|
|
|
|
var cmd_run = new Command("run", "Run BililiveRecorder in standard mode")
|
|
|
|
{
|
|
|
|
new Argument<string>("path"),
|
|
|
|
};
|
|
|
|
cmd_run.Handler = CommandHandler.Create<string>(RunConfigMode);
|
|
|
|
|
|
|
|
var cmd_portable = new Command("portable", "Run BililiveRecorder in config-less mode")
|
|
|
|
{
|
|
|
|
new Option<string>(new []{ "--cookie", "-c" }, "Cookie string for api requests"),
|
|
|
|
new Option<string>("--live-api-host"),
|
|
|
|
new Option<string>(new[]{ "--filename-format", "-f" }, "File name format"),
|
2021-04-09 15:56:36 +08:00
|
|
|
new Argument<string>("output-path"),
|
|
|
|
new Argument<int[]>("room-ids")
|
2021-02-23 18:03:37 +08:00
|
|
|
};
|
|
|
|
cmd_portable.Handler = CommandHandler.Create<PortableModeArguments>(RunPortableMode);
|
|
|
|
|
|
|
|
var root = new RootCommand("A Stream Recorder For Bilibili Live")
|
|
|
|
{
|
|
|
|
cmd_run,
|
2021-04-14 23:46:24 +08:00
|
|
|
cmd_portable,
|
|
|
|
new ToolCommand()
|
2021-02-23 18:03:37 +08:00
|
|
|
};
|
2020-01-05 23:47:38 +08:00
|
|
|
|
2021-02-23 18:03:37 +08:00
|
|
|
return root.Invoke(args);
|
|
|
|
}
|
|
|
|
|
|
|
|
private static int RunConfigMode(string path)
|
2020-01-05 23:47:38 +08:00
|
|
|
{
|
2021-05-02 22:24:57 +08:00
|
|
|
using var logger = BuildLogger();
|
2021-02-23 18:03:37 +08:00
|
|
|
Log.Logger = logger;
|
|
|
|
|
|
|
|
path = Path.GetFullPath(path);
|
|
|
|
var config = ConfigParser.LoadFrom(path);
|
|
|
|
if (config is null)
|
|
|
|
{
|
|
|
|
logger.Error("Initialize Error");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
config.Global.WorkDirectory = path;
|
2021-02-08 16:51:19 +08:00
|
|
|
|
2021-02-23 18:03:37 +08:00
|
|
|
var serviceProvider = BuildServiceProvider(config, logger);
|
2021-02-08 16:51:19 +08:00
|
|
|
var recorder = serviceProvider.GetRequiredService<IRecorder>();
|
2021-01-01 14:52:53 +08:00
|
|
|
|
2021-01-04 16:24:36 +08:00
|
|
|
ConsoleCancelEventHandler p = null!;
|
2021-02-23 18:03:37 +08:00
|
|
|
var semaphore = new SemaphoreSlim(0, 1);
|
2021-01-04 16:24:36 +08:00
|
|
|
p = (sender, e) =>
|
|
|
|
{
|
|
|
|
Console.CancelKeyPress -= p;
|
|
|
|
e.Cancel = true;
|
|
|
|
recorder.Dispose();
|
|
|
|
semaphore.Release();
|
|
|
|
};
|
|
|
|
Console.CancelKeyPress += p;
|
2020-06-21 21:26:51 +08:00
|
|
|
|
2021-01-04 16:24:36 +08:00
|
|
|
semaphore.Wait();
|
2021-02-23 18:03:37 +08:00
|
|
|
Thread.Sleep(1000 * 2);
|
|
|
|
Console.ReadLine();
|
2021-01-04 16:24:36 +08:00
|
|
|
return 0;
|
2020-01-05 23:47:38 +08:00
|
|
|
}
|
|
|
|
|
2021-02-23 18:03:37 +08:00
|
|
|
private static int RunPortableMode(PortableModeArguments opts)
|
2020-06-21 21:26:51 +08:00
|
|
|
{
|
2021-05-02 22:24:57 +08:00
|
|
|
using var logger = BuildLogger();
|
2021-04-09 15:56:36 +08:00
|
|
|
Log.Logger = logger;
|
2021-02-08 16:51:19 +08:00
|
|
|
|
2021-04-14 23:46:24 +08:00
|
|
|
var config = new ConfigV2()
|
|
|
|
{
|
2021-01-04 16:24:36 +08:00
|
|
|
DisableConfigSave = true,
|
|
|
|
};
|
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(opts.Cookie))
|
|
|
|
config.Global.Cookie = opts.Cookie;
|
|
|
|
if (!string.IsNullOrWhiteSpace(opts.LiveApiHost))
|
|
|
|
config.Global.LiveApiHost = opts.LiveApiHost;
|
2021-02-23 18:03:37 +08:00
|
|
|
if (!string.IsNullOrWhiteSpace(opts.FilenameFormat))
|
|
|
|
config.Global.RecordFilenameFormat = opts.FilenameFormat;
|
2021-01-04 16:24:36 +08:00
|
|
|
|
2021-02-23 18:03:37 +08:00
|
|
|
config.Global.WorkDirectory = opts.OutputPath;
|
2021-01-04 16:24:36 +08:00
|
|
|
config.Rooms = opts.RoomIds.Select(x => new RoomConfig { RoomId = x, AutoRecord = true }).ToList();
|
|
|
|
|
2021-04-09 15:56:36 +08:00
|
|
|
var serviceProvider = BuildServiceProvider(config, logger);
|
|
|
|
var recorder = serviceProvider.GetRequiredService<IRecorder>();
|
|
|
|
|
2021-01-04 16:24:36 +08:00
|
|
|
ConsoleCancelEventHandler p = null!;
|
2021-04-09 15:56:36 +08:00
|
|
|
var semaphore = new SemaphoreSlim(0, 1);
|
2021-01-04 16:24:36 +08:00
|
|
|
p = (sender, e) =>
|
|
|
|
{
|
|
|
|
Console.CancelKeyPress -= p;
|
|
|
|
e.Cancel = true;
|
|
|
|
recorder.Dispose();
|
|
|
|
semaphore.Release();
|
|
|
|
};
|
|
|
|
Console.CancelKeyPress += p;
|
|
|
|
|
|
|
|
semaphore.Wait();
|
2021-04-09 15:56:36 +08:00
|
|
|
Thread.Sleep(1000 * 2);
|
|
|
|
Console.ReadLine();
|
2021-01-04 16:24:36 +08:00
|
|
|
return 0;
|
2020-06-21 21:26:51 +08:00
|
|
|
}
|
2020-12-21 04:13:49 +08:00
|
|
|
|
2021-02-23 18:03:37 +08:00
|
|
|
private static IServiceProvider BuildServiceProvider(ConfigV2 config, ILogger logger) => new ServiceCollection()
|
|
|
|
.AddSingleton(logger)
|
|
|
|
.AddFlv()
|
|
|
|
.AddRecorderConfig(config)
|
|
|
|
.AddRecorder()
|
|
|
|
.BuildServiceProvider();
|
|
|
|
|
2021-05-02 22:24:57 +08:00
|
|
|
private static Logger BuildLogger() => new LoggerConfiguration()
|
2021-02-23 18:03:37 +08:00
|
|
|
.MinimumLevel.Verbose()
|
|
|
|
.Enrich.WithProcessId()
|
|
|
|
.Enrich.WithThreadId()
|
|
|
|
.Enrich.WithThreadName()
|
|
|
|
.Enrich.FromLogContext()
|
|
|
|
.Enrich.WithExceptionDetails()
|
2021-05-02 22:24:57 +08:00
|
|
|
.Destructure.ByTransforming<Flv.Xml.XmlFlvFile.XmlFlvFileMeta>(x => new
|
|
|
|
{
|
|
|
|
x.Version,
|
|
|
|
x.ExportTime,
|
|
|
|
x.FileSize,
|
|
|
|
x.FileCreationTime,
|
|
|
|
x.FileModificationTime,
|
|
|
|
})
|
2021-02-23 18:03:37 +08:00
|
|
|
.WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Verbose, outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] [{RoomId}] {Message:lj}{NewLine}{Exception}")
|
2021-05-02 22:24:57 +08:00
|
|
|
.WriteTo.File(new CompactJsonFormatter(), "./logs/bilirec.txt", shared: true, rollingInterval: RollingInterval.Day, rollOnFileSizeLimit: true)
|
2021-02-23 18:03:37 +08:00
|
|
|
.CreateLogger();
|
|
|
|
|
|
|
|
public class PortableModeArguments
|
2020-12-21 04:13:49 +08:00
|
|
|
{
|
2021-02-23 18:03:37 +08:00
|
|
|
public string OutputPath { get; set; } = string.Empty;
|
2020-12-21 04:13:49 +08:00
|
|
|
|
2021-02-23 18:03:37 +08:00
|
|
|
public string? Cookie { get; set; }
|
2020-12-21 04:13:49 +08:00
|
|
|
|
2021-02-23 18:03:37 +08:00
|
|
|
public string? LiveApiHost { get; set; }
|
2020-12-21 04:13:49 +08:00
|
|
|
|
2021-02-23 18:03:37 +08:00
|
|
|
public string? FilenameFormat { get; set; }
|
2021-01-04 16:24:36 +08:00
|
|
|
|
2021-02-23 18:03:37 +08:00
|
|
|
public IEnumerable<int> RoomIds { get; set; } = Enumerable.Empty<int>();
|
|
|
|
}
|
2020-01-05 23:47:38 +08:00
|
|
|
}
|
2020-12-21 19:08:44 +08:00
|
|
|
}
|