Skip to content

插件开发

Harlan-H edited this page Oct 24, 2022 · 8 revisions

0.简介

  • 插件加载模式
    1. 需要设置dll的名称跟请求下载的m3u8的主机名称一致
    2. 只要plugins中有插件就会自动加载
    3. 如果找到对应主机名称的dll就会采用对应的dll的处理方案进行操作
    4. 每一个下载任务都会new一个新的插件实例

1.创建项目

  1. 创建.net6的类库
  2. 创建项目的时候需要按照格式要求创建dll名称,否则无法加载插件
  3. 名称是M3u8Downloader_H.*.plugin,中间的星号为你需要下载的m3u8的主机名称

2. 实例化IPluginBuilder接口

  • 这里的实例是M3u8Downloader_H.bilivideo.plugin这个项目的代码
using M3u8Downloader_H.bilivideo.plugin.Readers;
using M3u8Downloader_H.M3U8.AttributeReaderManager;
using M3u8Downloader_H.Plugin;

namespace M3u8Downloader_H.bilivideo.plugin
{
    public class Class1 : IPluginBuilder
    {
        //在本实例中,不需要对下载后的数据进行任何处理,所以直接返回null
        public IDownloadService? CreatePluginService() => null;
        
        //如果需要使用此函数非常简单
        //这里采用了下面的实现了IDownloadService接口的处理方法
        //这里只要直接返回MyDownloadService的实例即可
        //public IDownloadService? CreatePluginService() => new MyDownloadService();

        //这里对media这个数据流进行处理 所以采用set函数进行替换原始的处理程序
        //MediaAttributeReader实现了IAttributeReader接口
        //如果你需要对其他个性化的标签进行处理,可以采用Add函数进行添加
        //MediaAttributeReader的具体实现,可以自己看一下代码
        public void SetAttributeReader(IAttributeReaderManager attributeReader)
        {
            attributeReader.Set("#EXTINF", new MediaAttributeReader());
        }
    }
}

3. 实例化下载处理接口

1. 对特殊密钥得处理实例

using PluginInterface;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using VideoDownloaderEx.Extensions;

namespace PluginTest3
{
    public class MyDownloadService : IDownloadService
    {
        private byte[] aesKey;
        private byte[] aesIv;

        //此函数会在单线程中调用
        //调用到此函数的时候,会将httpclient,以及header传入
        //那如果你需要发起http请求可以保存这个形参
        public Task Initialize(HttpClient httpClient, IEnumerable<KeyValuePair<string, string>>? headers,CancellationToken cancellationToken) => Task.CompletedTask;

        //这里假设key是超过16位  但是只有前16位是有用得
        //只有当m3u8文件有key那个字段得时候 才会被调用
        //此函数会在单线程中调用
        public void SetCryptData(string method, byte[] key, byte[] iv)
        {
            aesKey = key[0..16];
            aesIv = iv;
        }

        //这个函数是多线程调用得
        public Stream HandleData(Stream stream, CancellationToken cancellationToken)
        {
            //这里的AesDecrypt需要项目引用VideoDownloaderEx.Extensions.dll 然后using VideoDownloaderEx.Extensions即可使用
            return stream.AesDecrypt(aesKey, aesIv);
        }
    }
}

2. 需要发起http请求

using PluginInterface;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using VideoDownloaderEx.Extensions;

namespace PluginTest3
{
    public class Class1 : IPlugin
    {
        private byte[] aesKey;

        //这里假设需要是从某地址请求一段密钥
        //如果网站对某些请求头有检测 那请求操作得时候 最好加上请求头
        //此函数会在单线程中调用
        public async Task Initialize(HttpClient httpClient, IEnumerable<KeyValuePair<string, string>>? headers,CancellationToken cancellationToken)
        {
            //GetByteArrayAsync 需要项目引用VideoDownloaderEx.Extensions.dll 
            //然后using VideoDownloaderEx.Extensions
            aesKey = await httpClient.GetByteArrayAsync("https://www.xxx.com", headers, cancellationToken);
        }

        //这里假设在m3u8文件中 没有key那个字段 所以这个函数也自然不会被执行
        //此函数会在单线程中调用
        public void SetCryptData(string method, byte[] key, byte[] iv)
        {
        }

        //此函数会在多线程中调用
        public Stream HandleData(Stream stream, CancellationToken cancellationToken)
        {
            return stream.AesDecrypt(aesKey, new byte[16]);
        }
    }
}

4. 配置插件文件

  • 只需要.plugin.dll 这一个文件放入即可
  • 将你编写好的插件放入到Plugins目录中,软件在打开的时候会自动加载
  • 如果你需要变更某个插件,或者新加某个插件,请重启软件即可
  • 如果你不想使用某个插件,可以将那个插件移除,或者改名成其他的名字
Clone this wiki locally