theme: devui-blue
如何在本地搭建一个中文语音服务
为什么不在服务器搭建?为什么?因为我穷,买不起性能好的服务器,8G的内存都不够用跑不起来的感觉,16G太贵了
安装Python环境
- 首先配置好Python3.10配置教程的开发环境,随后在终端运行命令
- 下载地址Python3.10版本
安装依赖包
依次运行下面的命令安装对应的包
pip3 intall funasr
pip3 install modelscope
pip3 install torch torchaudio
funasr 阿里开源的一个大模型
modelscope魔搭社区 一个由阿里达摩院开发的模型服务平台
torch
和 torchaudio
是两个不同的Python库,它们通常一起使用以支持音频处理任务。
编写python代码
首先先创建voice.py文件, 然后指定模型目录,否则funasr会在C盘下载模型,导致C盘会很大,运行的时候这些模型首次会自己下载,会比较慢。
from modelscope.pipelines import pipeline
from modelscope.utils.constant import Tasks
from modelscope.hub.snapshot_download import snapshot_download
# 指定本地目录
local_dir_root = "./models_from_modelscope"
# 使用modelscope的模型库,里面有很多模型,可以自己试着换一下,这里使用的是长文本离线带字符串的模型
model_dir = snapshot_download('damo/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-pytorch', cache_dir=local_dir_root)
inference_pipeline = pipeline(
task=Tasks.auto_speech_recognition,
model=model_dir,
vad_model='damo/speech_fsmn_vad_zh-cn-16k-common-pytorch',
punc_model='damo/punc_ct-transformer_zh-cn-common-vocab272727-pytorch',
#lm_model='damo/speech_transformer_lm_zh-cn-common-vocab8404-pytorch',
#lm_weight=0.15,
#beam_size=10,
)
param_dict = {}
param_dict['use_timestamp'] = False
def transcribe_one(audio_path):
rec_result = inference_pipeline(input=audio_path, param_dict=param_dict)
return rec_result
audio_path = "example_zh.wav" # 本地wav音频文件
transcribed_text = transcribe_one(audio_path)
print(transcribed_text) # 打印转录后的文本
命令行运行python脚本
python voice.py
如果遇到报错,大多数是包版本不兼容
当时我运行的时候也报错包版本不兼容,我使用的是
torchaudio 2.2.2
torch 2.2.2
然后不出意外的话控制台就会输出example_zh.wav
音频中的文字
搭建一个web服务器端调用返回文字识别结果
- 新建一个
serve.py
文件 - 安装以下包
pip install flask
pip install flask_cors
- 使用
flask
在serve.py
搭建一个web服务器
from flask import Flask, request, jsonify
import os
from flask_cors import CORS
# 引入voice.py的语音识别函数
from voice import transcribe_one
app = Flask(__name__)
# 允许跨域
cors = CORS(app, resources={r'/*': {'origins': '*'}})
@app.route('/transcribe', methods=['POST'])
def transcribe_audio():
return jsonify({'transcription': '请求进来了'})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)
- 运行
serve.py
,访问http://localhost:5000/transcribe 能看到内容即可 - 首先下载ffmpeg,解压到某个盘,在把解压的路径添加到系统环境变量path下如(
E:\ffmpeg\bin
),cmd运行ffmpeg
看是否成功 - 新建一个文件夹
tmp
用来存放临时WebM文件 - 用
ffmpeg
把前端传来的格式转为wav
格式
from flask import Flask, request, jsonify
import os
from flask_cors import CORS
import ffmpeg
# 引入您的语音识别函数和相关库
from voice import transcribe_one
app = Flask(__name__)
cors = CORS(app, resources={r'/*': {'origins': '*'}})
@app.route('/transcribe', methods=['POST'])
def transcribe_audio():
# 获取前端上传的音频文件,前端传过来的名字叫recording
audio_file = request.files.get('recording')
# 检查文件是否上传成功
if not audio_file:
return jsonify({'error': 'No audio file uploaded.'}), 400
# 保存临时WebM文件
temp_webm_path = os.path.join('tmp', audio_file.filename) # 临时WebM文件路径
audio_file.save(temp_webm_path)
# 使用ffmpeg库进行WebM转WAV
try:
(
ffmpeg
.input(temp_webm_path)
.output(os.path.splitext(temp_webm_path)[0] + '.wav', acodec='pcm_s16le', ar='16000', ac='1')
.overwrite_output()
.run()
)
except ffmpeg.Error as e:
return jsonify({'error': str(e)}), 500
# 使用转换后的WAV文件进行语音识别
try:
transcribed_text = transcribe_one(os.path.splitext(temp_webm_path)[0] + '.wav')
except Exception as e:
return jsonify({'error': str(e)}), 500
# 删除临时文件(可选,根据需要决定是否保留)
# os.remove(temp_webm_path)
# os.remove(os.path.splitext(temp_webm_path)[0] + '.wav')
# 返回转录结果
print(transcribed_text)
return jsonify({'transcription': transcribed_text})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)
- 启动
python server.py
python server.py
前端实现
- 新建一个
index.html
文件,并添加以下内容,请求刚刚启动的服务
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
#btn {
width: 100px;
height: 50px;
background-color: #4caf50;
color: white;
border: none;
cursor: pointer;
}
</style>
</head>
<body>
<div>
<button id="btn">按住录音</button>
<div id="result"></div>
</div>
</body>
<script>
const btn = document.getElementById("btn");
btn.addEventListener("touchstart", startRecording);
btn.addEventListener("touchend", stopRecording);
let isRecording = false;
let mediaRecorder = null;
let chunks = [];
function startRecording() {
if (isRecording) return; // 防止重复启动
navigator.mediaDevices
.getUserMedia({ audio: true })
.then((stream) => {
mediaRecorder = new MediaRecorder(stream, { mimeType: "audio/webm" });
mediaRecorder.addEventListener("dataavailable", (event) => {
if (event.data.size > 0) {
chunks.push(event.data);
}
});
mediaRecorder.start();
isRecording = true;
})
.catch((error) => {
console.error("无法访问麦克风:", error);
});
}
function stopRecording() {
console.log(222);
if (!isRecording) return; // 防止在未录制状态下停止
isRecording = false;
mediaRecorder.stop();
mediaRecorder.addEventListener("stop", () => {
const blob = new Blob(chunks, { type: "audio/webm" });
sendRecordingToBackend(blob);
chunks = []; // 清空缓存的chunks
});
}
function sendRecordingToBackend(blob) {
const formData = new FormData();
formData.append("recording", blob, "recording.webm")
fetch("http://localhost:5000/transcribe", {
method: "POST",
body: formData,
}).then(response => response.json())
.then((data) => {
if(data?.transcription) {
document.getElementById("result").innerHTML = data?.transcription[0].text
}
})
}
</script>
</html>
-
访问这个
index.html
页面,按住按钮,然后开始语音说话,文字就可以返回正确的结果了。 -
如果在运行
python
脚本的时候cmd关掉进程也不关掉的方法是使用pythonw serve.py
这样就行了、还有就是把他变成一个window服务的方法。 -
以上就是语音转文字的实现方法了。
相关内容