mirror of
https://github.com/BililiveRecorder/BililiveRecorder.git
synced 2024-11-16 03:32:20 +08:00
Autofac
This commit is contained in:
parent
f586e48724
commit
00a14742b7
21
BililiveRecorder.Core/CoreModule.cs
Normal file
21
BililiveRecorder.Core/CoreModule.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
using Autofac;
|
||||
|
||||
namespace BililiveRecorder.Core
|
||||
{
|
||||
public class CoreModule : Module
|
||||
{
|
||||
public CoreModule()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void Load(ContainerBuilder builder)
|
||||
{
|
||||
builder.RegisterType<Settings>().As<ISettings>().InstancePerMatchingLifetimeScope("recorder_root");
|
||||
builder.RegisterType<StreamMonitor>().As<IStreamMonitor>();
|
||||
builder.RegisterType<RecordInfo>().As<IRecordInfo>();
|
||||
builder.RegisterType<RecordedRoom>().As<IRecordedRoom>();
|
||||
builder.RegisterType<Recorder>().AsSelf();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
{
|
||||
public interface IRecordInfo
|
||||
{
|
||||
string SavePath { get; set; }
|
||||
string SavePath { get; }
|
||||
string StreamFilePrefix { get; set; }
|
||||
string ClipFilePrefix { get; set; }
|
||||
string StreamName { get; set; }
|
||||
|
|
|
@ -7,7 +7,8 @@ namespace BililiveRecorder.Core
|
|||
{
|
||||
private static readonly Random random = new Random();
|
||||
|
||||
public string SavePath { get; set; }
|
||||
private ISettings Settings { get; }
|
||||
public string SavePath { get => Settings.SavePath; }
|
||||
|
||||
public string StreamFilePrefix { get; set; } = "录制";
|
||||
public string ClipFilePrefix { get; set; } = "剪辑";
|
||||
|
@ -30,9 +31,10 @@ namespace BililiveRecorder.Core
|
|||
return name;
|
||||
}
|
||||
|
||||
public RecordInfo(string name)
|
||||
public RecordInfo(string name, ISettings settings)
|
||||
{
|
||||
StreamName = name;
|
||||
Settings = settings;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ namespace BililiveRecorder.Core
|
|||
public bool IsMonitoring => StreamMonitor.receiver.IsConnected;
|
||||
public bool IsRecording => flvStream != null;
|
||||
|
||||
private readonly Func<string, bool, IFlvStreamProcessor> newIFlvStreamProcessor;
|
||||
public IFlvStreamProcessor Processor { get; set; } // FlvProcessor
|
||||
public ObservableCollection<IFlvClipProcessor> Clips { get; private set; } = new ObservableCollection<IFlvClipProcessor>();
|
||||
|
||||
|
@ -41,8 +42,14 @@ namespace BililiveRecorder.Core
|
|||
public DateTime LastUpdateDateTime { get; private set; } = DateTime.Now;
|
||||
public long LastUpdateSize { get; private set; } = 0;
|
||||
|
||||
public RecordedRoom(ISettings settings, int roomid)
|
||||
public RecordedRoom(ISettings settings,
|
||||
Func<string, IRecordInfo> newIRecordInfo,
|
||||
Func<int, IStreamMonitor> newIStreamMonitor,
|
||||
Func<string, bool, IFlvStreamProcessor> newIFlvStreamProcessor,
|
||||
int roomid)
|
||||
{
|
||||
this.newIFlvStreamProcessor = newIFlvStreamProcessor;
|
||||
|
||||
_settings = settings;
|
||||
_settings.PropertyChanged += _settings_PropertyChanged;
|
||||
|
||||
|
@ -50,12 +57,9 @@ namespace BililiveRecorder.Core
|
|||
|
||||
UpdateRoomInfo();
|
||||
|
||||
RecordInfo = new RecordInfo(StreamerName)
|
||||
{
|
||||
SavePath = _settings.SavePath
|
||||
};
|
||||
RecordInfo = newIRecordInfo(StreamerName);
|
||||
|
||||
StreamMonitor = new StreamMonitor(RealRoomid);
|
||||
StreamMonitor = newIStreamMonitor(RealRoomid);
|
||||
StreamMonitor.StreamStatusChanged += StreamMonitor_StreamStatusChanged;
|
||||
}
|
||||
|
||||
|
@ -88,6 +92,7 @@ namespace BililiveRecorder.Core
|
|||
Processor.Clip_Future = _settings.Clip_Future;
|
||||
}
|
||||
}
|
||||
/**
|
||||
else if (e.PropertyName == nameof(_settings.SavePath))
|
||||
{
|
||||
if (RecordInfo != null)
|
||||
|
@ -95,6 +100,7 @@ namespace BililiveRecorder.Core
|
|||
RecordInfo.SavePath = _settings.SavePath;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
private void StreamMonitor_StreamStatusChanged(object sender, StreamStatusChangedArgs e)
|
||||
|
@ -164,7 +170,8 @@ namespace BililiveRecorder.Core
|
|||
triggerType = TriggerType.HttpApi;
|
||||
}
|
||||
|
||||
Processor = new FlvStreamProcessor(savepath, _settings.Feature == EnabledFeature.RecordOnly);
|
||||
// Processor = new FlvStreamProcessor(savepath, _settings.Feature == EnabledFeature.RecordOnly);
|
||||
Processor = newIFlvStreamProcessor(savepath, _settings.Feature == EnabledFeature.RecordOnly);
|
||||
Processor.TagProcessed += Processor_TagProcessed;
|
||||
Processor.StreamFinalized += Processor_StreamFinalized;
|
||||
Processor.GetFileName = RecordInfo.GetStreamFilePath;
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
using NLog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
@ -14,12 +12,16 @@ namespace BililiveRecorder.Core
|
|||
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
public ObservableCollection<IRecordedRoom> Rooms { get; } = new ObservableCollection<IRecordedRoom>();
|
||||
public ISettings Settings { get; } = new Settings();
|
||||
public ISettings Settings { get; }
|
||||
|
||||
private readonly Func<int, IRecordedRoom> newIRecordedRoom;
|
||||
private CancellationTokenSource tokenSource;
|
||||
|
||||
public Recorder()
|
||||
public Recorder(ISettings settings, Func<int, IRecordedRoom> iRecordedRoom)
|
||||
{
|
||||
Settings = settings;
|
||||
newIRecordedRoom = iRecordedRoom;
|
||||
|
||||
tokenSource = new CancellationTokenSource();
|
||||
Repeat.Interval(TimeSpan.FromSeconds(6), DownloadWatchdog, tokenSource.Token);
|
||||
}
|
||||
|
@ -55,10 +57,16 @@ namespace BililiveRecorder.Core
|
|||
public void AddRoom(int roomid, bool enabled = false)
|
||||
{
|
||||
if (roomid <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(roomid), "房间号需要大于0");
|
||||
var rr = new RecordedRoom(Settings, roomid);
|
||||
}
|
||||
// var rr = new RecordedRoom(Settings, roomid);
|
||||
var rr = newIRecordedRoom(roomid);
|
||||
if (enabled)
|
||||
{
|
||||
Task.Run(() => rr.Start());
|
||||
}
|
||||
|
||||
Rooms.Add(rr);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,21 +9,27 @@ namespace BililiveRecorder.FlvProcessor
|
|||
{
|
||||
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
public IFlvMetadata Header { get; }
|
||||
public List<IFlvTag> HTags { get; }
|
||||
public List<IFlvTag> Tags { get; }
|
||||
private readonly int target = -1;
|
||||
public IFlvMetadata Header { get; private set; }
|
||||
public List<IFlvTag> HTags { get; private set; }
|
||||
public List<IFlvTag> Tags { get; private set; }
|
||||
private int target = -1;
|
||||
|
||||
public Func<string> GetFileName { get; set; }
|
||||
|
||||
public FlvClipProcessor(IFlvMetadata header, List<IFlvTag> head, List<IFlvTag> past, uint future)
|
||||
public FlvClipProcessor()
|
||||
{
|
||||
Header = header;
|
||||
}
|
||||
|
||||
public IFlvClipProcessor Initialize(IFlvMetadata metadata, List<IFlvTag> head, List<IFlvTag> data, uint seconds)
|
||||
{
|
||||
Header = metadata;
|
||||
HTags = head;
|
||||
Tags = past;
|
||||
target = Tags[Tags.Count - 1].TimeStamp + (int)(future * FlvStreamProcessor.SEC_TO_MS);
|
||||
Tags = data;
|
||||
target = Tags[Tags.Count - 1].TimeStamp + (int)(seconds * FlvStreamProcessor.SEC_TO_MS);
|
||||
logger.Debug("Clip 创建 Tags.Count={0} Tags[0].TimeStamp={1} Tags[Tags.Count-1].TimeStamp={2} Tags里秒数={3}",
|
||||
Tags.Count, Tags[0].TimeStamp, Tags[Tags.Count - 1].TimeStamp, (Tags[Tags.Count - 1].TimeStamp - Tags[0].TimeStamp) / 1000d);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public void AddTag(IFlvTag tag)
|
||||
|
|
20
BililiveRecorder.FlvProcessor/FlvProcessorModule.cs
Normal file
20
BililiveRecorder.FlvProcessor/FlvProcessorModule.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
using Autofac;
|
||||
|
||||
namespace BililiveRecorder.FlvProcessor
|
||||
{
|
||||
public class FlvProcessorModule : Module
|
||||
{
|
||||
public FlvProcessorModule()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void Load(ContainerBuilder builder)
|
||||
{
|
||||
builder.Register(c => new FlvTag()).As<IFlvTag>();
|
||||
builder.RegisterType<FlvMetadata>().As<IFlvMetadata>();
|
||||
builder.RegisterType<FlvClipProcessor>().As<IFlvClipProcessor>();
|
||||
builder.RegisterType<FlvStreamProcessor>().As<IFlvStreamProcessor>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -59,8 +59,16 @@ namespace BililiveRecorder.FlvProcessor
|
|||
public int TagAudioCount { get; private set; } = 0;
|
||||
private bool hasOffset = false;
|
||||
|
||||
public FlvStreamProcessor(string path, bool noclip)
|
||||
private readonly Func<IFlvClipProcessor> funcFlvClipProcessor;
|
||||
private readonly Func<byte[], IFlvMetadata> funcFlvMetadata;
|
||||
private readonly Func<IFlvTag> funcFlvTag;
|
||||
|
||||
public FlvStreamProcessor(Func<IFlvClipProcessor> funcFlvClipProcessor, Func<byte[], IFlvMetadata> funcFlvMetadata, Func<IFlvTag> funcFlvTag, string path, bool noclip)
|
||||
{
|
||||
this.funcFlvClipProcessor = funcFlvClipProcessor;
|
||||
this.funcFlvMetadata = funcFlvMetadata;
|
||||
this.funcFlvTag = funcFlvTag;
|
||||
|
||||
_noClip = noclip;
|
||||
if (path == null)
|
||||
{
|
||||
|
@ -153,7 +161,7 @@ namespace BililiveRecorder.FlvProcessor
|
|||
_fs?.Write(FLV_HEADER_BYTES, 0, FLV_HEADER_BYTES.Length);
|
||||
_fs?.Write(new byte[] { 0, 0, 0, 0, }, 0, 4);
|
||||
|
||||
Metadata = new FlvMetadata(tag.Data);
|
||||
Metadata = funcFlvMetadata(tag.Data);
|
||||
|
||||
// TODO: 添加录播姬标记、录制信息
|
||||
|
||||
|
@ -251,7 +259,7 @@ namespace BililiveRecorder.FlvProcessor
|
|||
_buffer.Write(data, 0, data.Length);
|
||||
long dataLen = _buffer.Position;
|
||||
_buffer.Position = 0;
|
||||
IFlvTag tag = new FlvTag();
|
||||
IFlvTag tag = funcFlvTag();
|
||||
|
||||
// Previous Tag Size
|
||||
_buffer.Read(b, 0, 4);
|
||||
|
@ -293,7 +301,7 @@ namespace BililiveRecorder.FlvProcessor
|
|||
lock (_writelock)
|
||||
{
|
||||
logger.Info("剪辑处理中,将会保存过去 {0} 秒和将来 {1} 秒的直播流", (Tags[Tags.Count - 1].TimeStamp - Tags[0].TimeStamp) / 1000d, Clip_Future);
|
||||
return new FlvClipProcessor(Metadata, HTags, new List<IFlvTag>(Tags.ToArray()), Clip_Future);
|
||||
return ((funcFlvClipProcessor()).Initialize(Metadata, HTags, new List<IFlvTag>(Tags.ToArray()), Clip_Future));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace BililiveRecorder.FlvProcessor
|
|||
List<IFlvTag> Tags { get; }
|
||||
Func<string> GetFileName { get; set; }
|
||||
|
||||
IFlvClipProcessor Initialize(IFlvMetadata metadata, List<IFlvTag> head, List<IFlvTag> data, uint seconds);
|
||||
void AddTag(IFlvTag tag);
|
||||
void FinallizeFile();
|
||||
event ClipFinalizedEvent ClipFinalized;
|
||||
|
|
|
@ -195,6 +195,10 @@
|
|||
<Project>{cb9f2d58-181d-49f7-9560-d35a9b9c1d8c}</Project>
|
||||
<Name>BililiveRecorder.Core</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\BililiveRecorder.FlvProcessor\BililiveRecorder.FlvProcessor.csproj">
|
||||
<Project>{51748048-1949-4218-8ded-94014abe7633}</Project>
|
||||
<Name>BililiveRecorder.FlvProcessor</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include=".NETFramework,Version=v4.6.2">
|
||||
|
|
|
@ -1,25 +1,16 @@
|
|||
using BililiveRecorder.Core;
|
||||
using Autofac;
|
||||
using BililiveRecorder.Core;
|
||||
using BililiveRecorder.FlvProcessor;
|
||||
using NLog;
|
||||
using NLog.Config;
|
||||
using NLog.Targets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Deployment.Application;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
|
||||
namespace BililiveRecorder.WPF
|
||||
|
@ -34,6 +25,9 @@ namespace BililiveRecorder.WPF
|
|||
|
||||
private const int MAX_LOG_ROW = 25;
|
||||
|
||||
private IContainer Container { get; set; }
|
||||
private ILifetimeScope RootScope { get; set; }
|
||||
|
||||
public Recorder Recorder { get; set; }
|
||||
public ObservableCollection<string> Logs { get; set; } =
|
||||
new ObservableCollection<string>()
|
||||
|
@ -48,11 +42,19 @@ namespace BililiveRecorder.WPF
|
|||
|
||||
public MainWindow()
|
||||
{
|
||||
_AddLog = (message) => Log.Dispatcher.Invoke(() => { Logs.Add(message); while (Logs.Count > MAX_LOG_ROW) Logs.RemoveAt(0); });
|
||||
var builder = new ContainerBuilder();
|
||||
builder.RegisterModule<FlvProcessorModule>();
|
||||
builder.RegisterModule<CoreModule>();
|
||||
|
||||
Container = builder.Build();
|
||||
|
||||
RootScope = Container.BeginLifetimeScope("recorder_root");
|
||||
|
||||
_AddLog = (message) => Log.Dispatcher.Invoke(() => { Logs.Add(message); while (Logs.Count > MAX_LOG_ROW) { Logs.RemoveAt(0); } });
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
Recorder = new Recorder();
|
||||
Recorder = RootScope.Resolve<Recorder>();
|
||||
DataContext = this;
|
||||
|
||||
|
||||
|
@ -109,7 +111,10 @@ namespace BililiveRecorder.WPF
|
|||
return;
|
||||
}
|
||||
if (e.Cancelled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.UpdateAvailable)
|
||||
{
|
||||
if (e.IsUpdateRequired)
|
||||
|
@ -148,7 +153,7 @@ namespace BililiveRecorder.WPF
|
|||
{
|
||||
UpdateBar.Dispatcher.Invoke(() =>
|
||||
{
|
||||
var p = (e.BytesTotal == 0) ? 100d : ((double)e.BytesCompleted / (double)e.BytesTotal) * 100d;
|
||||
var p = (e.BytesTotal == 0) ? 100d : (e.BytesCompleted / (double)e.BytesTotal) * 100d;
|
||||
UpdateBar.Progress = p;
|
||||
UpdateBar.ProgressText = string.Format("{0}KiB / {1}KiB - {2}%", e.BytesCompleted / 1024, e.BytesTotal / 1024, p.ToString("0.##"));
|
||||
});
|
||||
|
@ -228,7 +233,9 @@ namespace BililiveRecorder.WPF
|
|||
if (int.TryParse(r[0], out int roomid) && bool.TryParse(r[1], out bool enabled))
|
||||
{
|
||||
if (roomid > 0)
|
||||
{
|
||||
Recorder.AddRoom(roomid, enabled);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -250,7 +257,11 @@ namespace BililiveRecorder.WPF
|
|||
private void Clip_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var rr = _GetSenderAsRecordedRoom(sender);
|
||||
if (rr == null) return;
|
||||
if (rr == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Task.Run(() => rr.Clip());
|
||||
}
|
||||
|
||||
|
@ -262,7 +273,11 @@ namespace BililiveRecorder.WPF
|
|||
private void EnableAutoRec(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var rr = _GetSenderAsRecordedRoom(sender);
|
||||
if (rr == null) return;
|
||||
if (rr == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Task.Run(() => rr.Start());
|
||||
}
|
||||
|
||||
|
@ -274,7 +289,11 @@ namespace BililiveRecorder.WPF
|
|||
private void DisableAutoRec(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var rr = _GetSenderAsRecordedRoom(sender);
|
||||
if (rr == null) return;
|
||||
if (rr == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Task.Run(() => rr.Stop());
|
||||
}
|
||||
|
||||
|
@ -286,7 +305,11 @@ namespace BililiveRecorder.WPF
|
|||
private void TriggerRec(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var rr = _GetSenderAsRecordedRoom(sender);
|
||||
if (rr == null) return;
|
||||
if (rr == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Task.Run(() => rr.StartRecord());
|
||||
}
|
||||
|
||||
|
@ -298,7 +321,11 @@ namespace BililiveRecorder.WPF
|
|||
private void CutRec(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var rr = _GetSenderAsRecordedRoom(sender);
|
||||
if (rr == null) return;
|
||||
if (rr == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Task.Run(() => rr.StopRecord());
|
||||
}
|
||||
|
||||
|
@ -310,7 +337,11 @@ namespace BililiveRecorder.WPF
|
|||
private void RemoveRecRoom(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var rr = _GetSenderAsRecordedRoom(sender);
|
||||
if (rr == null) return;
|
||||
if (rr == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Recorder.RemoveRoom(rr);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user