前情提要
我们在上一篇文档中已经成功部署了snowboy并实现了自定义的唤醒词,并且创建了一个自定义的函数,在关键词触发后执行,那么我们可不可以在触发后继续监听麦克风,然后根据说出的关键词,进行更多好玩的操作呢,答案当然是可以,我们可以使用sherpa-ncnn来实现STT并处理
开始实验
1、安装sherpa-ncnn 包
官方已经发布python包,直接安装sherpa-ncnn 的包,就可以使用python调用了
pip install sherpa-ncnn
检查是否安装成功
python3 -c "import sherpa_ncnn; print(sherpa_ncnn.__file__)"
python3 -c "import _sherpa_ncnn; print(_sherpa_ncnn.__file__)"
如果正常输出说明安装没有问题。
2、下载模型
https://k2-fsa.github.io/sherpa/ncnn/pretrained_models/index.html
到上面的地址,去寻找你需要的模型
本文档使用的模型为:sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13
下载好以后上传到服务器,解压后记住路径
与snowboy集成
1、整理项目需要的代码和资源
创建你自己的目录用于整合mkdir snowboy-test
将之前clone的snowboy项目中的代码移动到自己的目录(我省略了pmdl文件的迁移,请注意)
cp snowboy/examples/Python3/demo.py snowboy-test
cp snowboy/swig/Python3/snowboydetect.py snowboy-test
cp snowboy/swig/Python3/_snowboydetect.so snowboy-test
cp -ar snowboy/resource snowboy-test
修改代码
修改demo.py中的代码。(可直接复制后覆盖原demo.py文件后修改)
我将代码改成了唤醒后,监听麦克风三秒,听到“开机”关键字时,回去使用wake on lan 通过网络发送魔术包的方式开启指定mac的电脑
注意点
- 代码中create_recognizer 函数中的模型路径需要你自己替换成你下载模型的位置
- action 函数中你可以继续写其他的操作,根据你的喜好
- while total_sp<3sample_rate 可以控制识别语音的时间 3是3秒,自行修改,长时间的没有测试过
import snowboydecoder
import sys
import signal
import sherpa_ncnn
import sounddevice as sd
from wakeonlan import send_magic_packet
interrupted = False
# 调用sherpa_ncnn
def create_recognizer():
# Please replace the model files if needed.
# See https://k2-fsa.github.io/sherpa/ncnn/pretrained_models/index.html
# for download links.
recognizer = sherpa_ncnn.Recognizer(
tokens="./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/tokens.txt",
encoder_param="./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/encoder_jit_trace-pnnx.ncnn.param",
encoder_bin="./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/encoder_jit_trace-pnnx.ncnn.bin",
decoder_param="./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/decoder_jit_trace-pnnx.ncnn.param",
decoder_bin="./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/decoder_jit_trace-pnnx.ncnn.bin",
joiner_param="./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/joiner_jit_trace-pnnx.ncnn.param",
joiner_bin="./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/joiner_jit_trace-pnnx.ncnn.bin",
num_threads=4,
hotwords_file="",
hotwords_score=1.5,
)
return recognizer
def action(res):
if "开机" in res:
print("字符串包含“开机”。")
mac="A8-5E-45-54-6A-85"
send_magic_packet(mac)
def sherpa_callback():
recognizer = create_recognizer()
devices = sd.query_devices()
print(devices)
default_input_device_idx = sd.default.device[0]
print(f'Use default device: {devices[default_input_device_idx]["name"]}')
sample_rate = recognizer.sample_rate
samples_per_read = int(0.1 * sample_rate)
last_result = None
with sd.InputStream(channels=1, dtype="float32", samplerate=sample_rate) as s:
total_sp=0
while total_sp<3*sample_rate:
#while True:
samples, _ = s.read(samples_per_read) # a blocking read
samples = samples.reshape(-1)
recognizer.accept_waveform(sample_rate, samples)
result = recognizer.text
if last_result != result:
last_result = result
print("\r{}".format(result), end="", flush=True)
total_sp+=len(samples)
action(result)
print("Started! Please speak")
def signal_handler(signal, frame):
global interrupted
interrupted = True
def interrupt_callback():
global interrupted
return interrupted
if len(sys.argv) == 1:
print("Error: need to specify model name")
print("Usage: python demo.py your.model")
sys.exit(-1)
def p():
print("我在")
if __name__=="__main__":
#sherpaSetting
# recognizer = create_recognizer()
#snowBoy
model = sys.argv[1]
# capture SIGINT signal, e.g., Ctrl+C
signal.signal(signal.SIGINT, signal_handler)
detector = snowboydecoder.HotwordDetector(model, sensitivity=0.5)
print('Listening... Press Ctrl+C to exit')
# main loop
detector.start(detected_callback=sherpa_callback,
interrupt_check=interrupt_callback,
sleep_time=0.03)
#detector.terminate()
运行
python demo.py xxx.pmdl
更多
如果你需要了解更多sherpa相关的信息
你可以访问 https://k2-fsa.github.io/sherpa
-
还不快抢沙发