关于comfyui的mmaudio音频生成插件时时间不一致问题(一)

张开发
2026/5/13 7:03:20 15 分钟阅读

分享文章

关于comfyui的mmaudio音频生成插件时时间不一致问题(一)
起因时这样的我在根据视频生成音频的时候发现生成的音频与视频的时间不对可以明显看到视频的FPS16长度图片数量537理论时间也输出了 537/16 33.5625 秒但是我们可以看到生成的音频时长是21秒看一下后台什么情况后台计算的视频长度是21.48秒不对啊于是我又尝试了一下别的视频发现都不对劲时间总是不对我们倒推算一下537张时间21.48秒那么帧率就是 537/21.48 25 FPS于是我尝试了别的帧率的视频发现这个mmaudio节点是默认所有视频25帧的而且不给改这就很操蛋了我要是硬件够的话我还用用16帧解决办法1. 所有视频都用25FPS2. 修改节点修改节点准备莫名的激动之前只是改一改一些导入错误而已第一次尝试修改暂时就是准备给他加一个可以输入的参数用来输入帧率这样我们就可以调控视频的帧率了要修改外观然后代替里面的默认25帧的参数就行很简单代码查询最难的一步看一下kijia大佬写的插件先弄懂大部分的代码就行一步一步来先了解一下comfyui的插件规定怎么写才是对的插件规定骨架不管是音频节点、图像节点ComfyUI 的节点都遵循一个固定模板先记住这个骨架下面的代码时资料的例子瞎写的不是哪个节点# 1. 导入必要的库比如处理音频的mmaudio、ComfyUI的基础类、数值处理的numpy等 import torch import mmaudio from mmaudio.apis import inference_audio from comfyui.nodes import NodeBase # 不同版本写法可能略不同核心是继承基类 # 2. 定义一个节点类比如“音频特征提取节点”必须继承ComfyUI的节点基类 class MMAudioFeatureExtractor(NodeBase): # 2.1 【关键】定义节点的输入参数UI上能填的参数都在这 classmethod def INPUT_TYPES(cls): return { required: { # 必选参数UI上标红必须填 audio_path: (STRING, {default: your_audio.wav, multiline: False}), # 字符串类型音频文件路径 feature_type: ([mfcc, mel, spectrogram], {default: mfcc}), # 下拉选择框可选特征类型 sample_rate: (INT, {default: 16000, min: 8000, max: 48000}), # 整数类型采样率 }, optional: { # 可选参数不填也能运行 normalize: (BOOLEAN, {default: True}), # 布尔值是否归一化 } } # 2.2 【关键】定义节点的输出类型节点能输出什么数据 RETURN_TYPES (TENSOR, STRING) # 输出张量特征数据、字符串特征类型说明 RETURN_NAMES (feature_tensor, feature_info) # 输出的名字UI上显示的输出端口名 # 2.3 【关键】定义节点执行的核心函数名下面的process方法就是实际干活的 FUNCTION extract_feature # 2.4 【关键】定义节点在UI上的分类比如“Audio/MMAudio”方便找 CATEGORY Audio/MMAudio # 2.5 【核心逻辑】节点的实际功能输入参数 → 处理 → 输出结果 def extract_feature(self, audio_path, feature_type, sample_rate, normalizeTrue): # 步骤1加载音频文件调用mmaudio的方法 audio_data, sr mmaudio.load(audio_path, srsample_rate) # 步骤2根据选择的特征类型提取音频特征 if feature_type mfcc: feature mmaudio.features.mfcc(audio_data, srsr, normalizenormalize) elif feature_type mel: feature mmaudio.features.mel_spectrogram(audio_data, srsr) else: feature mmaudio.features.spectrogram(audio_data, srsr) # 步骤3把特征转成ComfyUI能传递的张量PyTorch Tensor feature_tensor torch.from_numpy(feature) # 步骤4准备输出信息 feature_info f提取{feature_type}特征采样率{sample_rate}形状{feature_tensor.shape} # 必须返回和RETURN_TYPES数量、顺序完全一致的结果 return (feature_tensor, feature_info) # 3. 把节点注册到ComfyUI让UI能识别这个节点 NODE_CLASS_MAPPINGS { MMAudioFeatureExtractor: MMAudioFeatureExtractor # UI上显示的节点名: 上面定义的类名 } NODE_DISPLAY_NAME_MAPPINGS { MMAudioFeatureExtractor: MMAudio 音频特征提取 # 更友好的中文显示名 }上面这个是查的模板大概就是这样的骨架理解成必须用这种格式给节点comfyui才会识别到也就是comfyui给你开放了一套模板你必须按照这个模板来才可以被comfyui使用骨架解析1. 导入库开头的 importimport torchComfyUI 底层用 PyTorch所有数据比如音频特征都要转成 Tensor张量所以必须导入import mmaudio核心comfyui-mmaudio是基于 mmaudio 库做的所有音频处理加载、提取特征都靠它from comfyui.nodes import NodeBase继承 ComfyUI 的节点基类只有继承了你写的类才是 “ComfyUI 能识别的节点”。2. 节点类的核心部分小白重点记① INPUT_TYPES定义输入参数这是「UI 上能操作的参数」的定义处比如你在节点上填 “音频路径”、选 “MFCC 特征”、改 “采样率”都在这定义格式说明required必选参数不填节点跑不了UI 上会标红optional可选参数不填也能跑每个参数的格式参数名: (类型, 配置)类型STRING字符串比如文件路径、INT整数比如采样率、BOOLEAN布尔值True/False、[选项1,选项2]下拉选择框配置{default: 默认值, min: 最小值, max: 最大值, multiline: 是否多行}。② RETURN_TYPES / RETURN_NAMES定义输出RETURN_TYPES节点输出的数据类型比如TENSOR张量ComfyUI 里传递数据的核心格式、STRING字符串、AUDIO音频部分版本有专属类型RETURN_NAMES给输出端口起名字方便你在 UI 上看 “这个输出是特征张量那个是信息”。③ FUNCTION指定核心函数比如FUNCTION extract_feature意思是当你点击 “运行” 时节点会执行extract_feature这个方法下面定义的 def 函数。④ CATEGORY节点分类比如CATEGORY Audio/MMAudio意思是这个节点会出现在 ComfyUI 的 “Audio” 分类下的 “MMAudio” 子分类里方便你找。⑤ 核心方法比如 extract_feature这是节点「实际干活的地方」接收输入参数 → 调用 mmaudio 做音频处理 → 生成输出小白重点看逻辑先加载音频mmaudio.load(audio_path, srsample_rate)→ 把音频文件读成 “音频数据 采样率”再提取特征根据选的feature_type比如 mfcc调用 mmaudio 对应的函数提取特征转格式把 mmaudio 输出的 numpy 数组转成 PyTorch Tensor因为 ComfyUI 只认 Tensor返回结果必须和RETURN_TYPES的数量、顺序完全一致比如RETURN_TYPES (TENSOR, STRING)就必须返回(tensor, 字符串)。3. 节点注册最后两行NODE_CLASS_MAPPINGS把你定义的节点类 “注册” 到 ComfyUIUI 才能显示这个节点NODE_DISPLAY_NAME_MAPPINGS给节点起一个 “友好的显示名”比如中文不然 UI 上显示的是类名MMAudioFeatureExtractor不直观。上面的太过复杂当然是一定得看的我自己总结了一下根据节点mmaudio的nodes.py为例子其他节点的文件名字可能不一样但是一般放在最外层大概就是1. 导入库这个就是最简单的你要用那些包python的哪些依赖库就pip安装的那些还有自己写的那些文件核心处理过程2.节点的类你创建一个类MMAudioModelLoader代表这个节点然后按照规定定义一些东西就行INPUT_TYPES看上面的输入类型对应输入的东西RETURN_TYPES代表输出的类型其实就是一个暗号告诉你我输出的是这个暗号你要跟我的线连在一起必须得是一样的暗号才行这个暗号的名字随便你只要你不去设置官方设置的一些变成其他类型的输入类型就行例如INT就是数值类型的输入就不是连线了我们可以直接看看这个节点连接的下一个节点的输入代码暗号肯定是一样的至于输出了啥给他是不用管的一个数字一张图片一个对象啥都可以只要符合python代码直接搜索这个文件里面的名字定义肯定有然后看他对应的类是哪个马上找到果真是一样的暗号天王盖地虎暗号不对你还连不上的RETURN_NAMES代表输出的名字你会发现可以连线出来的哪个名字就跟RETURN_NAMES一样当然可以定义多个在括号内继续写就行用逗号隔开FUNCTION loadmodel说明这个类的处理过程就在这个loadmodel方法里面这里就是怎么读取模型的过程当然这个方法得写在这个类里面CATEGORY MMAudio这个就是规定节点的存放位置就是你搜索的位置这里就是放在MMAudio下面我们直接搜索就能看到了之前我就纳闷过有些插件位置跟存放的文件夹不一样原来是这样果真还是得直接看代码才行3.节点注册简单说就是盖个章让comfyui官方承认NODE_CLASS_MAPPINGS 就是映射里面的节点名字随便你设置例如MMAudioModelLoader是这个节点的名字他对应的是绿色的MMAudioModelLoader这个类我们刚才又在这个类里面把那些什么输入输出啊要干的事情方法全部设置好了所以这个节点就算弄好了又给官方承认了那这个类就搞定了可以直接在comfyui里面直接用NODE_DISPLAY_NAME_MAPPINGS 这个就是给这个节点显示的名字后面的是名字你设置成“爸爸”都无所谓只不过到时候会变成这样ps NODE_CLASS_MAPPINGS 和 NODE_DISPLAY_NAME_MAPPINGS 这两个不能随便改官方规定必须使用这两个名字不然你一改他就不承认了__init__.py这个就是初始化文件了对应上面的那几个映射让comfyui能够找到这里是不是很熟就是我们刚才定义的那个然后下面那个all直接一样就行反正没必要去改等下又各种问题就是前面的导入根据你的节点文件名字改就行这里的是nodes看你前面的文件名字Pyproject TOMLPython 项目的官方配置文件可以直接理解成这个项目的信息“项目身份证” “采购清单”它的核心作用是告诉 ComfyUI / Python 编译器 “这个插件是谁、叫什么、需要什么工具才能运行”。感觉像xml的配置文件啊反正差不多可以看到上面写了一些节点名字name、节点描述说明description、版本号version、协议license、仓库的地址Repository、仓库发布者也就是作者PublisherId等等最重要的就是这个dependencies——这个告诉我们需要什么依赖库才能使用这个节点就跟那个requirement差不多太长了休息一下下一篇继续

更多文章