超簡單部署離線語音合成TTS和語音識別

一篇文章講清楚超簡單 離線語音合成TTS 和 離線語音識別 系統部署
本文只介紹兩個輕量級的
語音合成用piper, 語音識別用vosk
部署簡單,效果勉強

語音合成

推薦 piper (其他沒用過)

安裝

linux下安裝

pip install piper-tts

下載模型(63M)

中文模型下載 zh_CN-huayan-medium.onnx 和 zh_CN-huayan-medium.onnx.json兩個文件, 放在同一個目錄
聲音好聽, 但是空格,符號等識別不了, 沒有停頓, 沒有更好的中文模型是個遺憾
如果只是windows系統用微軟的TTS效果比這個好
模型下載地址

https://hf-mirror.com/rhasspy/piper-voices
https://hf-mirror.com/rhasspy/piper-voices/tree/main/zh/zh_CN/huayan/medium

使用

在當前目錄下會輸出66.wav這個音頻文件

echo '今年前5個月,我國貨物貿易進出口總值17.94萬億元' | piper --model ./zh_CN-huayan-medium.onnx --output_file 66.wav

對接

下面代碼未驗證過

import subprocess
import os
import asyncio
from fastapi import FastAPI, HTTPException, Query
from fastapi.responses import FileResponse
from pydantic import BaseModel
import uuidapp = FastAPI()# 設置模型路徑和輸出目錄(使用絕對路徑)
# MODEL_PATH = './model/zh_CN-huayan-x_low.onnx'
MODEL_PATH = './model/zh_CN-huayan-medium.onnx'
OUTPUT_DIR = os.path.abspath('./output/')  # 使用絕對路徑# 確保輸出目錄存在
if not os.path.exists(OUTPUT_DIR):os.makedirs(OUTPUT_DIR)class SynthesizeRequest(BaseModel):text: strmode: str = Query('sync', enum=['sync', 'async'])  # 支持 'sync' 或 'async'# 同步版本的 TTS 生成
def synthesize_text_sync(text: str, output_file: str):try:# 調用 piper 命令生成音頻command = f"echo '{text}' | piper --model {MODEL_PATH} --output_file {output_file}"print(command)result = subprocess.run(#['echo', text, '|', 'piper', '--model', MODEL_PATH, '--output_file', output_file],command,check=True, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)# 打印 piper 命令的輸出(標準輸出和標準錯誤)print(f"piper stdout: {result.stdout.decode()}")print(f"piper stderr: {result.stderr.decode()}")if not os.path.exists(output_file):raise FileNotFoundError(f"音頻文件未生成: {output_file}")except subprocess.CalledProcessError as e:raise HTTPException(status_code=500, detail=f"Failed to generate speech: {str(e)}")# 異步版本的 TTS 生成
async def synthesize_text_async(text: str, output_file: str):try:# 使用異步方式調用 piper 命令生成音頻process = await asyncio.create_subprocess_exec('echo', text, '|', 'piper', '--model', MODEL_PATH, '--output_file', output_file,stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)stdout, stderr = await process.communicate()# 打印 piper 命令的輸出(標準輸出和標準錯誤)print(f"piper stdout: {stdout.decode()}")print(f"piper stderr: {stderr.decode()}")if process.returncode != 0 or not os.path.exists(output_file):raise FileNotFoundError(f"音頻文件未生成: {output_file}")except Exception as e:raise HTTPException(status_code=500, detail=f"Failed to generate speech: {str(e)}")@app.post("/synthesize/")
async def synthesize(request: SynthesizeRequest):text = request.textif not text:raise HTTPException(status_code=400, detail="Text is required")# 生成音頻文件路徑(絕對路徑)# output_file = os.path.join(OUTPUT_DIR, 'welcome.wav')# 生成唯一的文件名,避免并發沖突unique_id = str(uuid.uuid4())  # 使用 UUID 生成唯一標識符output_file = os.path.join(OUTPUT_DIR, f"{unique_id}.wav")  # 生成唯一的文件名# 根據請求的模式選擇同步或異步if request.mode == 'sync':synthesize_text_sync(text, output_file)elif request.mode == 'async':await synthesize_text_async(text, output_file)else:raise HTTPException(status_code=400, detail="Invalid mode, must be 'sync' or 'async'")# 確保文件存在后再返回if not os.path.exists(output_file):raise HTTPException(status_code=500, detail=f"音頻文件生成失敗: {output_file}")# 返回音頻文件return FileResponse(output_file, media_type='audio/wav')

語音識別

用vosk
1,nuget安裝vosk
2,去官網下載一個中文模型(只有42M) : https://alphacephei.com/vosk/models
42M的模型效果很一般,好在使用簡單
還有個1.3G的模型,沒有測試,應該不錯

using Vosk;/// <summary>
/// 語音轉文字
/// 需要去官網下載模型: https://alphacephei.com/vosk/models
/// 解壓模型后放在項目目錄下面
/// </summary>
public class VoskDemo
{public static void DemoBytes(Model model){// Demo byte buffer 基本語音識別VoskRecognizer rec = new VoskRecognizer(model, 16000.0f);rec.SetMaxAlternatives(0);rec.SetWords(true);using(Stream source = File.OpenRead("test.wav")) {byte[] buffer = new byte[4096];int bytesRead;while((bytesRead = source.Read(buffer, 0, buffer.Length)) > 0) {if (rec.AcceptWaveform(buffer, bytesRead)) {Console.WriteLine(rec.Result());} else {Console.WriteLine(rec.PartialResult());}}}Console.WriteLine(rec.FinalResult());}public static void DemoFloats(Model model){// Demo float array  流媒體VoskRecognizer rec = new VoskRecognizer(model, 16000.0f);using(Stream source = File.OpenRead("test.wav")) {byte[] buffer = new byte[4096];int bytesRead;while((bytesRead = source.Read(buffer, 0, buffer.Length)) > 0) {float[] fbuffer = new float[bytesRead / 2];for (int i = 0, n = 0; i < fbuffer.Length; i++, n+=2) {fbuffer[i] = BitConverter.ToInt16(buffer, n);}if (rec.AcceptWaveform(fbuffer, fbuffer.Length)) {Console.WriteLine(rec.Result());} else {Console.WriteLine(rec.PartialResult());}}}Console.WriteLine(rec.FinalResult());}public static void DemoSpeaker(Model model){// Output speakers 說話人識別SpkModel spkModel = new SpkModel("model-spk");VoskRecognizer rec = new VoskRecognizer(model, 16000.0f);rec.SetSpkModel(spkModel);using(Stream source = File.OpenRead("test.wav")) {byte[] buffer = new byte[4096];int bytesRead;while((bytesRead = source.Read(buffer, 0, buffer.Length)) > 0) {if (rec.AcceptWaveform(buffer, bytesRead)) {Console.WriteLine(rec.Result());} else {Console.WriteLine(rec.PartialResult());}}}Console.WriteLine(rec.FinalResult());}public static void Test(){// You can set to -1 to disable logging messagesVosk.Vosk.SetLogLevel(0);Model model = new Model("vosk-model-small-cn-0.22"); // 模型目錄//DemoBytes(model);//DemoFloats(model);DemoSpeaker(model);}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/84610.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/84610.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/84610.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【算力網】

一、算力網-DNS 1.1、核心架構設計 1.1.1 設計框架 基于SRv6的智能DNS算法設計框架&#xff0c;結合IPv6路由可編程性、動態路徑優化及業務感知能力&#xff0c;實現網絡性能與用戶體驗的雙重提升&#xff1a;? ?SRv6-DNS融合架構? ?控制平面?&#xff1a; DNS服務器集…

shell分析nginx日志的指令

shell指令 查看有多少個IP訪問&#xff1a; awk {print $1} log_file|sort|uniq|wc -l 查看某一個頁面被訪問的次數&#xff1a; grep "/index.php" log_file | wc -l 查看每一個IP訪問了多少個頁面&#xff1a; awk {S[$1]} END {for (a in S) print a,S[a]} …

CMS軟件以及常見分類

CMS&#xff08;Content Management System&#xff0c;內容管理系統&#xff09;是 讓非技術人員也能便捷創建、編輯、管理網站內容的軟件 &#xff0c;核心是 分離 “內容” 和 “頁面設計”&#xff08;內容存在數據庫&#xff0c;頁面用模板生成&#xff09;&#xff0c;無…

Spring @Value 典型用法

典型用法 注入常量值 Value("Hello World") private String message;注入配置文件中的屬性值&#xff08;如 application.properties&#xff09; // 假設你有如下配置&#xff1a; app.nameMyApp app.version1.0.0// Java 類中使用&#xff1a; Value("${ap…

golang -- map實現原理

目錄 一、前言二、結構1. hmap(map) 結構2. bmap(buckets) 結構 三、哈希沖突四、負載因子五、哈希函數六、擴容增量擴容等量擴容 一、前言 在現代編程語言中&#xff0c;map 是一種非常重要的數據結構&#xff0c;廣泛用于存儲和快速查找鍵值對。Go 語言中的 map 是一種高效且…

Vue2 Extends 繼承機制與組件復用實踐

extends在某些場景下依然發揮作用&#xff0c;如Options API。子組件將繼承父組件的屬性、方法、生命周期鉤子函數以及混合&#xff08;mixins&#xff09;等選項。 注意&#xff1a;子組件可以覆蓋、或繼承擴展父組件的選項。子組件的生命周期鉤子和父組件的鉤子一起執行。 &l…

openSUSE MicroOS不可變Linux

openSUSE MicroOS不可Linux 1、openSUSE MicroOS簡介安裝時可能遇到的問題 2、ssh登錄3、openSUSE MicroOS配置國內軟件源4、系統變更openSUSE MicroOS安裝軟件包方法1&#xff1a;進入事務性更新模式安裝軟件包方法2&#xff1a;繼續快照id基于這個快照進行增量安裝方法3&…

建站SEO優化之站點地圖sitemap

文章目錄 編寫規范小型網站站點地圖小型網站規范示例站點地圖說明 大型網站站點地圖大型網站規范示例以豆瓣站點地圖為例 近期文章&#xff1a; 個人建站做SEO網站外鏈這一點需要注意&#xff0c;做錯了可能受到Google懲罰一文搞懂SEO優化之站點robots.txt網頁常見水印實現方式…

Java分層開發必知:PO、BO、DTO、VO、POJO概念詳解

目錄 引言一、核心概念與定義1、PO&#xff08;Persistent Object&#xff0c;持久化對象&#xff09;2、BO&#xff08;Business Object&#xff0c;業務對象&#xff09;3、DTO&#xff08;Data Transfer Object&#xff0c;數據傳輸對象&#xff09;4、VO&#xff08;View O…

Linux下OLLAMA安裝卡住怎么辦?

網絡環境不理想&#xff0c;經常在官方的linux安裝腳本執行時卡住&#xff0c;其實主要是下載文件卡住&#xff0c;于是我想到了是否可以把其中下載的過程顯化、分步&#xff0c;這樣更可控&#xff0c;于是修改了官方的install.sh #!/bin/sh # This script installs Ollama o…

C++面試(5)-----刪除鏈表中指定值的節點

操作系統&#xff1a;ubuntu22.04 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 給定一個單向鏈表的頭節點 head 和一個特定值 val&#xff0c;要求編寫一個函數來刪除鏈表中所有值等于 val 的節點&#xff0c;并返回修改后的鏈表頭節點。 示例&#xff1a; 輸…

如何用AI賦能學習

由于博主是大學生&#xff0c;今天花費了大量的時間去進行期末的復習&#xff0c;不過從復習中得到了一些學習的靈感&#xff0c;即&#xff1a;如何用AI賦能學習 當我們需要掌握一門新的技能的時候&#xff0c;我們很容易的想到三種辦法&#xff1a;買書自己學&#xff0c;報…

【threejs】每天一個小案例講解:常見材質

代碼倉 GitHub - TiffanyHoo/three_practices: Learning three.js together! 可自行clone&#xff0c;無需安裝依賴&#xff0c;直接liver-server運行/直接打開chapter01中的html文件 運行效果圖 知識要點 1. MeshBasicMaterial&#xff08;基礎網格材質&#xff09; ? 特…

springboot后端與鴻蒙的結合

軟件&#xff1a;鴻蒙devceo3.1&#xff0c;springboot項目采用IDEA 目的&#xff1a; 1、結合springboot后端與鴻蒙的結合運用。 2、Log日志查看console語句的信息。 3、引入 import http from ohos.net.http。 4、調用springboot后端提供的鏈接發送post 5、TextInput的…

minio集群通過mc mirror命令進行定時備份,支持X86和arm兩種架構

文章目錄 前言一、思路二、使用步驟1.下載mc二進制文件2.手動測試備份命令3.配置定時任務4.成功截圖 總結 前言 通過mc mirror命令對minio集群進行定時備份。 一、思路 通過mc mirror命令配合crond定時任務進行周期性的備份 二、使用步驟 1.下載mc二進制文件 wget https:…

三大能力升級,為老項目重構開辟新路徑

在軟件技術飛速迭代的今天&#xff0c;老項目重構是開發者們繞不開的難題。接口實現缺失、業務邏輯矛盾、架構規劃偏離等問題如同攔路虎&#xff0c;讓重構工作舉步維艱。而傳統的 AI 輔助方式&#xff0c;因未充分關聯項目實際情況&#xff0c;猶如 “空中造樓”&#xff0c;難…

AES加密

AES加密算法詳解 AES&#xff08;Advanced Encryption Standard&#xff09;是一種對稱密鑰分組加密算法&#xff0c;用于保護電子數據的安全性。其核心特點是通過相同的密鑰進行加密和解密&#xff0c;屬于對稱加密體系。。以下從核心特性、加密流程及安全性三方面展開說明&a…

關于聯詠(Novatek )自動曝光中Lv值的計算方式實現猜想

目錄 一、常見Lv對應的實際場景 二、常見光圈值 三、最小二乘法計算SV中的系數K

[docker]鏡像操作:關于docker pull、save、load一些疑惑解答

在使用 Docker 的過程中&#xff0c;鏡像管理是極其重要的一環。無論是拉取、保存還是加載鏡像&#xff0c;每一個步驟都可能遇到一些疑問或者誤區。 本文將結合實際案例&#xff0c;對常見的 Docker 鏡像操作問題進行系統性總結&#xff0c;幫你更好地理解 Docker 鏡像的工作機…

SFTrack:面向警務無人機的自適應多目標跟蹤算法——突破小尺度高速運動目標的追蹤瓶頸

【導讀】 本文針對無人機&#xff08;UAV&#xff09;視頻中目標尺寸小、運動快導致的多目標跟蹤難題&#xff0c;提出一種更簡單高效的方法。核心創新在于從低置信度檢測啟動跟蹤&#xff08;貼合無人機場景特性&#xff09;&#xff0c;并改進傳統外觀匹配算法以關聯此類檢測…