2018-03-21 20:56:56 +08:00
|
|
|
using System;
|
2018-03-12 18:57:20 +08:00
|
|
|
using System.Collections.ObjectModel;
|
2018-11-28 22:29:35 +08:00
|
|
|
using System.ComponentModel;
|
2018-03-24 09:48:06 +08:00
|
|
|
using System.Linq;
|
2021-02-23 18:03:37 +08:00
|
|
|
using System.Threading.Tasks;
|
2020-11-27 18:51:02 +08:00
|
|
|
using BililiveRecorder.Core.Config;
|
2021-01-01 14:46:27 +08:00
|
|
|
using BililiveRecorder.Core.Config.V2;
|
2021-02-23 18:03:37 +08:00
|
|
|
using BililiveRecorder.Core.Event;
|
|
|
|
using BililiveRecorder.Core.SimpleWebhook;
|
2021-04-20 20:41:26 +08:00
|
|
|
using Serilog;
|
2018-03-12 18:57:20 +08:00
|
|
|
|
|
|
|
namespace BililiveRecorder.Core
|
|
|
|
{
|
2018-11-28 22:29:35 +08:00
|
|
|
public class Recorder : IRecorder
|
2018-03-12 18:57:20 +08:00
|
|
|
{
|
2021-02-23 18:03:37 +08:00
|
|
|
private readonly object lockObject = new object();
|
|
|
|
private readonly ObservableCollection<IRoom> roomCollection;
|
|
|
|
private readonly IRoomFactory roomFactory;
|
2021-04-20 20:41:26 +08:00
|
|
|
private readonly ILogger logger;
|
2021-02-23 18:03:37 +08:00
|
|
|
private readonly BasicWebhookV1 basicWebhookV1;
|
|
|
|
private readonly BasicWebhookV2 basicWebhookV2;
|
2018-03-21 20:56:56 +08:00
|
|
|
|
2020-11-27 18:51:02 +08:00
|
|
|
private bool disposedValue;
|
|
|
|
|
2021-04-20 20:41:26 +08:00
|
|
|
public Recorder(IRoomFactory roomFactory, ConfigV2 config, ILogger logger)
|
2018-03-20 00:12:32 +08:00
|
|
|
{
|
2021-02-23 18:03:37 +08:00
|
|
|
this.roomFactory = roomFactory ?? throw new ArgumentNullException(nameof(roomFactory));
|
|
|
|
this.Config = config ?? throw new ArgumentNullException(nameof(config));
|
2021-04-20 20:41:26 +08:00
|
|
|
this.logger = logger?.ForContext<Recorder>() ?? throw new ArgumentNullException(nameof(logger));
|
2021-02-23 18:03:37 +08:00
|
|
|
this.roomCollection = new ObservableCollection<IRoom>();
|
|
|
|
this.Rooms = new ReadOnlyObservableCollection<IRoom>(this.roomCollection);
|
2018-11-10 12:17:41 +08:00
|
|
|
|
2021-02-23 18:03:37 +08:00
|
|
|
this.basicWebhookV1 = new BasicWebhookV1(config);
|
|
|
|
this.basicWebhookV2 = new BasicWebhookV2(config.Global);
|
2018-03-20 00:12:32 +08:00
|
|
|
|
2018-04-14 05:22:56 +08:00
|
|
|
{
|
2021-05-17 23:29:33 +08:00
|
|
|
logger.Debug("Recorder created with {RoomCount} rooms", config.Rooms.Count);
|
2021-04-30 19:35:15 +08:00
|
|
|
for (var i = 0; i < config.Rooms.Count; i++)
|
|
|
|
{
|
|
|
|
var item = config.Rooms[i];
|
|
|
|
if (item is not null)
|
|
|
|
this.AddRoom(roomConfig: item, initDelayFactor: i);
|
|
|
|
}
|
|
|
|
|
2021-02-23 18:03:37 +08:00
|
|
|
this.SaveConfig();
|
2018-04-14 05:22:56 +08:00
|
|
|
}
|
2018-03-20 00:12:32 +08:00
|
|
|
}
|
2018-03-12 18:57:20 +08:00
|
|
|
|
2021-02-23 18:03:37 +08:00
|
|
|
public event EventHandler<AggregatedRoomEventArgs<RecordSessionStartedEventArgs>>? RecordSessionStarted;
|
|
|
|
public event EventHandler<AggregatedRoomEventArgs<RecordSessionEndedEventArgs>>? RecordSessionEnded;
|
|
|
|
public event EventHandler<AggregatedRoomEventArgs<RecordFileOpeningEventArgs>>? RecordFileOpening;
|
|
|
|
public event EventHandler<AggregatedRoomEventArgs<RecordFileClosedEventArgs>>? RecordFileClosed;
|
|
|
|
public event EventHandler<AggregatedRoomEventArgs<NetworkingStatsEventArgs>>? NetworkingStats;
|
|
|
|
public event EventHandler<AggregatedRoomEventArgs<RecordingStatsEventArgs>>? RecordingStats;
|
|
|
|
public event PropertyChangedEventHandler? PropertyChanged;
|
2021-01-04 16:24:36 +08:00
|
|
|
|
2021-02-23 18:03:37 +08:00
|
|
|
public ConfigV2 Config { get; }
|
2021-01-04 16:24:36 +08:00
|
|
|
|
2021-02-23 18:03:37 +08:00
|
|
|
public ReadOnlyObservableCollection<IRoom> Rooms { get; }
|
2021-01-04 16:24:36 +08:00
|
|
|
|
2021-01-01 14:46:27 +08:00
|
|
|
public void AddRoom(int roomid) => this.AddRoom(roomid, true);
|
2018-11-10 12:17:41 +08:00
|
|
|
|
|
|
|
public void AddRoom(int roomid, bool enabled)
|
2018-03-21 20:56:56 +08:00
|
|
|
{
|
2021-02-23 18:03:37 +08:00
|
|
|
lock (this.lockObject)
|
2018-10-25 19:20:23 +08:00
|
|
|
{
|
2021-05-17 23:29:33 +08:00
|
|
|
this.logger.Debug("AddRoom {RoomId}, AutoRecord: {AutoRecord}", roomid, enabled);
|
2021-02-23 18:03:37 +08:00
|
|
|
var roomConfig = new RoomConfig { RoomId = roomid, AutoRecord = enabled };
|
2021-04-30 19:35:15 +08:00
|
|
|
this.AddRoom(roomConfig, 0);
|
2021-02-23 18:03:37 +08:00
|
|
|
this.SaveConfig();
|
2021-01-01 14:46:27 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-30 19:35:15 +08:00
|
|
|
private void AddRoom(RoomConfig roomConfig, int initDelayFactor)
|
2021-01-01 14:46:27 +08:00
|
|
|
{
|
2021-02-23 18:03:37 +08:00
|
|
|
roomConfig.SetParent(this.Config.Global);
|
2021-04-30 19:35:15 +08:00
|
|
|
var room = this.roomFactory.CreateRoom(roomConfig, initDelayFactor);
|
2021-02-23 18:03:37 +08:00
|
|
|
this.roomCollection.Add(room);
|
|
|
|
this.AddEventSubscription(room);
|
|
|
|
}
|
2019-03-01 18:00:20 +08:00
|
|
|
|
2021-02-23 18:03:37 +08:00
|
|
|
public void RemoveRoom(IRoom room)
|
|
|
|
{
|
|
|
|
lock (this.lockObject)
|
2018-10-25 19:20:23 +08:00
|
|
|
{
|
2021-02-23 18:03:37 +08:00
|
|
|
if (this.roomCollection.Remove(room))
|
|
|
|
{
|
|
|
|
this.RemoveEventSubscription(room);
|
2021-05-17 23:29:33 +08:00
|
|
|
this.logger.Debug("RemoveRoom {RoomId}", room.RoomConfig.RoomId);
|
2021-02-23 18:03:37 +08:00
|
|
|
room.Dispose();
|
2021-05-17 23:29:33 +08:00
|
|
|
this.SaveConfig();
|
2021-02-23 18:03:37 +08:00
|
|
|
}
|
2018-10-25 19:20:23 +08:00
|
|
|
}
|
2018-03-21 20:56:56 +08:00
|
|
|
}
|
|
|
|
|
2021-02-23 18:03:37 +08:00
|
|
|
public void SaveConfig()
|
2018-03-24 02:27:58 +08:00
|
|
|
{
|
2021-02-23 18:03:37 +08:00
|
|
|
this.Config.Rooms = this.Rooms.Select(x => x.RoomConfig).ToList();
|
|
|
|
ConfigParser.SaveTo(this.Config.Global.WorkDirectory!, this.Config);
|
2018-03-24 02:27:58 +08:00
|
|
|
}
|
2018-03-24 09:48:06 +08:00
|
|
|
|
2021-02-23 18:03:37 +08:00
|
|
|
#region Events
|
2019-08-14 21:41:41 +08:00
|
|
|
|
2021-02-23 18:03:37 +08:00
|
|
|
private void AddEventSubscription(IRoom room)
|
|
|
|
{
|
|
|
|
room.RecordSessionStarted += this.Room_RecordSessionStarted;
|
|
|
|
room.RecordSessionEnded += this.Room_RecordSessionEnded;
|
|
|
|
room.RecordFileOpening += this.Room_RecordFileOpening;
|
|
|
|
room.RecordFileClosed += this.Room_RecordFileClosed;
|
|
|
|
room.NetworkingStats += this.Room_NetworkingStats;
|
|
|
|
room.RecordingStats += this.Room_RecordingStats;
|
|
|
|
room.PropertyChanged += this.Room_PropertyChanged;
|
|
|
|
}
|
2020-11-27 18:51:02 +08:00
|
|
|
|
2021-02-23 18:03:37 +08:00
|
|
|
private void Room_NetworkingStats(object sender, NetworkingStatsEventArgs e)
|
|
|
|
{
|
|
|
|
var room = (IRoom)sender;
|
|
|
|
NetworkingStats?.Invoke(this, new AggregatedRoomEventArgs<NetworkingStatsEventArgs>(room, e));
|
2019-08-14 21:41:41 +08:00
|
|
|
}
|
|
|
|
|
2021-02-23 18:03:37 +08:00
|
|
|
private void Room_RecordingStats(object sender, RecordingStatsEventArgs e)
|
|
|
|
{
|
|
|
|
var room = (IRoom)sender;
|
|
|
|
RecordingStats?.Invoke(this, new AggregatedRoomEventArgs<RecordingStatsEventArgs>(room, e));
|
|
|
|
}
|
2020-12-20 20:56:40 +08:00
|
|
|
|
2021-02-23 18:03:37 +08:00
|
|
|
private void Room_RecordFileClosed(object sender, RecordFileClosedEventArgs e)
|
2019-08-14 21:41:41 +08:00
|
|
|
{
|
2021-02-23 18:03:37 +08:00
|
|
|
var room = (IRoom)sender;
|
|
|
|
_ = Task.Run(async () => await this.basicWebhookV2.SendFileClosedAsync(e).ConfigureAwait(false));
|
|
|
|
_ = Task.Run(async () => await this.basicWebhookV1.SendAsync(new RecordEndData(e)).ConfigureAwait(false));
|
|
|
|
RecordFileClosed?.Invoke(this, new AggregatedRoomEventArgs<RecordFileClosedEventArgs>(room, e));
|
|
|
|
}
|
2018-11-02 21:02:25 +08:00
|
|
|
|
2021-02-23 18:03:37 +08:00
|
|
|
private void Room_RecordFileOpening(object sender, RecordFileOpeningEventArgs e)
|
|
|
|
{
|
|
|
|
var room = (IRoom)sender;
|
|
|
|
_ = Task.Run(async () => await this.basicWebhookV2.SendFileOpeningAsync(e).ConfigureAwait(false));
|
|
|
|
RecordFileOpening?.Invoke(this, new AggregatedRoomEventArgs<RecordFileOpeningEventArgs>(room, e));
|
2018-03-24 09:48:06 +08:00
|
|
|
}
|
2018-11-01 23:40:50 +08:00
|
|
|
|
2021-02-23 18:03:37 +08:00
|
|
|
private void Room_RecordSessionStarted(object sender, RecordSessionStartedEventArgs e)
|
2018-11-01 23:40:50 +08:00
|
|
|
{
|
2021-02-23 18:03:37 +08:00
|
|
|
var room = (IRoom)sender;
|
|
|
|
_ = Task.Run(async () => await this.basicWebhookV2.SendSessionStartedAsync(e).ConfigureAwait(false));
|
|
|
|
RecordSessionStarted?.Invoke(this, new AggregatedRoomEventArgs<RecordSessionStartedEventArgs>(room, e));
|
2018-11-01 23:40:50 +08:00
|
|
|
}
|
|
|
|
|
2021-02-23 18:03:37 +08:00
|
|
|
private void Room_RecordSessionEnded(object sender, RecordSessionEndedEventArgs e)
|
|
|
|
{
|
|
|
|
var room = (IRoom)sender;
|
|
|
|
_ = Task.Run(async () => await this.basicWebhookV2.SendSessionEndedAsync(e).ConfigureAwait(false));
|
|
|
|
RecordSessionEnded?.Invoke(this, new AggregatedRoomEventArgs<RecordSessionEndedEventArgs>(room, e));
|
|
|
|
}
|
2018-11-28 22:29:35 +08:00
|
|
|
|
2021-02-23 18:03:37 +08:00
|
|
|
private void Room_PropertyChanged(object sender, PropertyChangedEventArgs e)
|
2020-11-27 18:51:02 +08:00
|
|
|
{
|
2021-02-23 18:03:37 +08:00
|
|
|
// TODO
|
|
|
|
// throw new NotImplementedException();
|
2020-11-27 18:51:02 +08:00
|
|
|
}
|
|
|
|
|
2021-02-23 18:03:37 +08:00
|
|
|
private void RemoveEventSubscription(IRoom room)
|
2020-11-27 18:51:02 +08:00
|
|
|
{
|
2021-02-23 18:03:37 +08:00
|
|
|
room.RecordSessionStarted -= this.Room_RecordSessionStarted;
|
|
|
|
room.RecordSessionEnded -= this.Room_RecordSessionEnded;
|
|
|
|
room.RecordFileOpening -= this.Room_RecordFileOpening;
|
|
|
|
room.RecordFileClosed -= this.Room_RecordFileClosed;
|
|
|
|
room.RecordingStats -= this.Room_RecordingStats;
|
|
|
|
room.PropertyChanged -= this.Room_PropertyChanged;
|
2020-11-27 18:51:02 +08:00
|
|
|
}
|
|
|
|
|
2021-02-23 18:03:37 +08:00
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region Dispose
|
|
|
|
|
2020-11-27 18:51:02 +08:00
|
|
|
protected virtual void Dispose(bool disposing)
|
|
|
|
{
|
2021-01-01 14:46:27 +08:00
|
|
|
if (!this.disposedValue)
|
2020-11-27 18:51:02 +08:00
|
|
|
{
|
|
|
|
if (disposing)
|
|
|
|
{
|
|
|
|
// dispose managed state (managed objects)
|
2021-04-20 20:41:26 +08:00
|
|
|
this.logger.Debug("Dispose called");
|
2021-02-23 18:03:37 +08:00
|
|
|
this.SaveConfig();
|
|
|
|
foreach (var room in this.roomCollection)
|
|
|
|
room.Dispose();
|
2020-11-27 18:51:02 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// free unmanaged resources (unmanaged objects) and override finalizer
|
|
|
|
// set large fields to null
|
2021-01-01 14:46:27 +08:00
|
|
|
this.disposedValue = true;
|
2020-11-27 18:51:02 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
|
|
|
|
// ~Recorder()
|
|
|
|
// {
|
|
|
|
// // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
|
|
|
// Dispose(disposing: false);
|
|
|
|
// }
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
{
|
|
|
|
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
2021-01-01 14:46:27 +08:00
|
|
|
this.Dispose(disposing: true);
|
2020-11-27 18:51:02 +08:00
|
|
|
GC.SuppressFinalize(this);
|
|
|
|
}
|
2021-02-23 18:03:37 +08:00
|
|
|
|
|
|
|
#endregion
|
2018-03-12 18:57:20 +08:00
|
|
|
}
|
|
|
|
}
|