Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
Harlan-H committed May 16, 2024
2 parents 3cc321d + 7bd7ef8 commit 578bd29
Show file tree
Hide file tree
Showing 21 changed files with 177 additions and 85 deletions.
6 changes: 6 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# 3.14.3 (2024/05/16)
- 优化插件开发
- 允许插件使用log功能
- 当增加或删除插件不在需要重启软件
- 优化代理设置提示

# 3.14.2 (2024/05/13)
- 优化当多个任务同时开启日志时界面卡顿的问题

Expand Down
17 changes: 9 additions & 8 deletions M3u8Downloader_H.Core/DownloadClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ public class DownloadClient
private Uri _url;
private readonly IEnumerable<KeyValuePair<string, string>>? _header;
private readonly IPluginManager? pluginManager;
private readonly ILog _log;
private M3u8FileInfoClient? m3U8FileInfoClient;
private M3uDownloaderClient? m3UDownloaderClient;
private M3uCombinerClient? m3UCombinerClient;
private IM3u8UriManager? m3U8UriManager;

public ILog? Log { get; set; } = default!;
public string M3uContent { get; set; } = default!;
public M3UFileInfo M3u8FileInfo { get; set; } = default!;
public M3UKeyInfo M3UKeyInfo { get; set; } = default!;
Expand All @@ -42,7 +42,7 @@ private IM3u8UriManager M3U8UriManager
{
get
{
m3U8UriManager ??= M3u8UriManagerFactory.CreateM3u8UriManager(pluginManager?.M3U8UriProvider, httpClient, _header);
m3U8UriManager ??= M3u8UriManagerFactory.CreateM3u8UriManager(pluginManager?.M3U8UriProvider, _header);
return m3U8UriManager;
}

Expand All @@ -54,7 +54,7 @@ private IM3UFileInfoMananger M3uFileReader
{
m3U8FileInfoClient ??= new M3u8FileInfoClient(httpClient, pluginManager);
m3U8FileInfoClient.M3UFileReader.TimeOuts = TimeSpan.FromSeconds(Settings.Timeouts);
m3U8FileInfoClient.M3UFileReader.Log = Log;
m3U8FileInfoClient.M3UFileReader.Log = _log;
return m3U8FileInfoClient.M3UFileReader;
}
}
Expand All @@ -70,7 +70,7 @@ public IDownloaderSource Downloader
m3UDownloaderClient.Downloader.M3UFileInfo = M3u8FileInfo;
m3UDownloaderClient.Downloader.Headers = _header;
m3UDownloaderClient.Downloader.DownloadParams = DownloadParams;
m3UDownloaderClient.Downloader.Log = Log;
m3UDownloaderClient.Downloader.Log = _log;
}

return m3UDownloaderClient.Downloader;
Expand All @@ -85,18 +85,19 @@ public M3uCombinerClient Merger
{
DownloadParams = DownloadParams,
Settings = Settings,
Log = Log
Log = _log
};
return m3UCombinerClient;
}
}

public DownloadClient(HttpClient httpClient,Uri url,IEnumerable<KeyValuePair<string,string>>? header, IPluginBuilder? pluginBuilder)
public DownloadClient(HttpClient httpClient,Uri url,IEnumerable<KeyValuePair<string,string>>? header, ILog log, Type? pluginType)
{
this.httpClient = httpClient;
_url = url;
_header = header;
pluginManager = PluginManger.CreatePluginMangaer(pluginBuilder);
_log = log;
pluginManager = PluginManger.CreatePluginMangaer(pluginType, httpClient, log);
}

public async Task GetM3u8Uri(CancellationToken cancellationToken)
Expand All @@ -122,7 +123,7 @@ public async Task GetM3U8FileInfo(CancellationToken cancellationToken)
{
M3u8FileInfo = await M3uFileReader.GetM3u8FileInfo(_url, _header, cancellationToken);
}
Log?.Info("获取视频流{0}个", M3u8FileInfo.MediaFiles.Count);
_log.Info("获取视频流{0}个", M3u8FileInfo.MediaFiles.Count);
if (M3UKeyInfo is not null)
M3u8FileInfo.Key = M3UKeyInfo;

Expand Down
4 changes: 2 additions & 2 deletions M3u8Downloader_H.Core/M3u8Downloader_H.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<Version>3.14.2.0</Version>
<Version>3.14.3.0</Version>
<Authors>Harlan</Authors>
<AssemblyVersion>3.14.2.0</AssemblyVersion>
<AssemblyVersion>3.14.3.0</AssemblyVersion>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)'=='Release'">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ namespace M3u8Downloader_H.Core.M3u8UriManagers
{
internal class M3u8UriManagerFactory
{
public static IM3u8UriManager CreateM3u8UriManager(IM3u8UriProvider? iM3U8UriProvider,HttpClient httpClient, IEnumerable<KeyValuePair<string, string>>? headers)
public static IM3u8UriManager CreateM3u8UriManager(IM3u8UriProvider? iM3U8UriProvider,IEnumerable<KeyValuePair<string, string>>? headers)
{
if (iM3U8UriProvider is not null)
return new PluginM3u8UriManager(iM3U8UriProvider, httpClient, headers);
return new PluginM3u8UriManager(iM3U8UriProvider, headers);
else
return new M3u8UriManager();

Expand Down
6 changes: 2 additions & 4 deletions M3u8Downloader_H.Core/M3u8UriManagers/PluginM3u8UriManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,12 @@ namespace M3u8Downloader_H.Core.M3u8UriManagers
internal class PluginM3u8UriManager : IM3u8UriManager
{
private readonly IM3u8UriProvider m3U8UriProvider;
private readonly HttpClient httpClient;
private readonly IEnumerable<KeyValuePair<string, string>>? headers;
public bool Completed { get; set; } = false;

public PluginM3u8UriManager(IM3u8UriProvider m3U8UriProvider,HttpClient httpClient, IEnumerable<KeyValuePair<string, string>>? headers)
public PluginM3u8UriManager(IM3u8UriProvider m3U8UriProvider,IEnumerable<KeyValuePair<string, string>>? headers)
{
this.m3U8UriProvider = m3U8UriProvider;
this.httpClient = httpClient;
this.headers = headers;
}

Expand All @@ -27,7 +25,7 @@ public Task<Uri> GetM3u8UriAsync(Uri uri, int reserve0, CancellationToken cancel
{
try
{
var url = m3U8UriProvider.GetM3u8UriAsync(httpClient, uri, headers, cancellationToken);
var url = m3U8UriProvider.GetM3u8UriAsync(uri, headers, cancellationToken);
Completed = true;
return url;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public PluginM3u8Downloader(IDownloadService downloadService, M3UFileInfo m3UFi

public override async ValueTask Initialization(CancellationToken cancellationToken)
{
await _pluginDownload.Initialize(HttpClient,Headers, m3UFileInfo, cancellationToken);
await _pluginDownload.Initialize(Headers, m3UFileInfo, cancellationToken);
}

protected override Stream DownloadAfter(Stream stream, string contentType, CancellationToken cancellationToken)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ public PluginM3UFileReaderManager(IM3u8FileInfoStreamService m3U8FileInfoService
}

protected override async Task<(Uri?, Stream)> GetM3u8FileStreamAsync(Uri uri, IEnumerable<KeyValuePair<string, string>>? headers, CancellationToken cancellationToken = default)
=> await m3U8FileInfoService.GetM3u8FileStreamAsync(httpClient, uri, headers, cancellationToken);
=> await m3U8FileInfoService.GetM3u8FileStreamAsync(uri, headers, cancellationToken);
}
}
4 changes: 2 additions & 2 deletions M3u8Downloader_H.M3U8/M3u8Downloader_H.M3U8.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<AssemblyVersion>3.14.2.0</AssemblyVersion>
<Version>3.14.2.0</Version>
<AssemblyVersion>3.14.3.0</AssemblyVersion>
<Version>3.14.3.0</Version>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)'=='Release'">
Expand Down
3 changes: 1 addition & 2 deletions M3u8Downloader_H.Plugin.Abstractions/IDownloadService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@ public interface IDownloadService
/// <summary>
/// 初始化函数,在没有进行任何下载之前,第一个调用的函数
/// </summary>
/// <param name="httpClient">http实例</param>
/// <param name="headers">附带的请求头,如果有的话</param>
/// <param name="m3UFileInfo">m3u8的数据</param>
/// <param name="cancellationToken">取消的token</param>
/// <returns>没有返回内容</returns>
Task Initialize(HttpClient httpClient, IEnumerable<KeyValuePair<string, string>>? headers, M3UFileInfo m3UFileInfo, CancellationToken cancellationToken);
Task Initialize(IEnumerable<KeyValuePair<string, string>>? headers, M3UFileInfo m3UFileInfo, CancellationToken cancellationToken);


/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@ public interface IM3u8FileInfoStreamService
/// 如果需要默认得处理函数可以使用下面得方式,同时引入M3u8Downloader_H.Common这个dll
/// httpClient.GetStreamAndUriAsync(uri, headers, cancellationToken);
/// </summary>
/// <param name="httpClient">http实例</param>
/// <param name="uri">请求地址</param>
/// <param name="headers">请求头</param>
/// <param name="cancellationToken">取消的令牌</param>
/// <returns>返回得到得m3u8数据流</returns>
Task<(Uri?,Stream)> GetM3u8FileStreamAsync(HttpClient httpClient, Uri uri, IEnumerable<KeyValuePair<string, string>>? headers, CancellationToken cancellationToken = default);
Task<(Uri?,Stream)> GetM3u8FileStreamAsync(Uri uri, IEnumerable<KeyValuePair<string, string>>? headers, CancellationToken cancellationToken = default);
}
}
3 changes: 1 addition & 2 deletions M3u8Downloader_H.Plugin.Abstractions/IM3u8UriProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@ public interface IM3u8UriProvider
/// <summary>
/// 获取m3u8得数据流,此函数可以做解析网站得操作,只要最终返回m3u8得数据流即可
/// </summary>
/// <param name="httpClient">http实例</param>
/// <param name="uri">请求地址</param>
/// <param name="headers">请求头</param>
/// <param name="cancellationToken">取消的令牌</param>
/// <returns>返回m3u8得地址</returns>
Task<Uri> GetM3u8UriAsync(HttpClient httpClient, Uri uri, IEnumerable<KeyValuePair<string, string>>? headers, CancellationToken cancellationToken = default);
Task<Uri> GetM3u8UriAsync(Uri uri, IEnumerable<KeyValuePair<string, string>>? headers, CancellationToken cancellationToken = default);
}
}
31 changes: 31 additions & 0 deletions M3u8Downloader_H.Plugin.Abstractions/IPluginBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,37 @@
{
public interface IPluginBuilder
{
// 修改后的插件将在构造函数中添加两个参数
// HttpClient , Ilog
// 两个参数的位置无所谓 需要用哪个就在构造函数中添加上
// 构造函数必须时继承自IPluginBuilder接口的构造函数,
// 如果这两个参数都不需要可以不写构造函数
/* 例子1:
public class Class1 : IPluginBuilder
{
public Class1(HttpClient httpClient)
{
this.httpClient = httpClient;
}
}
例子2:
public class Class1 : IPluginBuilder
{
public Class1(HttpClient httpClient,ILog log)
{
this.httpClient = httpClient;
this.log = log;
}
}
例子3:
public class Class1 : IPluginBuilder
{
public Class1(ILog log)
{
this.log = log;
}
}
*/
/// <summary>
/// 创建获取m3u8 uri的类
/// 如果你不需要处理,只要return null 即可
Expand Down
2 changes: 1 addition & 1 deletion M3u8Downloader_H.Plugin/M3u8Downloader_H.Plugin.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Version>1.0.1.0</Version>
<Version>1.0.2.0</Version>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)'=='Release'">
Expand Down
59 changes: 49 additions & 10 deletions M3u8Downloader_H.Plugin/PluginClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,52 +5,91 @@ namespace M3u8Downloader_H.Plugin.PluginClients
{
public partial class PluginClient
{
private static string _filterStr = "M3u8Downloader_H.*.plugin.dll";
private static string _pluginKeyRegex = @"M3u8Downloader_H\.(.*?)\.plugin";
private readonly Dictionary<string, Type> _pluginDict = new();
private readonly FileSystemWatcher watcher = new FileSystemWatcher();
public IEnumerable<string> Keys => _pluginDict.Keys;

public string PluginPath { get; set; } = default!;

private PluginClient()
{

}

public void Load(string path)
public void Init()
{
watcher.Path = PluginPath;
watcher.Filter = _filterStr;
watcher.NotifyFilter = NotifyFilters.FileName;
watcher.Created += OnCreated;
watcher.Deleted += OnDeleted;
}

private void OnDeleted(object sender, FileSystemEventArgs e)
{
if (string.IsNullOrEmpty(e.Name)) return;

string key = e.Name!.Normalize(_pluginKeyRegex);
if (_pluginDict.ContainsKey(key))
{
_pluginDict.Remove(key);
}
}

private void OnCreated(object sender, FileSystemEventArgs e)
{
if (string.IsNullOrEmpty(e.Name)) return;

LoadFile(e.FullPath, e.Name!);
}

public void Load()
{
try
{
DirectoryInfo directoryInfo = new(path);
foreach (var item in directoryInfo.EnumerateFiles("M3u8Downloader_H.*.plugin.dll", SearchOption.TopDirectoryOnly))
DirectoryInfo directoryInfo = new(PluginPath);
foreach (var item in directoryInfo.EnumerateFiles(_filterStr, SearchOption.TopDirectoryOnly))
{
Type? type = LoadLibrary(item.FullName);
string key = item.Name.Normalize(@"M3u8Downloader_H\.(.*?)\.plugin");
if (type is not null && !string.IsNullOrWhiteSpace(key))
_pluginDict.Add(key, type);
LoadFile(item.FullName, item.Name);
}
watcher.EnableRaisingEvents = true;
}
catch (DirectoryNotFoundException)
{

}
}

private void LoadFile(string fullPath,string fileName)
{
Type? type = LoadLibrary(fullPath);
string key = fileName.Normalize(_pluginKeyRegex);
if (type is not null && !string.IsNullOrWhiteSpace(key))
_pluginDict.Add(key, type);
}


private static Type? LoadLibrary(string path)
{
try
{
Type[] exportTypes = Assembly.LoadFrom(path).GetExportedTypes();
Type[] exportTypes = Assembly.LoadFile(path).GetExportedTypes();
return exportTypes.FirstOrDefault(i => typeof(IPluginBuilder).IsAssignableFrom(i));
}catch(FileLoadException)
{
return null;
}
}

public IPluginBuilder? CreatePluginBuilder(string? key)
public Type? GetPluginType(string? key)
{
if (string.IsNullOrWhiteSpace(key))
return null;

if (_pluginDict.TryGetValue(key, out Type? type))
return (IPluginBuilder?)Activator.CreateInstance(type);
return type;
return null;
}
}
Expand Down
36 changes: 33 additions & 3 deletions M3u8Downloader_H.Plugin/PluginManagers/PluginManger.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using M3u8Downloader_H.Plugin.AttributeReaderManagers;
using M3u8Downloader_H.Common.Interfaces;
using M3u8Downloader_H.Plugin.AttributeReaderManagers;
using Newtonsoft.Json.Linq;
using System.Reflection;

namespace M3u8Downloader_H.Plugin.PluginManagers
{
Expand Down Expand Up @@ -35,11 +38,38 @@ private void Build()

public partial class PluginManger
{
public static PluginManger? CreatePluginMangaer(IPluginBuilder? pluginBuilder)
public static PluginManger? CreatePluginMangaer(Type? type,HttpClient httpClient,ILog log)
{
if (pluginBuilder is null)
if (type is null)
return null;

ConstructorInfo constructor = type.GetConstructors()[0];
ParameterInfo[] parameterInfos = constructor.GetParameters();



IPluginBuilder pluginBuilder;
if (parameterInfos.Length == 0)
pluginBuilder = (IPluginBuilder)constructor.Invoke(null);
else
{
object[] argsArray = new object[parameterInfos.Length];
for (int i = 0; i < parameterInfos.Length; i++)
{
if (parameterInfos[i].ParameterType == typeof(HttpClient))
{
argsArray[i] = httpClient;
}else if (parameterInfos[i].ParameterType == typeof(ILog))
{
argsArray[i] = log;
}else
{
argsArray[i] = default!;
}
}
pluginBuilder = (IPluginBuilder)constructor.Invoke(argsArray);
}

PluginManger pluginManger = new(pluginBuilder);
pluginManger.Build();
return pluginManger;
Expand Down
Loading

0 comments on commit 578bd29

Please sign in to comment.