你有没有想过如何使用 Python 进行实时语音到文本的转录?我们将使用 Quart 和 Deepgram 来实现本文中的目标。

Quart 是一个异步的 Python Web 微框架,可以更轻松地为 WebSocket 提供服务,我们将在本教程中使用它。 Quart 是 Flask 的异步重新实现。如果我们熟悉 Flask,我们将能够快速升级 Quart。 Deepgram 使用 AI 语音识别来进行实时音频转录,我们将使用我们的 Python SDK。

如果您想继续前进,该项目的最终代码位于 Github 中的此处。

入门

在我们开始之前,必须生成一个 Deepgram API 密钥以在我们的项目中使用。我们可以去这里。对于本教程,我们将使用 Python 3.10,但 Deepgram 也支持一些早期版本的 Python。我们还需要设置一个虚拟环境来保存我们的项目。我们可以在这里阅读更多关于的信息以及如何创建一个。

安装依赖

创建一个文件夹目录来存储我们所有的项目文件,并在其中创建一个虚拟环境。确保我们的虚拟环境已激活,如上一节中的文章所述。确保所有依赖项都安装在该环境中。

为了快速参考,以下是我们创建和激活虚拟环境所需的命令:

mkdir [% NAME_OF_YOUR_DIRECTORY %]
cd [% NAME_OF_YOUR_DIRECTORY %]
python3 -m venv venv
source venv/bin/activate

进入全屏模式 退出全屏模式

我们需要从终端安装以下依赖项:

  • Quart最新版

  • Deepgram Python SDK

  • dotenv 库,它帮助我们处理环境变量

pip install quart
pip install deepgram-sdk
pip install python-dotenv

进入全屏模式 退出全屏模式

创建 Quart 应用程序

让我们启动并运行一个启动并运行一个呈现 HTML 页面的入门 Quart 应用程序,以便我们可以继续我们的实时语音到文本转录项目。

在我们的项目中创建一个名为main.py的文件,以及一个包含名为index.html的 HTML 文件的模板文件夹

[quart 项目结构](https://res.cloudinary.com/practicaldev/image/fetch/s--I6A4w3m4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to -uploads.s3.amazonaws.com/uploads/articles/l6mf37ucywrt87t99du9.png)

main.py文件将保存我们的 Python 代码。

from quart import Quart, render_template

app = Quart(__name__)

@app.route('/')
async def index():
   return await render_template('index.html')

if __name__ == "__main__":
   app.run('localhost', port=3000, debug=True)

进入全屏模式 退出全屏模式

最后,我们将 HTML 文件存储在模板文件夹中,并在此处保存我们的 HTML 标记。

<!DOCTYPE html>
<html>
  <head>
      <title>Live Transcription</title>
  </head>
  <body>
      <h1>Transcribe Audio With Quart</h1>
      <p id="status">Connection status will go here</p>
      <p id="transcript"></p>
  </body>
</html>

进入全屏模式 退出全屏模式

我们必须将其导出到环境变量中才能运行应用程序。在我们的终端中,输入以下内容:

export QUART_APP=main:app

进入全屏模式 退出全屏模式

如果我们从终端启动我们的开发服务器使用python main.py运行项目,并在http://127.0.0.1:3000/处打开浏览器,index.html页面将呈现:

[渲染 Quart index HTML 页面](https://res.cloudinary.com/practicaldev/image/fetch/s--T5gvXM0e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https:// dev-to-uploads.s3.amazonaws.com/uploads/articles/od217suz9ovi1023czzj.png)

添加 Deepgram API Key

我们的 API 密钥将允许使用 Deepgram 使用 AI 语音识别进行实时音频转录。让我们创建一个.env文件来存储我们的密钥。当我们将代码推送到 Github 时,请确保将此文件添加到我们的.gitignore文件中,从而隐藏我们的密钥。

[使用 .env 文件隐藏 api 密钥](https://res.cloudinary.com/practicaldev/image/fetch/s--hOJny0Qj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https:/ /dev-to-uploads.s3.amazonaws.com/uploads/articles/ua8uzhe6m42bro05n4b4.png)

在我们的文件中,使用我们的 Deepgram API 密钥添加以下环境变量,我们可以在这里抓取:

DEEPGRAM_API_KEY="abcde12345"

进入全屏模式 退出全屏模式

下面的代码展示了如何将我们的密钥加载到项目中并在main.py中访问它:

from deepgram import Deepgram
from dotenv import load_dotenv
import os

load_dotenv()

app = Quart(__name__)

dg_client = Deepgram(os.getenv('DEEPGRAM_API_KEY'))

进入全屏模式 退出全屏模式

从浏览器获取麦克风数据

我们的下一步是从浏览器获取麦克风数据,这需要一点 JavaScript。

index.html中的<script></script>标签内使用此代码来访问用户的麦克风数据。

<script>
 navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {
   if (!MediaRecorder.isTypeSupported('audio/webm')) return alert('Browser not supported')
   const mediaRecorder = new MediaRecorder(stream, { mimeType: 'audio/webm' })
 })
</script>

进入全屏模式 退出全屏模式

如果您想了解有关在浏览器中使用麦克风的更多信息,请查看这篇文章。

服务器和浏览器之间的Websocket连接

我们需要在我们的项目中使用 WebSockets。我们可以将 WebSockets 视为服务器和客户端之间的连接,它保持打开状态并允许来回发送连续消息。

第一个 WebSocket 连接位于保存 Quart 应用程序的 Python 服务器和浏览器客户端之间。

我们需要在 Quart Web 服务器代码中创建一个 WebSocket 端点来监听客户端连接。在main.py文件中,添加如下代码:

from quart import Quart, render_template, websocket

@app.websocket('/listen')
async def websocket_endpoint():
  await websocket.accept()
  try:
      while True:
          data = await websocket.receive()
  except Exception as e:
      raise Exception(f'Could not process audio: {e}')
  finally:
      await websocket.close(1000)

进入全屏模式 退出全屏模式

此代码接受服务器和客户端之间的 WebSocket 连接。只要连接保持打开状态,我们就会接收字节并等待我们从客户端收到消息。如果这不起作用,那么我们将抛出异常。一旦服务器和客户端完成相互发送消息,我们将关闭连接。

index.html中的代码监听客户端连接。如果有,它会像这样连接到客户端:

<script>
 ...
 const socket = new WebSocket('ws://localhost:3000/listen')
</script>

进入全屏模式 退出全屏模式

服务器与 Deepgram 之间的 Websocket 连接

我们需要在我们的中央 Quart 服务器和 Deepgram 之间建立连接,以获取音频并进行实时语音转录。将此代码添加到我们的main.py文件中。

@app.websocket('/listen')
async def websocket_endpoint():

   try:
       deepgram_socket = await process_audio(websocket)

       while True:
           data = await websocket.receive()
           deepgram_socket.send(data)
   except Exception as e:
       raise Exception(f'Could not process audio: {e}')
   finally:
       websocket.close(1000)

进入全屏模式 退出全屏模式

我们正在定义一个名为deepgram_socket的变量,它调用一个函数process_audio并打开与 Deepgram 的连接。在这个用户定义的方法中,我们还将连接到 Deepgram。当服务器和浏览器连接保持打开状态时,我们将等待消息并发送数据。

接下来,让我们创建我们的函数来处理音频,获取实时音频转录并连接到 Deepgram。在我们的main.py中,添加此代码。

from typing import Dict, Callable

async def process_audio(fast_socket):
   async def get_transcript(data: Dict) -> None:
       if 'channel' in data:
           transcript = data['channel']['alternatives'][0]['transcript']

           if transcript:
               await fast_socket.send(transcript)

   deepgram_socket = await connect_to_deepgram(get_transcript)

   return deepgram_socket

async def connect_to_deepgram(transcript_received_handler: Callable[[Dict], None]) -> str:
   try:
       socket = await dg_client.transcription.live({'punctuate': True, 'interim_results': False})
       socket.registerHandler(socket.event.CLOSE, lambda c: print(f'Connection closed with code {c}.'))
       socket.registerHandler(socket.event.TRANSCRIPT_RECEIVED, transcript_received_handler)

       return socket
   except Exception as e:
       raise Exception(f'Could not open socket: {e}')

进入全屏模式 退出全屏模式

process_audio函数将fast_socket作为参数,这将保持客户端和 Quart 服务器之间的连接打开。我们还连接到 Deepgram 并传入get_transcript函数。此函数获取脚本并将其发送回客户端。

connect_to_deepgram函数创建到 deepgram 的套接字连接,监听连接以关闭,并获取传入的转录对象。

最后,在我们的index.html中,我们需要通过以下事件接收和获取数据。请注意,他们正在登录到我们的控制台。如果您想了解更多关于这些事件的作用,请查看这篇博文。

<script>
    socket.onopen = () => {
        document.querySelector('#status').textContent = 'Connected'
        mediaRecorder.addEventListener('dataavailable', async (event) => {
            if (event.data.size > 0 && socket.readyState == 1) {
                socket.send(event.data)
            }
        })
        mediaRecorder.start(250)
    }

    socket.onmessage = (message) => {
        const received = message.data
        if (received) {
            document.querySelector('#transcript').textContent += ' ' + message.data
        }

    }

    socket.onclose = () => {
        console.log({
            event: 'onclose'
        })
    }

    socket.onerror = (error) => {
        console.log({
            event: 'onerror',
            error
        })
    }
</script>

进入全屏模式 退出全屏模式

让我们启动我们的应用程序并开始获取实时音频转录。从我们的终端,运行python main.py并在端口 3000 上拉起我们的 localhost,http://127.0.0.1:3000/。如果我们还没有,请允许访问我们的麦克风。开始说话,我们应该会看到如下所示的成绩单:

[Quart 直播示例中的最终结果](https://res.cloudinary.com/practicaldev/image/fetch/s--rz2UDf4i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https:// /dev-to-uploads.s3.amazonaws.com/uploads/articles/b2e3h0z0w6dj1upwwaid.png)

恭喜您使用 Quart 和 Deepgram 构建实时语音到文本转录项目。您可以在此处找到代码以及如何运行项目的说明。如果您有任何问题,请随时通过 Twitter 与我们联系:@DeepgramDevs。

Logo

学AI,认准AI Studio!GPU算力,限时免费领,邀请好友解锁更多惊喜福利 >>>

更多推荐