Python+Appium+百度sdk(三)--语音识别控制

这次的目标是继上次的健康时报打卡机器人,现在要实现语音控制。

一、部署工作

使用的是百度智能云:具体操作文档https://ai.baidu.com/ai-doc/SPEECH/Gk38lyqzo

入门者看着新手指南就可以了。

之后进入百度智能云登录账号后领取可以实现语音识别的额度:

 之后点击创建任务:

 

 之后就获取了语音识别的AppID、API Key、Secret Key:

点击隔壁的技术文档:

 

 之后点击下载SDK:

 下载Python SDK:

 注意看一下使用说明:

 之后就开始入门吧。

二、语音识别

 安装Python SDK:

pip install baidu-api

 或者在Pycharm中找到baidu-aip进行下载:

 之后打开pycharm,新建ApiSpeech:参考如下代码

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)

按照技术文档进行操作,要对一段语音文件进行识别:

需要注意的是下面需要调用ffmpeg,在上次的文章中我已经下载完成了:

  

在cmd中输入ffmpeg表示配置成功。

开启pycharm,在pycharm中的用法如下:

ffmpeg -y  -i %s  -acodec pcm_s16le -f s16le -ac 1 -ar 16000 %s.pcm

第一个%s表示原始文件

第二个%s也表示原始文件,但是它加了后缀.pcm

在请求时需要指定一个pcm格式的文件,而技术文档给的是如下的代码:

# 读取文件
def get_file_content(filePath):
    with open(filePath, 'rb')as fp:
        return fp.read()


# 识别本地文件
a = client.asr(get_file_content('录音.pcm'), 'pcm', 16000, {'dev_pid': 1537})

print(a)

看看它需要的参数有如下:

有参数表我们可得知需要格式为pcm、wav或者amr的格式。

如果我单纯只用电脑录音,只会让它报错:

Traceback (most recent call last): File "D:/PythonvideoTest/mian.py", line 18, in <module> a = client.asr(get_file_content('录音.m4a'), 'pcm', 16000, {'dev_pid': 1537}) File "D:\PythonvideoTest\venv\lib\site-packages\aip\speech.py", line 69, in asr data['speech'] = base64.b64encode(speech).decode() File "D:\python\lib\base64.py", line 58, in b64encode encoded = binascii.b2a_base64(s, newline=False) TypeError: a bytes-like object is required, not 'builtin_function_or_method'  

 16000表示采样率,1537表示是保准的普通话,不可以带口音。

 之后我调用了ffmepg进行转码,否则无法生成正确的识别效果:

# 读取文件
def get_file_content(filePath):
    cmd_str = "ffmpeg -y  -i %s  -acodec pcm_s16le -f s16le -ac 1 -ar 16000 %s.pcm" % (filePath, filePath)
    os.system(cmd_str)  # 调用系统命令ffmpeg,传入音频文件名
    with open(filePath, 'rb')as fp:
        return fp.read()


# 识别本地文件
a = client.asr(get_file_content('video.m4a'), 'pcm', 16000, {'dev_pid': 1537, })

print(a)

最后的结果是:

上面红色的字是转码的过程。

看看传出来的字典是代表什么意思:

{'corpus_no': '7065173086757783768', 
 'err_msg': 'success.', 
 'err_no': 0,
 'result': ['你好。'], 
 'sn': '460221681121644988797'}

若err_msg包含的是错误描述信息,帮助理解和解决发生的错误,看下面这个文档:

https://ai.baidu.com/ai-doc/SPEECH/Dk4o0bmkl

接下来就从字典中取字:

print(a['result'])

在网上看见:当key不存在时,要使用如下:

if a.get('result'):
	print(a.get('result')[0])

三、语音生成

result = client.synthesis('嘿嘿嘿嘿嘿', 'zh', 1, {'vol': 5, })

# 识别正确返回语音二进制,错误则返回dict 参照下面代码
if not isinstance(result, dict):
    with open("audio.mp3", 'wb')as f:
        f.write(result)
        #调用系统命令
        os.system("audio.mp3")

之后在目录会出现一个audio.mp3文件。但是我并没有生成音频T T。

语音生成的参数:

        'spd':5,  # 语速-中等
        'vol': 5,  # 音量-中等
        'pit':5,  # 音调-中等
        'per':0  # 发音人-女声

然后我就把result的结果打印出来:

{'err_detail': '16: Open api characters limit reached',
'err_msg': '16: Open api characters limit reached',
'err_no': 502,
'err_subcode': 16,
'tts_logid': 3329425580}

所以结果是我的字长超过了限制:Open api characters limit reached,没有对应接口额度。

原来是我没有领取免费额度...额...醉了。

  

其他错误:

https://ai.baidu.com/ai-doc/SPEECH/Ck4nlz91i

四、实时语音识别

(一)各种模块的安装

在上面我们都是使用本地的音频来识别检测的,那么要保持检测麦克风,只要有声音就生成wav文件向API发送请求,当识别不到语音信息时,则自动停止。

使用的语音识别模块为:speech_recognition

需要的其他模块:baidu-aip、PyAudio、pyttsx3、wave

具体说明:

在windows平台下,使用speech_recognition记录音频,并转换为16k的wav,之后利用ffmpeg将wav转化为pcm文件,上传到百度语音端,返回语音信息。

 安装speech_recognition:SpeechRecognition · PyPI

pip install SpeechRecognition

或者在pycharm中安装:

 安装pocketsphinx(离线语音识别)

pip install pocketsphinx

如若出现:

 那么就去:https://www.lfd.uci.edu/~gohlke/pythonlibs/#pocketsphinx下载whl文件,我下载的是:

 安装PyAudio:PyAudio · PyPI

pip install PyAudio

如若出现下面的报错:

ERROR: Command errored out with exit status 1: 'd:\python\python.exe' -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\Users\auus\AppData\Local\Temp\pip-install-qifk_0di\pyaudio_ca262538ea45479397c1173b7e87e16a\setup.py'"'"'; __ file ='"'"'C:\Users\auus\AppData\Local\Temp\pip-install-qifk_0di\pyaudio_ca262538ea45479397c1173b7e87e16a\setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(file) if os.path.exists(file) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file__, '"'"'exec'"'"'))' install --record 'C:\Users\auus\AppData\Local\Temp\pip-record-2f5ahtzc\install-record.txt' --single-version-externally-managed --compile --install-headers 'd:\python\Include\PyAudio' Check the logs for full command output.

ERROR: Command errored out with exit status 1: command: 'd:\python\python.exe' -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\Users\auus\AppData\Local\Temp\pip-install-qifk_0di\pyaudio_ca262538ea45479397c1173b7e87e16a\setup.py'"'"'; file='"'"'C:\Users\auus\AppData\Local\Temp\pip-install-qifk_0di\pyaudio_ca262538ea45479397c1173b7e87e16a\setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(file) if os.path.exists(file) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' install --record 'C:\Users\auus\AppData\Local\Temp\pip-record-2f5ahtzc\install-record.txt' --single-version-externally-managed --compile --install-headers 'd:\python\Include\PyAudio' cwd: C:\Users\auus\AppData\Local\Temp\pip-install-qifk_0di\pyaudio_ca262538ea45479397c1173b7e87e16a\

解决过程:

 

  •  下载后切换到终端使用pip执行刚刚下载好的文件
pip install PyAudio-0.2.11-cp38-cp38-win_amd64.whl

在GitHub上有语音识别的Demo:https://github.com/Uberi/speech_recognition/blob/master/examples/microphone_recognition.py

在过程中我遇到了一个我明明在pycharm的配置环境中安装了PyAudio(在Windows上安装的),但是使用import PyAduio时却出错的问题。最后我重装python修改了虚拟环境才得以解决这个问题...

(2)代码

语音识别库参考:https://github.com/Uberi/speech_recognition/blob/master/reference/library-reference.rst

第一步:实现可以听取麦克风并且进行读取文本。

import time
import speech_recognition as sr
import pyaudio
import os
import pyttsx3
import wave
import pocketsphinx
from aip import AipSpeech

APP_ID = '25611234'
API_KEY = 'Ia1pGYSvwe3iWfOr0x1n1234'
SECRET_KEY = '4rTh892aD0qh49VwlsTmRiQ6iwv12345'

client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)


# 用于录音speech_recognition
def grow_audio(rate=16000):
    # 用于读取麦克风
    r = sr.Recognizer()
    with sr.Microphone(sample_rate=rate) as source:
        print("他在等你讲话...")
        # 动态调整能量阈值以解决环境噪音
        r.adjust_for_ambient_noise(source)
        # 限制录音时长位30s
        audio = r.listen(source, phrase_time_limit=30)
        print('okk!')
    # 将音频写入
    with open('voice.wav', 'wb') as f:
        f.write(audio.get_wav_data())


# 读取文件
def get_file_content(filePath):
    cmd_str = "ffmpeg -y  -i %s  -acodec pcm_s16le -f s16le -ac 1 -ar 16000 %s.pcm" % (filePath, filePath)
    os.system(cmd_str)  # 调用系统命令ffmpeg,传入音频文件名
    with open(filePath + ".pcm", 'rb')as fp:
        return fp.read()


# 识别文件 使用百度API
def pcm2text():
    pcm_audio = get_file_content('voice.wav')
    text = client.asr(pcm_audio, 'pcm', 16000, {'dev_pid': 1537, })
    print(text['result'])


if __name__ == "__main__":
    while True:
        grow_audio()
        pcm2text()

最后实现效果为:

第二步:实现人机交互

导入上次实现的半自动打卡机器人的程序,并且加入pyttsx3进行人机交互。

import time
import speech_recognition as sr
import pyaudio
import os
import pyttsx3
import wave
import pocketsphinx
from aip import AipSpeech
from appium import webdriver
from appium.webdriver.common.touch_action import TouchAction

APP_ID = '25611234'
API_KEY = 'Ia1pGYSvwe3iWfOr0x1n1234'
SECRET_KEY = '4rTh892aD0qh49VwlsTmRiQ6iwv12345'

client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)


# 用于录音speech_recognition
def grow_audio(rate=16000):
    # 用于读取麦克风
    r = sr.Recognizer()
    with sr.Microphone(sample_rate=rate) as source:
        print("他在等你讲话...")
        # 动态调整能量阈值以解决环境噪音
        r.adjust_for_ambient_noise(source)
        # 限制录音时长位30s
        audio = r.listen(source, phrase_time_limit=30)
        print('okk!')
    # 将音频写入
    with open('voice.wav', 'wb') as f:
        f.write(audio.get_wav_data())


# 读取文件
def get_file_content(filePath):
    cmd_str = "ffmpeg -y  -i %s  -acodec pcm_s16le -f s16le -ac 1 -ar 16000 %s.pcm" % (filePath, filePath)
    os.system(cmd_str)  # 调用系统命令ffmpeg,传入音频文件名
    with open(filePath + ".pcm", 'rb')as fp:
        return fp.read()


# 识别文件 使用百度API
def pcm2text():
    pcm_audio = get_file_content('voice.wav')
    text = client.asr(pcm_audio, 'pcm', 16000, {'dev_pid': 1537, })
    print(text['result'])
    return text['result']


def say_hi():
    engine.say('嘿,你来找我玩啦!')
    # 本句话是没有声音的,如果要调用say()函数,每次调用都要加上这句
    engine.runAndWait()


# 健康上报
def headlth_update():
    tests = {
        "platformName": "Android",
        "platformVersion": "11",
        "deviceName": "M2012K11AC",
        "appPackage": " com.tencent.wework",
        "appActivity": ".launch.LaunchSplashEduActivity",
        "noReset": "True"
    }
    driver = webdriver.Remote("http://localhost:4723/wd/hub", tests)
    engine.say('正在健康上报')
    engine.runAndWait()
    time.sleep(3)
    # 工作台
    el1 = driver.find_element_by_xpath(
        "/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget"
        ".LinearLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android"
        ".widget.LinearLayout/android.view.ViewGroup/android.widget.RelativeLayout["
        "4]/android.widget.RelativeLayout/android.widget.TextView")
    el1.click()
    time.sleep(6)
    el2 = driver.find_element_by_xpath(
        "/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget"
        ".LinearLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android"
        ".widget.FrameLayout[2]/android.widget.RelativeLayout/android.view.ViewGroup/androidx.recyclerview.widget"
        ".RecyclerView/android.widget.RelativeLayout["
        "1]/android.widget.LinearLayout/android.widget.RelativeLayout/android.widget.ImageView")
    el2.click()
    engine.say('健康上报完成')
    engine.runAndWait()


if __name__ == "__main__":
    # 初始化
    engine = pyttsx3.init()
    say_hi()
    while True:
        grow_audio()
        output = pcm2text()
        if '企业微信进行健康上报' or '打开' or '微信' or '健康上报' in output:
            engine.say('好的')
            engine.runAndWait()
            headlth_update()

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

郑烯烃快去学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值