目 录CONTENT

文章目录

基于Porcupine实现离线语音关键词唤

成培培
2026-03-10 / 0 评论 / 0 点赞 / 8 阅读 / 0 字

最近项目上可能会用到语音AI助手,涉及到需要通过关键词唤醒后对语音助手说话执行操作,类似小爱同学那样,于是简单调研了一下相关的技术

Porcupine介绍

Picovoice Porcupine 是由 Picovoice 开发的一款 离线语音唤醒(Wake Word Detection)引擎。它的主要功能是实时监听麦克风音频,并在检测到指定的关键词(Wake Word)时触发相应的动作,例如开始录音或唤醒语音助手。并且支持离线唤醒,官网地址:https://picovoice.ai/
使用起来非常简单,也不需要自己训练唤醒词,可惜只是SDK开源,商业产品使用通常需要授权

创建唤醒词模型

这里需要注册一个账号进入其后台生成唤醒词
https://www.chengpei.top/upload/picovoice.png
选择语言填写关键词生成即可,会得到一个.ppn结尾的唤醒词模型文件

下载中文模型文件

因为我们要用中文唤醒,所以这里需要到github上下载它的中文模型文件才能支持,github地址:https://github.com/Picovoice/porcupine
文件在lib/common目录下,下载到本地备用

安装SDK

我这里用Python3开发,需要安装以下依赖: pvporcupinepyaudio

示例代码

import pvporcupine
import pyaudio
import struct
import wave
import time
import audioop

MAX_RECORD_TIME = 10
ACCESS_KEY = "+kBtDsWEedR06YSLDQUdV5eRK0NxMzHYxiGGUqisGFEU0l5mYonfqg=="
KEYWORD_PATH = "/Users/chengpei/Downloads/你好_zh_mac_v4_0_0/你好_zh_mac_v4_0_0.ppn"

# 初始化 Porcupine
porcupine = pvporcupine.create(
    access_key=ACCESS_KEY,
    keyword_paths=[KEYWORD_PATH],
    model_path="/Users/chengpei/Downloads/porcupine_params_zh.pv"
)

pa = pyaudio.PyAudio()

stream = pa.open(
    rate=porcupine.sample_rate,
    channels=1,
    format=pyaudio.paInt16,
    input=True,
    frames_per_buffer=porcupine.frame_length
)

print("开始监听关键词...")

recording = False
frames = []
start_time = 0
silence_time = 0
SILENCE_THRESHOLD = 1000
MAX_SILENCE = 2.0

while True:
    pcm = stream.read(porcupine.frame_length)
    pcm_unpacked = struct.unpack_from("h"*porcupine.frame_length, pcm)

    # 1 唤醒检测
    if not recording:
        result = porcupine.process(pcm_unpacked)

        if result >= 0:
            print("检测到关键词!开始录音...")
            recording = True
            frames = []
            silence_time = 0
            start_time = time.time()
            continue

    # 2 录音
    if recording:
        frames.append(pcm)

        # 计算音量
        volume = audioop.rms(pcm, 2)

        if volume < SILENCE_THRESHOLD:
            silence_time += porcupine.frame_length / porcupine.sample_rate
        else:
            silence_time = 0

        # 3 静音结束
        if silence_time > MAX_SILENCE or time.time() - start_time > MAX_RECORD_TIME:
            print("录音完成")

            filename = f"record_{int(time.time())}.wav"

            wf = wave.open(filename, 'wb')
            wf.setnchannels(1)
            wf.setsampwidth(pa.get_sample_size(pyaudio.paInt16))
            wf.setframerate(porcupine.sample_rate)
            wf.writeframes(b''.join(frames))
            wf.close()

            print("保存:", filename)

            recording = False

其中ACCESS_KEY可以在picovoice拿到,KEYWORD_PATH就是在后台生成的关键词模型文件,model_path要指定porcupine_params_zh.pv才能支持中文。
代码运行后开始麦克风监听,检测到关键词时开始录音,如果一直说话超市10秒结束录音,10秒内停止说话的话会在停止说话2秒时停止录音。
我一开始测试时不停止录音是因为环境噪音比较大,因为它这里是根据音量判断是否有人说话的,如果环境噪音大也可以调整参数SILENCE_THRESHOLD,效果还行,有了录音后续就可以针对录音文件文字识别进而进行其他业务操作了

0

评论区