详解python的webrtc库实现语音端点检测
发布时间 - 2026-01-11 01:32:53 点击率:次引言

语音端点检测最早应用于电话传输和检测系统当中,用于通信信道的时间分配,提高传输线路的利用效率.端点检测属于语音处理系统的前端操作,在语音检测领域意义重大.
但是目前的语音端点检测,尤其是检测 人声 开始和结束的端点始终是属于技术难点,各家公司始终处于 能判断,但是不敢保证 判别准确性 的阶段.
现在基于云端语义库的聊天机器人层出不穷,其中最著名的当属amazon的 Alexa/Echo 智能音箱.
国内如雨后春笋般出现了各种搭载语音聊天的智能音箱(如前几天在知乎上广告的若琪机器人)和各类智能机器人产品.国内语音服务提供商主要面对中文语音服务,由于语音不像图像有分辨率等等较为客观的指标,很多时候凭主观判断,所以较难判断各家语音识别和合成技术的好坏.但是我个人认为,国内的中文语音服务和国外的英文语音服务,在某些方面已经有超越的趋势.
通常搭建机器人聊天系统主要包括以下三个方面:
- 语音转文字(ASR/STT)
- 语义内容(NLU/NLP)
- 文字转语音(TTS)
语音转文字(ASR/STT)
在将语音传给云端API之前,是本地前端的语音采集,这部分主要包括如下几个方面:
- 麦克风降噪
- 声源定位
- 回声消除
- 唤醒词
- 语音端点检测
- 音频格式压缩
python 端点检测
由于实际应用中,单纯依靠能量检测特征检测等方法很难判断人声说话的起始点,所以市面上大多数的语音产品都是使用唤醒词判断语音起始.另外加上声音回路,还可以做语音打断.这样的交互方式可能有些傻,每次必须喊一下 唤醒词 才能继续聊天.这种方式聊多了,个人感觉会嘴巴疼:-O .现在github上有snowboy唤醒词的开源库,大家可以登录snowboy官网训练自己的唤醒词模型.
- Kitt-AI : Snowboy
- Sensory : Sensory
考虑到用唤醒词嘴巴会累,所以大致调研了一下,Python拥有丰富的库,直接import就能食用.这种方式容易受强噪声干扰,适合一个人在家玩玩.
- pyaudio: pip install pyaudio 可以从设备节点读取原始音频流数据,音频编码是PCM格式;
- webrtcvad: pip install webrtcvad 检测判断一组语音数据是否为空语音;
当检测到持续时间长度 T1 vad检测都有语音活动,可以判定为语音起始;
当检测到持续时间长度 T2 vad检测都没有有语音活动,可以判定为语音结束;
完整程序代码可以从我的github下载
程序很简单,相信看一会儿就明白了
'''
Requirements:
+ pyaudio - `pip install pyaudio`
+ py-webrtcvad - `pip install webrtcvad`
'''
import webrtcvad
import collections
import sys
import signal
import pyaudio
from array import array
from struct import pack
import wave
import time
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 16000
CHUNK_DURATION_MS = 30 # supports 10, 20 and 30 (ms)
PADDING_DURATION_MS = 1500 # 1 sec jugement
CHUNK_SIZE = int(RATE CHUNK_DURATION_MS / 1000) # chunk to read
CHUNK_BYTES = CHUNK_SIZE 2 # 16bit = 2 bytes, PCM
NUM_PADDING_CHUNKS = int(PADDING_DURATION_MS / CHUNK_DURATION_MS)
# NUM_WINDOW_CHUNKS = int(240 / CHUNK_DURATION_MS)
NUM_WINDOW_CHUNKS = int(400 / CHUNK_DURATION_MS) # 400 ms/ 30ms ge
NUM_WINDOW_CHUNKS_END = NUM_WINDOW_CHUNKS 2
START_OFFSET = int(NUM_WINDOW_CHUNKS CHUNK_DURATION_MS 0.5 RATE)
vad = webrtcvad.Vad(1)
pa = pyaudio.PyAudio()
stream = pa.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
start=False,
# input_device_index=2,
frames_per_buffer=CHUNK_SIZE)
got_a_sentence = False
leave = False
def handle_int(sig, chunk):
global leave, got_a_sentence
leave = True
got_a_sentence = True
def record_to_file(path, data, sample_width):
"Records from the microphone and outputs the resulting data to 'path'"
# sample_width, data = record()
data = pack('<' + ('h' len(data)), data)
wf = wave.open(path, 'wb')
wf.setnchannels(1)
wf.setsampwidth(sample_width)
wf.setframerate(RATE)
wf.writeframes(data)
wf.close()
def normalize(snd_data):
"Average the volume out"
MAXIMUM = 32767 # 16384
times = float(MAXIMUM) / max(abs(i) for i in snd_data)
r = array('h')
for i in snd_data:
r.append(int(i times))
return r
signal.signal(signal.SIGINT, handle_int)
while not leave:
ring_buffer = collections.deque(maxlen=NUM_PADDING_CHUNKS)
triggered = False
voiced_frames = []
ring_buffer_flags = [0] NUM_WINDOW_CHUNKS
ring_buffer_index = 0
ring_buffer_flags_end = [0] NUM_WINDOW_CHUNKS_END
ring_buffer_index_end = 0
buffer_in = ''
# WangS
raw_data = array('h')
index = 0
start_point = 0
StartTime = time.time()
print(" recording: ")
stream.start_stream()
while not got_a_sentence and not leave:
chunk = stream.read(CHUNK_SIZE)
# add WangS
raw_data.extend(array('h', chunk))
index += CHUNK_SIZE
TimeUse = time.time() - StartTime
active = vad.is_speech(chunk, RATE)
sys.stdout.write('1' if active else '_')
ring_buffer_flags[ring_buffer_index] = 1 if active else 0
ring_buffer_index += 1
ring_buffer_index %= NUM_WINDOW_CHUNKS
ring_buffer_flags_end[ring_buffer_index_end] = 1 if active else 0
ring_buffer_index_end += 1
ring_buffer_index_end %= NUM_WINDOW_CHUNKS_END
# start point detection
if not triggered:
ring_buffer.append(chunk)
num_voiced = sum(ring_buffer_flags)
if num_voiced > 0.8 NUM_WINDOW_CHUNKS:
sys.stdout.write(' Open ')
triggered = True
start_point = index - CHUNK_SIZE 20 # start point
# voiced_frames.extend(ring_buffer)
ring_buffer.clear()
# end point detection
else:
# voiced_frames.append(chunk)
ring_buffer.append(chunk)
num_unvoiced = NUM_WINDOW_CHUNKS_END - sum(ring_buffer_flags_end)
if num_unvoiced > 0.90 NUM_WINDOW_CHUNKS_END or TimeUse > 10:
sys.stdout.write(' Close ')
triggered = False
got_a_sentence = True
sys.stdout.flush()
sys.stdout.write('\n')
# data = b''.join(voiced_frames)
stream.stop_stream()
print(" done recording")
got_a_sentence = False
# write to file
raw_data.reverse()
for index in range(start_point):
raw_data.pop()
raw_data.reverse()
raw_data = normalize(raw_data)
record_to_file("recording.wav", raw_data, 2)
leave = True
stream.close()
程序运行方式sudo python vad.py
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# python
# 端点检测
# 语音库
# webrtc
# Python如何实现文本转语音
# Python实现简单的语音识别系统
# Python语言实现百度语音识别API的使用实例
# python在命令行下使用google翻译(带语音)
# python实现百度语音识别api
# python调用百度语音识别实现大音频文件语音识别功能
# python调用百度REST API实现语音识别
# python调用百度语音REST API
# python调用百度语音识别api
# python语音识别实践之百度语音API
# 国内
# 主要包括
# 持续时间
# 自己的
# 检测到
# 都是
# 都有
# 还可以
# 尤其是
# 就能
# 很难
# 几天
# 上有
# 信道
# 雨后春笋
# 这部
# 英文
# 不像
# 很简单
# 考虑到
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Laravel如何集成第三方登录_Laravel Socialite实现微信QQ微博登录
如何自定义建站之星网站的导航菜单样式?
如何在企业微信快速生成手机电脑官网?
如何用低价快速搭建高质量网站?
简历在线制作网站免费版,如何创建个人简历?
Python结构化数据采集_字段抽取解析【教程】
详解MySQL数据库的安装与密码配置
b2c电商网站制作流程,b2c水平综合的电商平台?
如何制作新型网站程序文件,新型止水鱼鳞网要拆除吗?
html文件怎么打开证书错误_https协议的html打开提示不安全【指南】
Win11怎么更改系统语言为中文_Windows11安装语言包并设为显示语言
如何在IIS服务器上快速部署高效网站?
Win11怎么关闭透明效果_Windows11辅助功能视觉效果设置
小米17系列还有一款新机?主打6.9英寸大直屏和旗舰级影像
JS碰撞运动实现方法详解
html5audio标签播放结束怎么触发事件_onended回调方法【教程】
如何在橙子建站上传落地页?操作指南详解
Firefox Developer Edition开发者版本入口
英语简历制作免费网站推荐,如何将简历翻译成英文?
合肥制作网站的公司有哪些,合肥聚美网络科技有限公司介绍?
php读取心率传感器数据怎么弄_php获取max30100的心率值【指南】
php增删改查怎么学_零基础入门php数据库操作必知基础【教程】
Win11关机界面怎么改_Win11自定义关机画面设置【工具】
如何用IIS7快速搭建并优化网站站点?
高端企业智能建站程序:SEO优化与响应式模板定制开发
如何用wdcp快速搭建高效网站?
Laravel怎么调用外部API_Laravel Http Client客户端使用
七夕网站制作视频,七夕大促活动怎么报名?
简单实现Android验证码
Windows10如何更改计算机工作组_Win10系统属性修改Workgroup
Laravel Telescope怎么调试_使用Laravel Telescope进行应用监控与调试
微博html5版本怎么弄发超话_超话进入入口及发帖格式要求【教程】
如何在阿里云虚拟主机上快速搭建个人网站?
Android滚轮选择时间控件使用详解
如何正确选择百度移动适配建站域名?
Laravel如何实现多级无限分类_Laravel递归模型关联与树状数据输出【方法】
Laravel广播系统如何实现实时通信_Laravel Reverb与WebSockets实战教程
Win11怎么关闭专注助手 Win11关闭免打扰模式设置【操作】
Laravel Blade组件怎么用_Laravel可复用视图组件的创建与使用
Laravel如何实现多表关联模型定义_Laravel多对多关系及中间表数据存取【方法】
Laravel如何监控和管理失败的队列任务_Laravel失败任务处理与监控
Laravel怎么在Blade中安全地输出原始HTML内容
Laravel如何升级到最新的版本_Laravel版本升级流程与兼容性处理
如何在云指建站中生成FTP站点?
Laravel怎么集成Log日志记录_Laravel单文件与每日日志配置及自定义通道【详解】
Laravel怎么实现一对多关联查询_Laravel Eloquent模型关系定义与预加载【实战】
如何快速搭建高效WAP手机网站?
Laravel如何实现数据库事务?(DB Facade示例)
微信h5制作网站有哪些,免费微信H5页面制作工具?
Laravel如何部署到服务器_线上部署Laravel项目的完整流程与步骤

