Files
Musicreater/examples/doc_importdata_plugin.md
2026-02-12 21:57:22 +08:00

130 lines
5.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 示例插件:导入音符数据
> 版权所有 © 2026 金羿
> Copyright © 2026 Eilles
睿乐组织 开发交流群 [861684859](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=fxNYIX_zKMgaO8X6K7pP7tHtLB7JRvdX&noverify=0&group_code=861684859)
Email [TriM-Organization@hotmail.com](mailto:TriM-Organization@hotmail.com)
```license
本示例模块开放授权同时本教程文件已开放至公共领域
请注意
若是对本文件的直接转载在形式上没有修改增删添加注释或单纯修改排版翻译录屏截图
则该使用者需要在转载所及之处明确在转载的内容开头标注本文之原始著作权人
在当前文件下该原始著作权人为金羿(Eilles)
如果是对本文进行了一定程度上的修改和补充或者以不同方式演绎本文件如制成视频教程等
则无需标注原作者允许该使用者自行署名
本声明仅限于包含此声明的本文件本声明与项目内其他文件无关
```
本教程文档的关联文件是[exp_importdata_plugin.py](./exp_importdata_plugin.py)
## 新建文件夹 · 基础模块知识
首先一个 **· v3** 的插件应当存储于一个 Python 模块之中也就是插件存在于可以被 import 语句引入的 module
这就意味着承载插件的模块本质上可以是多个 Python `.py` 文件组成的带有 `__init__.py` 的一个文件夹
或者是一个简单的 `.py` 文件
我们有这种共识大家已经知道了模块的相关知识后面的教程中你已经理解 **· v3** 插件和 Python 模块的区别
## 开始编写插件 · 插件基础
首先导入插件所需的类
在这里我们是一个用来导入数据的插件
所以就需要导入 `MusicInputPluginBase` 类和 `music_input_plugin` 函数
同时`PluginMetaInformation` 类和 `PluginTypes` 类也必须导入这是插件的元信息所需要的
```python
from Musicreater.plugins import (
music_input_plugin,
PluginMetaInformation,
PluginTypes,
MusicInputPluginBase,
)
```
如果插件需要配置那么请再导入 `PluginConfig` 并从此继承一个类且须用 dataclass 装饰器来注册之
_对于这个类的使用方式可以阅读 dataclass 的官方文档_
```python
from Musicreater.plugins import PluginConfig
from dataclasses import dataclass
@dataclass
class ExampleImportConfig(PluginConfig):
example_config_item3: bool
example_config_item1: str = "example_config_item"
example_config_item2: int = 0
```
## 编写插件 · 开始
接着我们来制作一个插件
首先一个 **· v3** 的插件应当是一个继承自我们已经准备好的插件基类的****缩句插件是类
**· v3** 任何对音乐的操作包括导入导出处理都分为对 **整首曲目** 的操作和对 **单个音轨** 的操作
我们的样例是一个对**整首曲目**进行**导入操作**的插件因此需要继承 `MusicInputPluginBase`
插件类的类名称不得以 `Base` 结尾因为咱写的是插件不是插件基类
在插件的类的开头需要用插件注册装饰函数来对插件类装饰
```python
@music_input_plugin("example_import_plugin")
class xxx:
...
```
我们这里对应插件类型的注册器是 `music_input_plugin` 函数
在注册器函数后的参数是这个插件的惟一识别码不应与其他插件混淆
通常可以是这个插件的功能描述或者就是插件名
接着编写这个插件也即是此类
每个插件的类必须包含一个用于指定插件元信息的 `metainfo` 属性
如果插件是导入数据或者导出数据的插件则必须包含一个 `supported_formats` 属性用以声明插件所支持的数据格式
用于导入的插件类必须包含一个 `loadbytes` 方法用于从字节流中导入数据可选是否单独实现 `load` 方法如果不单独实现则在调用时会直接通过打开文件后使用 `loadbytes` 的方式实现
```python
# 注册插件
@music_input_plugin("something_convert_to_music")
# 继承自对应类型的插件基类
class ExampleImportPlugin(MusicInputPluginBase):
# 插件元信息定义
metainfo = PluginMetaInformation(
name="示例导入插件", # 插件名称
author="金羿", # 插件作者
description="这是一个示例导入插件", # 插件描述
version=(0, 0, 1), # 插件版本
type=PluginTypes.FUNCTION_MUSIC_IMPORT, # 插件类型
license="The Unlicense", # 插件许可证
dependencies=("something_convertion_library") # 插件对于其他插件的依赖项(此功能尚未实现)
)
# 导入导出插件支持的数据格式,大小写皆可,无需加后缀名前的那个点
supported_formats = ("EXP", "example_format")
# 定义 loadbytes 方法,从字节流中导入数据
def loadbytes(
self, bytes_buffer_in: BinaryIO, config: Optional[ExampleImportConfig]
) -> "SingleMusic":
...
# 插件可选地定义 load 方法,从文件导入数据。下面展示的是不定义 load 方法时候的实现方式
def load(
self, file_path: Path, config: Optional[ExampleImportConfig]
) -> "SingleMusic":
with file_path.open("rb") as f:
return self.loadbytes(f, config)
```
至此一个插件的编写已经完成
同时如果有不清楚的地方可以查看我们的[内置插件](../Musicreater/builtin_plugins/)说不定会给你一些启发