1 如何用Python为Audacity编写扩展脚本
1.1 概述
Audacity官方网站的资料非常丰富
和杂乱
,Audacity本身支持的功能也非常多,扩展性也非常好,比如,官方支持的扩展方式有:
1.1.1 插件
- Nyquist(Lisp或SAL):Audacity的内置脚本格式。便于生成用户界面元素,且已针对Audacity的需求进行优化。请注意,这种插件格式不支持实时效果。相关文档:[创建您自己的Nyquist插件](Creating your own Nyquist Plugins)
- VST3(C++):插件行业标准。在Audacity、Musescore以及大多数数字音频工作站(DAWs)中都得到广泛支持。相关文档:https://steinbergmedia.github.io/vst3_doc/vstsdk/index.html
- LV2(C、C++及其他与C兼容的语言):Linux插件标准。在开源软件中广泛使用。相关文档:https://lv2plug.in/book/
- Vamp(C++、Python):一种易于开发的音频分析器框架。相关文档:https://www.vamp-plugins.org/develop.html
此外,Audacity还支持LADSPA、VST2.4和Audio Units。LADSPA和VST2.4分别是LV2和VST3的前身,相对较为陈旧。Audio Units仅在macOS上可用。
1.1.2 脚本
Audacity支持以下脚本格式:
- mod-script-pipe(Python、Perl):这是一个模块,它公开了一个命名管道,可向其发送命令。相关文档:https://manual.audacityteam.org/man/scripting.html
- 宏(Macros):您可以使用Audacity的宏功能将效果和操作串联起来。这些宏可以导出为文件。
1.2 Audacity扩展开发的选型
本人对Audacity的扩展开发只是有点粗浅的理解,并未全面深入到Audacity的各个类型的插件开发,起因是作者想将一个CD音频文件根据cue文件拆分成独立的文件,但Audacity这一历史悠久的音频处理软件,居然没有根据cue文件拆分音频的功能(折中的办法是先用工具把cue文件转成audacity标签文件,导入到audacity,再从audacity导出音频根据标签拆分)!从社区了解到的结果也大致如此!能用是能用,但过程比较繁琐,不如原生功能好,好在Audacity的插件类型种类非常多,看起来还很错的样子,至少可以写插件来完成这些功能,在AI加持下,应该不太困难吧!
1.2.1 Nyquist从入门到放弃
初步阅读了下Audacity的插件规则,并看了下Audacity本身很多菜单功能都是用Nyquist
插件编写的,想必这就是首选了!
通过几天的摸索,发现我想多了,Nyquist
插件是文本无需编译不假,但:
Nyquist
使用Lisp
语言:这一上古语言,语法别扭,括号能括到崩溃,官方说你也可以用SAL
语法,由解释器再逐句翻译成Lisp
(是的,最终还是Lisp
),但官方没有说SAL
语法Bug一堆,连基本函数在Lisp
语法下可以工作,但SAL
语法下就提示未定义!那就老老实实学Lisp
语法吧!- 语法怪就怪吧,对本行搞编程的人也不是无法逾越的困难,结果
Nyquist
的Lisp
语法也不是Common Lisp
而是一个小众方言,对很多功能不全!那就学方言吧,问题不大! Nyquist
的Lisp
引擎不支持Unicode
,中文路径名、歌曲名、Cue中的标题(有中文)都会报错,由于是小众语言引擎,支持不力,15年前就提出Unicode问题,到现在也没有支持!直接堵死了开发Nyquist插件的路子。
::: alert-danger
Nyquist插件,适合做各种音频算法的处理,Lisp有强大的数学能力,这是其他语言原生无法企及的!只要不涉及到Unicode字符,都可以用Nyquist插件,好处是可以集成在Audacity主界面的菜单中!
:::
1.2.2 Audacity Macro从入门到放弃
1个设计良好的宏引擎,至少要有一个好的编辑器,命令提示、快速搜索,基本的变量、语句控制, OK, Audacity的宏,表格化的命令编辑器,选命令要人工肉眼鼠标点击,这不是10条20条,而是几百条!不支持条件语句、不支持循环语句、不支持变量,完全无法愉快的玩耍
::: alert-danger
忠告:不要使用Audacity的宏编辑器编写宏命令集,请直接使用记事本,自行在官网命令列表中查找命令
:::
1.3 编写Python脚本
1.3.1 准备工作
- 打开Audacity的“mod-script-pipe”功能:菜单路径“编辑 -> 首选项”,如下图所示
::: alert-info
修改“mod-script-pipe”后要重启Audacity!
:::
- 下载
pipeclient.py
脚本到本地工程目录,文件地址:pipeclient.py
1.3.2 编写通信函数
建议不要直接使用pipeclien
t的write
函数向Audacity发送消息,而使用下面的send_blocking_command
函数来发送消息,这是官方论坛作者答复某位用户收发命令失败给的回复(Audacity接收到命令后,需要处理时间,不会立即返回)。
import pipeclient as pc
import time
timeout = 60.0
client = pc.PipeClient(enc='utf-8')
def get_reply (prnt=False):
start = time.time()
info = ""
while info == "" and time.time() - start < timeout:
info = client.read()
time.sleep(0.05)
if info == "":
sys.exit(f'Timeout after {timeout} seconds')
if info[-26:-1] != 'BatchCommand finished: OK':
sys.exit(f'Command failed')
if prnt:
print(info)
def send_blocking_command (cmd):
client.write(cmd)
get_reply(1)
client.write(f'Message:Text="{cmd.split(":")[0]} completed"')
get_reply(1)
::: alert-danger
声明client
时,要指定字符编码,如:pc.PipeClient(enc='utf-8')
中的utf-8
,否则会可能出现解码失败!
:::
1.3.3 查阅官方命令列表并自由发挥
官方的命令参考文档:scripting_reference.html, 这些命令在编写宏时也同样有效。
示例1:使用Python脚本向Audacity发送导入音频文件
的指令
send_blocking_command(f'Import2:Filename="{wav_file}"')
::: alert-info
send_blocking_command
在前文中已经定义,使用Import2
命令时,必须指定参数Filename
,变量wav_file
由用户自己声明。
:::
示例2:删除当前Audacity工程中的所有音轨
send_blocking_command(f'SelAllTracks:')
send_blocking_command(f'RemoveTracks:')
::: alert-danger
代码解释:先选中所有轨道,再执行删除轨道命令。
:::
示例3: 选中一段音轨并导出成文件
send_blocking_command(f'SelectTime:Start={time_start} End={time_end}')
send_blocking_command(f'Export2: Filename="{new_wav_file}" NumChannels=2')
::: alert-info
SelectTime
命令用于按时间选择音轨,Start
参数用于指定开始时间,单位为秒,End
参数用于指定结束时间,单位为秒。
Export2
命令用于将选中的区间导出为文件,Filename
指定输出文件名,Audacity会自动根据这个文件的扩展名转换成对应的音频格式(.wav, .mp3, .flac, .ape… …),NumChannels
参数指定几个声道(2声道是立体声)
:::
作者声明:本文用于记录和分享作者的学习心得,可能有部分文字或示例来自AI平台,如:豆包、DeepSeek(硅基流动)(注册链接)等,由于本人水平有限,难免存在表达错误,欢迎留言交流和指教!
Copyright © 2022~2025 All rights reserved.