Python实现语音控制图形移动:基于百度API与Tkinter的完整教程

远山来客
远山来客
发布时间:2026-10-15| 3人浏览过
原创

本文详解如何使用Python结合百度语音识别API与Tkinter库,实现通过语音指令控制图形界面中矩形移动的功能。内容涵盖获取百度Token、使用PyAudio进行本地录音、音频格式处理及Base64编码,以及通过tkinter.canvas实现图形交互。提供完整的AI.py与main.py代码结构及运行测试步骤,适合Python初学者了解语音交互与GUI开发结合的应用场景。

Python语音控制图形移动项目概述

本文参考了一篇通过识别文字来打开浏览器默认网站的文章,其核心思路是利用Python调用百度API实现语音识别功能。

本项目的目标相对简单:利用语音识别技术将用户说出的文字转化为指令,并根据文字内容控制图形在画布上的移动。例如,当识别到“向上”时,画布上的图形便会向上移动。为了实现这一功能,本文选用百度语音识别API,主要因其提供免费额度且易于接入。具体的系统流程图如下所示:

百度API应用创建与Token获取

接下来直接进入程序设计环节。首先,需要登录百度云控制台,并创建一个新应用以获取必要的接口凭证。

在创建应用的过程中,请务必注意保存生成的API Key和Secret Key。只有使用你自己创建的应用所对应的密钥,后续的程序才能正常调用服务并生效。

百度官方提供了详尽的语音识别开发文档,其中对具体的调用方法有清晰说明。如果希望深入理解底层原理,建议查阅其REST API文档以获取更详细的技术规范。

官方文档内容详实,但本文仅聚焦于实际开发中用到的核心方法。语音识别的基本流程为:首先组装URL以获取访问令牌(Token),接着处理本地音频文件,将其转换为JSON格式后发送至百度语音识别服务器,最后接收并解析返回的识别结果。

音频格式处理与录音实现

百度语音识别服务支持pcm、wav等多种音频格式。需要注意的是,如果上传非pcm格式(如wav或amr),百度服务端会额外执行格式转换操作,从而增加处理耗时。因此,建议将音频保存为pcm格式以获得最佳识别效果。然而,由于Windows系统自带的播放器通常无法直接识别pcm格式,为了便于调试和播放,本文改用wav格式,并在代码中引用wave库,该库主要用于读写wav类型的音频文件。在参数设置上,采样率固定使用pcm标准的16000Hz,编码格式为16bit位深的单声道音频。

在录音功能模块中,使用了PyAudio库。这是一个Python环境下的音频处理模块,主要作用是将音频流输送到计算机声卡进行录制。程序会在当前文件夹中打开一个新的音频流进行录音,并将录音数据暂存。本地录音的核心实现代码如下:


def save_wave_file(filepath, data):
    wf = wave.open(filepath, 'wb')
    wf.setnchannels(channels)
    wf.setsampwidth(sampwidth)
    wf.setframerate(framerate)
    wf.writeframes(b''.join(data))
    wf.close()
 
 
# 录音
def my_record():
    pa = PyAudio()
    # 打开一个新的音频stream
    stream = pa.open(format=paInt16, channels=channels,
                     rate=framerate, input=True, frames_per_buffer=num_samples)
    my_buf = []  # 存放录音数据
    t = time.time()
    print('正在录音...')
    while time.time() < t + 5:  # 设置录音时间(秒)
        # 循环read,每次read 2000frames
        string_audio_data = stream.read(num_samples)
        my_buf.append(string_audio_data)
    print('录音结束.')
    save_wave_file(FILEPATH, my_buf)
    stream.close()

语音识别API调用与数据处理

获取令牌(Token)是调用API的关键步骤。根据之前创建应用时获得的API Key和Secret Key,需要组装特定的URL来获取Token。在语音识别函数中,程序会调用获取到的Token以及已经录制好的音频数据,按照百度要求的格式写入JSON参数,从而完成音频上传。

百度语音接口要求对本地语音的二进制数据进行Base64编码,因此代码中使用了base64库进行编码处理。创建识别请求时采用POST方式提交,在识别函数中需填入百度语音提供的短语音识别请求地址。识别结果会即时返回,并以JSON格式封装,具体的识别文本位于JSON对象的“result”字段中,统一采用utf-8编码。


# 组装url获取token
base_url = "https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=%s&client_secret=%s"
APIKey = "*****************"
SecretKey = "********************"
HOST = base_url % (APIKey, SecretKey)
 
 
def getToken(host):
    res = requests.post(host)
    r = res.json()['access_token']
    return r
 
 
# 传入语音二进制数据,token
# dev_pid为百度语音识别提供的几种语言选择,默认1537为有标点普通话
def speech2text(speech_data, token, dev_pid=1537):
    FORMAT = 'wav'
    RATE = '16000'
    CHANNEL = 1
    CUID = '*******'
    SPEECH = base64.b64encode(speech_data).decode('utf-8')
    data = {
        'format': FORMAT,
        'rate': RATE,
        'channel': CHANNEL,
        'cuid': CUID,
        'len': len(speech_data),
        'speech': SPEECH,
        'token': token,
        'dev_pid': dev_pid
    }
    url = 'https://vop.baidu.com/server_api'  # 短语音识别请求地址
    headers = {'Content-Type': 'application/json'}
    print('正在识别...')
    r = requests.post(url, json=data, headers=headers)
    Result = r.json()
    if 'result' in Result:
        return Result['result'][0]
    else:
        return Result

Tkinter图形界面与移动控制逻辑

最后一步是编写控制图形移动的逻辑。首先需要明确如何在界面中呈现图形的移动效果。本项目选用tkinter模块,它是Python调用Tcl/Tk接口的标准GUI库,具有跨平台特性,是Python中较为流行的图形编程接口。尽管其性能相对较弱、执行速度较慢,但足以满足此类简单交互需求。

利用tkinter中的canvas组件,我们设置了一个画布,并创建了一个事件ID为1的矩形,将其显示在画布中。此外,在画布上添加了Button按钮,并在其回调函数中绑定了对应的逻辑。点击按钮将触发音频录制和语音识别流程。为了使代码结构更简洁,我们将移动函数直接嵌入到语音识别函数中调用:当识别结果返回后,程序对结果进行判断,进而驱动图形进行相应的移动。


def move(result):
    print(result)
    if "向上" in result:
        canvas.move(1, 0, -30)  # 移动的是 ID为1的事物【move(2,0,-5)则移动ID为2的事物】,使得横坐标加0,纵坐标减30
    elif "向下" in result:
        canvas.move(1, 0, 30)
    elif "向左" in result:
        canvas.move(1, -30, 0)
    elif "向右" in result:
        canvas.move(1, 30, 0)
 
 
tk = Tk()
tk.title("语音识别控制图形移动")
Button(tk, text="开始录音", command=AI.my_record).pack()
Button(tk, text="开始识别", command=speech2text).pack()
canvas = Canvas(tk, width=500, height=500)  # 设置画布
canvas.pack()  # 显示画布
r = canvas.create_rectangle(180, 180, 220, 220, fill="red")  # 事件ID为1
mainloop()

出于个人编码习惯,我将语音识别逻辑和图形控制逻辑分别写在了两个不同的文件中。这导致在main.py中无法直接获取AI.py中函数的返回值,因为tkinter模块通过mainloop()进入事件循环,该循环是持续运行的,直接调用无法获取返回值。为解决此问题,我在main.py中重新构建了一个函数来调用AI.py中的逻辑,并声明了全局变量,将AI.py中的返回值赋值给main.py的全局变量,从而成功获取识别结果,并将该函数绑定到Button的回调中,实现了预期功能。

实际上,这种分文件写法使得代码显得较为繁琐,如果将所有逻辑写在一个文件中会更简单。以下是两个文件之间的调用关系示意图:

完整代码结构与运行测试

以下是完整的Demo代码示例。

AI.py文件内容如下:


import wave  # 可读、写wav类型的音频文件。
import requests  # 基于urllib,采⽤Apache2 Licensed开源协议的 HTTP 库。在本项目中用于传递headers和POST请求
import time
import base64  # 百度语音要求对本地语音二进制数据进行base64编码
from pyaudio import PyAudio, paInt16  # 音频处理模块,用于将音频流输送到计算机声卡上
 
framerate = 16000  # 采样率
num_samples = 2000  # 采样点
channels = 1  # 声道
sampwidth = 2  # 采样宽度2bytes
FILEPATH = 'speech.wav'
 
# 组装url获取token
base_url = "https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=%s&client_secret=%s"
APIKey = "8bv3inF5roWBtEXYpZViCs39"
SecretKey = "HLXYiLGCpeOD6ddF1m6BvwcDZVOYtwwD"
HOST = base_url % (APIKey, SecretKey)
 
 
def getToken(host):
    res = requests.post(host)
    r = res.json()['access_token']
    return r
 
 
def save_wave_file(filepath, data):
    wf = wave.open(filepath, 'wb')
    wf.setnchannels(channels)
    wf.setsampwidth(sampwidth)
    wf.setframerate(framerate)
    wf.writeframes(b''.join(data))
    wf.close()
 
 
# 录音
def my_record():
    pa = PyAudio()
    # 打开一个新的音频stream
    stream = pa.open(format=paInt16, channels=channels,
                     rate=framerate, input=True, frames_per_buffer=num_samples)
    my_buf = []  # 存放录音数据
    t = time.time()
    print('正在录音...')
    while time.time() < t + 5:  # 设置录音时间(秒)
        # 循环read,每次read 2000frames
        string_audio_data = stream.read(num_samples)
        my_buf.append(string_audio_data)
    print('录音结束.')
    save_wave_file(FILEPATH, my_buf)
    stream.close()
 
 
def get_audio(file):
    with open(file, 'rb') as f:
        data = f.read()
    return data
 
 
# 传入语音二进制数据,token
# dev_pid为百度语音识别提供的几种语言选择,默认1537为有标点普通话
def speech2text(speech_data, token, dev_pid=1537):
    FORMAT = 'wav'
    RATE = '16000'
    CHANNEL = 1
    CUID = '*******'
    SPEECH = base64.b64encode(speech_data).decode('utf-8')
    data = {
        'format': FORMAT,
        'rate': RATE,
        'channel': CHANNEL,
        'cuid': CUID,
        'len': len(speech_data),
        'speech': SPEECH,
        'token': token,
        'dev_pid': dev_pid
    }
    url = 'https://vop.baidu.com/server_api'  # 短语音识别请求地址
    headers = {'Content-Type': 'application/json'}
    print('正在识别...')
    r = requests.post(url, json=data, headers=headers)
    Result = r.json()
    if 'result' in Result:
        return Result['result'][0]
    else:
        return Result

main.py文件内容如下:


import AI
from tkinter import *  # 导入tkinter模块的所有内容
 
token = None
speech = None
result = None
 
 
def getToken():
    temptoken = AI.getToken(AI.HOST)
    return temptoken
 
 
def speech2text():
    global token
    if token is None:
        token = getToken()
    speech = AI.get_audio(AI.FILEPATH)
    result = AI.speech2text(speech, token, dev_pid=1537)
    print(result)
    move(result)
 
 
def move(result):
    print(result)
    if "向上" in result:
        canvas.move(1, 0, -30)  # 移动的是 ID为1的事物【move(2,0,-5)则移动ID为2的事物】,使得横坐标加0,纵坐标减30
    elif "向下" in result:
        canvas.move(1, 0, 30)
    elif "向左" in result:
        canvas.move(1, -30, 0)
    elif "向右" in result:
        canvas.move(1, 30, 0)
 
 
tk = Tk()
tk.title("语音识别控制图形移动")
Button(tk, text="开始录音", command=AI.my_record).pack()
Button(tk, text="开始识别", command=speech2text).pack()
canvas = Canvas(tk, width=500, height=500)  # 设置画布
canvas.pack()  # 显示画布
r = canvas.create_rectangle(180, 180, 220, 220, fill="red")  # 事件ID为1
mainloop()

两个文件的依赖关系如下图所示:

程序运行时,录制的音频文件会自动保存在当前文件夹下的speech目录中。

接下来进行测试结果展示,运行程序后的初始界面如下:

点击“开始录音”按钮后,程序开始采集音频:

点击“开始识别”按钮后,程序执行语音识别逻辑:

识别成功后,可以看到画布中的红色矩形向右移动,表明指令解析正确:

经测试,用户在录音时适当提高音量(大吼)有助于提高识别准确率。

至此,关于基于Python创建语音识别控制系统的教程介绍完毕。如需了解更多Python语音识别控制系统的相关内容,欢迎搜索本站历史文章或继续浏览后续教程,希望大家今后多多支持本站!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。