Python实时音频识别与处理——让上网课不再单调

Python实时语音识别转字幕

实现原理

用speech_recognition库获得实时电脑音频输入,用requests和json库将生成的语音文件上传至百度的云语音识别服务器进行识别,返回结果用wx库显示为字幕,同时写为txt文件作为记录。用threading库调用两个thread,一个识别和处理音频,另一个从txt文件读取生成字幕。

该项目为个人参赛作品。原名TRAS(Toolkit for Recognition and Automatic Summarization),语音识别与自动总结工具。具体使用说明请看我的Github。该项目可用来为网课或语音生成字幕,也可帮助聋哑人“听”到电脑音频。代码写的不规范,请各位见谅!

代码

以下代码在我的Github上也有。这里为学习与分享的目的加了注释。

import requests
import json
import base64
import os
import logging
import speech_recognition as sr
import wx
import threading
#调用库

def get_token():  # 调用百度云语音识别API,具体看百度的技术文档
    logging.info('Retrieving token...') #和print差不多
    baidu_server = "https://openapi.baidu.com/oauth/2.0/token?"
    grant_type = "client_credentials"
    client_id = "EUON57v2pcpk5CDQnet6AN6s" #你的ID
    client_secret = "oHb0INPt5MGSC4LfoQ9hd7W2oSR6GLmV" #密钥
    url = f"{baidu_server}grant_type={grant_type}&client_id={client_id}&client_secret={client_secret}"
    res = requests.post(url)
    token = json.loads(res.text)["access_token"] #用json处理返回数据
    return token


def audio_baidu(filename):  # 上传音频至百度云语音识别,返回结果存储为文本
    if not os.path.exists('record'):
        os.makedirs('record') #创建目录
    filename = 'record/' + filename
    logging.info('Analysing audio file...')
    with open(filename, "rb") as f:
        speech = base64.b64encode(f.read()).decode('utf-8')
    size = os.path.getsize(filename)
    token = get_token()
    headers = {'Content-Type': 'application/json'}
    url = "https://vop.baidu.com/server_api"
    data = {
        "format": "wav",
        "rate": "16000",
        "dev_pid": 1737,  #识别类型。1737=english, 17372=enhanced english, 15372=enhanced chinese, 具体参考百度技术文档
        "speech": speech,
        "cuid": "3.141592653589793238462643383279502884197169399375105820", #独特的符号串
        "len": size,
        "channel": 1,
        "token": token,
    }

    req = requests.post(url, json.dumps(data), headers)
    result = json.loads(req.text)

    if result["err_msg"] == "success.":
        message = ''.join(result['result'])
        print('RETURNED: ' + message)
        return result['result']
    else:
        print("RETURNED: Recognition failure")
        return -1


def main():  # 线程2: 语音识别
    logging.basicConfig(level=logging.INFO)

    wav_num = 0
    while True:
        r = sr.Recognizer() #创建识别类
        mic = sr.Microphone() #创建麦克风对象
        logging.info('Recording...')
        with mic as source:
            r.adjust_for_ambient_noise(source) #减少环境噪音
            audio = r.listen(source, timeout=1000) #录音,1000ms超时
        with open('record/' + f"00{wav_num}.wav", "wb") as f:
            f.write(audio.get_wav_data(convert_rate=16000)) #写文件
        message = ''.join(audio_baidu(f"00{wav_num}.wav"))
        history = open('record/' + f"history.txt", "a")
        history.write(message + '\n')
        history.close()

        wav_num += 1


def update_content(win, height=200, width=800): #用来更新字幕窗口内容
    f = open('record/' + f"history.txt", "r") #读取文件
    try:
        last_line = f.readlines()[-1] #读文件最后一行
    except IndexError:
        last_line = ''
    if last_line.strip('\n') in ['key point']:  #有特殊词汇的话字幕加粗显示
        logging.info('Emphasized')
        ft = wx.Font(80, wx.MODERN, wx.NORMAL, wx.BOLD, False, '') #设置字体
    else:
        ft = wx.Font(50, wx.MODERN, wx.NORMAL, wx.NORMAL, False, '')
    richText = wx.TextCtrl(win, value='', pos=(0, 0), size=(width, height))
    richText.SetInsertionPoint(0) #从头插入文字,把原来的内容顶掉
    richText.SetFont(ft)
    richText.SetValue(last_line)
    f.close()
    return last_line


def show_win(x=320, y=550, height=200, width=800):  #创建字幕窗口
    win = wx.Frame(None, title="TRAS v1.0.0", pos=(x, y), size=(width, height), style=wx.STAY_ON_TOP) #创建Frame对象
    win.SetTransparent(1000) #透明度
    win.Show()

    return win


#主程序
if __name__ == "__main__":
    history = open('record/' + f"history.txt", "w+")
    history.close()

    thread = threading.Thread(target=main) #创建另一个thread跑语音识别
    thread.start()

    global app #这里有报错,要设置全局变量
    app = wx.App() #创建对象
    while True:
        win = show_win() #创建字幕窗口
        v = update_content(win) #更新窗口内容
        wx.CallLater(2000, win.Destroy) #两秒没操作的话隐藏窗口
        app.MainLoop()

运行结果

(整个项目的运行方法请看Github
程序开始运行后,对着电脑麦克风说话,就能顺利显示实时字幕啦!
hello
nice to meet you

功能拓展

该程序目前支持MacOS,WinOS未测试。选用ws库也是因为它支持Mac更好。其它的辅助功能请见github。这里的版本是英文识别,目前的id与密钥调用的是博主的免费额度,到达上限后可能会报错。有兴趣的同学可以了解百度云的其它功能,自行注册账号获得调用额度。有任何问题欢迎私信讨论或评论区留言!

### 使用正弦(Sine)作为激活函数的优缺点及应用场景 #### 优点 1. **周期性和平滑性** 正弦函数具有周期性的特性,这使得它能够捕捉到数据中的周期模式。这种特性对于处理时间序列数据或信号处理任务非常有用[^2]。 2. **非线性映射能力** 正弦函数是非线性函数,能够在神经网络中引入复杂的非线性关系。相比于传统的单调激活函数(如ReLU),它可以更好地表示某些特定类型的复杂函数[^3]。 3. **导数简单且连续** 正弦函数的导数是余弦函数,其形式简单且在整个实数范围内连续可微分。这一特点有助于稳定训练过程中的梯度流动[^5]。 4. **适用于频域建模** 在涉及频率成分的任务中,例如音频合成、图像重建等场景下,正弦激活函数可能表现出更好的适应性。 #### 缺点 1. **饱和区域问题** 类似于其他基于三角函数的激活函数,当输入值远离原点时,正弦函数会进入饱和状态,导致梯度接近零。这种情况可能会阻碍反向传播过程中权重的有效更新。 2. **振荡行为可能导致不稳定收敛** 由于正弦函数本身的周期性特征,在优化期间可能出现频繁切换方向的现象,从而增加找到全局最优解难度,并延长训练时间[^4]。 3. **初始化敏感性** 对初始参数设置较为敏感,如果随机初始化不当,则容易陷入局部极小值或者造成模型难以学习有效表征。 #### 应用场景 1. **物理仿真动力学预测** 当目标是对自然界中存在的波动现象进行模拟时,比如弹簧振动系统或是电磁波传播规律的研究等领域里,采用sin作为隐藏层单元间的转换机制往往能取得不错的效果。 2. **音乐生成语音识别** 音乐音符本质上是由不同频率组合而成的声音片段集合;而人类说话声音也包含了丰富的谐波结构信息。因此利用具备良好表达这些特性的工具——即含sine component 的NN架构来进行此类任务显得尤为合适。 3. **计算机视觉中的纹理分析** 图像中的许多重复图案可以通过分解成若干基本正弦波叠加来近似描述出来。所以针对这类需求设计含有相应组件的算法框架将会更加贴切实际状况下的表现形式。 ```python import torch import torch.nn as nn class SineActivation(nn.Module): def __init__(self): super(SineActivation, self).__init__() def forward(self, x): return torch.sin(x) # Example usage within a neural network model definition. model = nn.Sequential( nn.Linear(784, 128), SineActivation(), nn.Linear(128, 64), SineActivation(), nn.Linear(64, 10) ) ```
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

EricFrenzy

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

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

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

打赏作者

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

抵扣说明:

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

余额充值