【Python实践】使用Python实时语音控制电脑全局音量

时间:2022-12-29 07:12:38

前言

说到人工智能中语言实时识别技术及通过人工智能控制设备,大家应该比较熟悉,基本充斥着我们生活的方方面面,比如智能家居,我们手机中的智能机器人,如:苹果的Siri,小米的小爱,天猫精灵,华为的小艺,微软的小冰,以及银行大堂或者酒店前台线下服务类的迎宾机器人等等。都是我们常用到的人工智能语音实时控制技术,那假如我们自己来开发一个语言控制程序来控制我们的电脑或者其他设备,我们应该怎么做呢,一直停留在应用层面的开发人员是不是跃跃欲试呢。开发这样的程序我们需要用到哪些技术,哪些库呢?废话不多说,直接进入实操阶段。本文通过实现实时语音控制电脑音量展开实操。

需要用到的技术和工具

Python

正如我们的题目所提到。所以实现这个程序需要使用到Python编程语言,还没学会Python语言的童鞋,可以快速了解一下,就算不了解。如果你只是想试试,跟着教程基本也能完成,但是前提是你电脑有Python的开发环境,关于环境的相关安装,线上有很多介绍,这里就不再赘述

语音识别库SpeechRcognition

SpeechRcognition的特点优势:

  1. 满足几种主流语音 API ,灵活性高;
  2. Google Web Speech API 支持硬编码到 SpeechRecognition 库中的默认 API 密钥,无需注册就可用;
  3. SpeechRecognition无需构建访问麦克风和从头开始处理音频文件的脚本, 只需几分钟即可自动完成音频输入、检索并运行。因此易用性很高。

安装命令:

pip install SpeechRecognition

安装情况如下图:

【Python实践】使用Python实时语音控制电脑全局音量

音频库:pyaudio

pyaudio库,使用pyaudio可以进行录音,音频播放,生成wav文件等等操作。PyAudio 提供了 PortAudio 的 Python 语言版本,这是一个跨平台的音频 I/O 库,使用 PyAudio 你可以在 Python 程序中播放和录制音频。为PoTaTudio提供Python绑定,跨平台音频I/O库。使用PyAudio,您可以轻松地使用Python在各种平台上播放和录制音频,例如GNU/Linux、微软Windows和苹果Mac OS X/MACOS。

安装命令如下:

pip install pyAudio

安装情况如下图:

【Python实践】使用Python实时语音控制电脑全局音量

百度人工智能接口

AipSpeech是语音识别的Python SDK客户端,为使用语音识别的开发人员提供了一系列的交互方法。

安装命令如下:

pip install baidu-aip

代码中的使用

from aip import AipSpeech

官方文档:​​https://cloud.baidu.com/doc/SPEECH/s/Bk4o0bmt3​

官方链接:​​https://console.bce.baidu.com/ai/?fromai=1#/ai/speech/overview/index​

电脑控制模块pycaw

pycaw是一个windows系统控制的Python库,本文就是通过pycaw库来对电脑音量进行控制

安装命令如下:

pip3 install pycaw -i https://pypi.douban.com/simple

下面直接进入实践阶段

编程实践

百度接口基本使用

导入百度语音库AipSpeech

from aip import AipSpeech

""" 你的 APPID AK SK """
APP_ID = '你的 App ID'
API_KEY = '你的 Api Key'
SECRET_KEY = '你的 Secret Key'

client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)

这个是实时语音效果:

【Python实践】使用Python实时语音控制电脑全局音量

引入其他相关库

import time
import speech_recognition as sr
import logging #debug日志记录

音量控制需要引入的库,所以说Python开发简单,得益于他有很多现成的模块

from ctypes import cast, POINTER
from comtypes import CLSCTX_ALL
from pycaw.pycaw import AudioUtilities, IAudioEndpointVolume

由于pycaw中的vol_range与0-100这个不是对应的关系,不方便设置实际的声音,因此需要进行装换,但是无法得知其转换关系,暂时没有转换的公式,只能通过字典的形式查询,建立音量对应关系如下:

dict = {0: -65.25, 1: -56.99, 2: -51.67, 3: -47.74, 4: -44.62, 5: -42.03, 6: -39.82, 7: -37.89, 8: -36.17,
9: -34.63, 10: -33.24,
11: -31.96, 12: -30.78, 13: -29.68, 14: -28.66, 15: -27.7, 16: -26.8, 17: -25.95, 18: -25.15, 19: -24.38,
20: -23.65,
21: -22.96, 22: -22.3, 23: -21.66, 24: -21.05, 25: -20.46, 26: -19.9, 27: -19.35, 28: -18.82, 29: -18.32,
30: -17.82,
31: -17.35, 32: -16.88, 33: -16.44, 34: -16.0, 35: -15.58, 36: -15.16, 37: -14.76, 38: -14.37, 39: -13.99,
40: -13.62,
41: -13.26, 42: -12.9, 43: -12.56, 44: -12.22, 45: -11.89, 46: -11.56, 47: -11.24, 48: -10.93, 49: -10.63,
50: -10.33,
51: -10.04, 52: -9.75, 53: -9.47, 54: -9.19, 55: -8.92, 56: -8.65, 57: -8.39, 58: -8.13, 59: -7.88,
60: -7.63,
61: -7.38, 62: -7.14, 63: -6.9, 64: -6.67, 65: -6.44, 66: -6.21, 67: -5.99, 68: -5.76, 69: -5.55, 70: -5.33,
71: -5.12, 72: -4.91, 73: -4.71, 74: -4.5, 75: -4.3, 76: -4.11, 77: -3.91, 78: -3.72, 79: -3.53, 80: -3.34,
81: -3.15, 82: -2.97, 83: -2.79, 84: -2.61, 85: -2.43, 86: -2.26, 87: -2.09, 88: -1.91, 89: -1.75,
90: -1.58,
91: -1.41, 92: -1.25, 93: -1.09, 94: -0.93, 95: -0.77, 96: -0.61, 97: -0.46, 98: -0.3, 99: -0.15, 100: 0.0}

因为语音识别接口识别出来可能是中文,这里需要将数字中文表达转为数字

#中文转数字
common_used_numerals_tmp ={'零':0, '一':1, '二':2, '两':2, '三':3, '四':4, '五':5, '六':6, '七':7, '八':8, '九':9, '十':10, '百':100, '千':1000, '万':10000, '亿':100000000}

def chinese2digits(uchars_chinese):
total = 0
r = 1 #表示单位:个十百千...
for i in range(len(uchars_chinese) - 1, -1, -1):
val = common_used_numerals_tmp.get(uchars_chinese[i])
if val >= 10 and i == 0: #应对 十三 十四 十*之类
if val > r:
r = val
total = total + val
else:
r = r * val
#total =total + r * x
elif val >= 10:
if val > r:
r = val
else:
r = r * val
else:
total = total + r * val
return total

调用麦克风进行语音识别

r = sr.Recognizer()
# 麦克风
mic = sr.Microphone(sample_rate=16000)
while True:
logging.info('录音中...')
with mic as source:
r.adjust_for_ambient_noise(source)
audio = r.listen(source)
logging.info('录音结束,识别中...')

start_time = time.time()
print(type(audio))
audio_data = audio.get_wav_data()
print(type(audio_data))
# 识别本地文件
ret = aip_speech.asr(audio_data, 'wav', 16000, {'dev_pid': 1536, })
print(ret)
if ret and ret['err_no'] == 0:
result = ret['result'][0]
print(result)

status = result[4:].isdigit()
if not status:
myvol = chinese2digits(result[4:])
else:
myvol = result[4:]

print(myvol)
# 设置音量大小
volume.SetMasterVolumeLevel(dict[int(myvol)], None)

end_time = time.time()
print(end_time - start_time)
else:
print(ret['err_msg'])
logging.info('end')

完整代码

"""
实时语音控制电脑音量
"""
import time
import speech_recognition as sr
import logging
from ctypes import cast, POINTER
from comtypes import CLSCTX_ALL
from pycaw.pycaw import AudioUtilities, IAudioEndpointVolume

logging.basicConfig(level=logging.DEBUG)
from aip import AipSpeech

# filename = './audio/test.wav'

BAIDU_APP_ID = '你的 App ID'
BAIDU_API_KEY = '你的 Api Key'
BAIDU_SECRET_KEY = '你的 Secret Key'

aip_speech = AipSpeech(BAIDU_APP_ID, BAIDU_API_KEY, BAIDU_SECRET_KEY)

#中文转数字
common_used_numerals_tmp ={'零':0, '一':1, '二':2, '两':2, '三':3, '四':4, '五':5, '六':6, '七':7, '八':8, '九':9, '十':10, '百':100, '千':1000, '万':10000, '亿':100000000}

def chinese2digits(uchars_chinese):
total = 0
r = 1 #表示单位:个十百千...
for i in range(len(uchars_chinese) - 1, -1, -1):
val = common_used_numerals_tmp.get(uchars_chinese[i])
if val >= 10 and i == 0: #应对 十三 十四 十*之类
if val > r:
r = val
total = total + val
else:
r = r * val
#total =total + r * x
elif val >= 10:
if val > r:
r = val
else:
r = r * val
else:
total = total + r * val
return total

#电脑声音控制
devices = AudioUtilities.GetSpeakers()
interface = devices.Activate(IAudioEndpointVolume._iid_, CLSCTX_ALL, None)
volume = cast(interface, POINTER(IAudioEndpointVolume))

# 获取音量值,0.0代表最大,-65.25代表最小
vl = volume.GetMasterVolumeLevel()
print(vl)

dict = {0: -65.25, 1: -56.99, 2: -51.67, 3: -47.74, 4: -44.62, 5: -42.03, 6: -39.82, 7: -37.89, 8: -36.17,
9: -34.63, 10: -33.24,
11: -31.96, 12: -30.78, 13: -29.68, 14: -28.66, 15: -27.7, 16: -26.8, 17: -25.95, 18: -25.15, 19: -24.38,
20: -23.65,
21: -22.96, 22: -22.3, 23: -21.66, 24: -21.05, 25: -20.46, 26: -19.9, 27: -19.35, 28: -18.82, 29: -18.32,
30: -17.82,
31: -17.35, 32: -16.88, 33: -16.44, 34: -16.0, 35: -15.58, 36: -15.16, 37: -14.76, 38: -14.37, 39: -13.99,
40: -13.62,
41: -13.26, 42: -12.9, 43: -12.56, 44: -12.22, 45: -11.89, 46: -11.56, 47: -11.24, 48: -10.93, 49: -10.63,
50: -10.33,
51: -10.04, 52: -9.75, 53: -9.47, 54: -9.19, 55: -8.92, 56: -8.65, 57: -8.39, 58: -8.13, 59: -7.88,
60: -7.63,
61: -7.38, 62: -7.14, 63: -6.9, 64: -6.67, 65: -6.44, 66: -6.21, 67: -5.99, 68: -5.76, 69: -5.55, 70: -5.33,
71: -5.12, 72: -4.91, 73: -4.71, 74: -4.5, 75: -4.3, 76: -4.11, 77: -3.91, 78: -3.72, 79: -3.53, 80: -3.34,
81: -3.15, 82: -2.97, 83: -2.79, 84: -2.61, 85: -2.43, 86: -2.26, 87: -2.09, 88: -1.91, 89: -1.75,
90: -1.58,
91: -1.41, 92: -1.25, 93: -1.09, 94: -0.93, 95: -0.77, 96: -0.61, 97: -0.46, 98: -0.3, 99: -0.15, 100: 0.0}


r = sr.Recognizer()
# 麦克风
mic = sr.Microphone(sample_rate=16000)
while True:
logging.info('录音中...')
with mic as source:
r.adjust_for_ambient_noise(source)
audio = r.listen(source)
logging.info('录音结束,识别中...')

start_time = time.time()
print(type(audio))
audio_data = audio.get_wav_data()
print(type(audio_data))
# 识别本地文件
ret = aip_speech.asr(audio_data, 'wav', 16000, {'dev_pid': 1536, })
print(ret)
if ret and ret['err_no'] == 0:
result = ret['result'][0]
print(result)

status = result[4:].isdigit()
if not status:
myvol = chinese2digits(result[4:])
else:
myvol = result[4:]

print(myvol)
# 设置音量大小
volume.SetMasterVolumeLevel(dict[int(myvol)], None)

end_time = time.time()
print(end_time - start_time)
else:
print(ret['err_msg'])
logging.info('end')

执行结果如下:

【Python实践】使用Python实时语音控制电脑全局音量

【Python实践】使用Python实时语音控制电脑全局音量