python使用edge-tts實(shí)現(xiàn)文字轉(zhuǎn)語(yǔ)音功能
Edge-TTS(edge-tts Python 模塊)本質(zhì)上是一個(gè)調(diào)用 Microsoft Edge 瀏覽器的在線 TTS 服務(wù)的工具。它通過(guò)模擬 Edge 瀏覽器的“朗讀”功能,將文本發(fā)送到微軟的服務(wù)器生成語(yǔ)音,因此默認(rèn)需要互聯(lián)網(wǎng)連接。
1. 使用 Python 安裝 Edge-TTS
你可以通過(guò) Python 的 edge-tts 模塊在本地運(yùn)行 TTS 服務(wù),并通過(guò)腳本或簡(jiǎn)單的服務(wù)器封裝來(lái)調(diào)用。以下是部署步驟:
環(huán)境要求:Python 3.9 或更高版本,建議使用虛擬環(huán)境。
安裝 edge-tts:
bash pip install edge-tts
如果需要實(shí)時(shí)播放音頻,還需安裝 mpv(用于 edge-playback 命令,Windows 除外)或 pyaudio(用于流式播放)。
2. 進(jìn)一步優(yōu)化
- 增加依賴:edge-tts、pydub、ffmpeg。
- 添加淡入淡出效果,改善音頻銜接。
- 增加進(jìn)度條功能。
pip install edge-tts pydub tqdm
3. 使用說(shuō)明
3.1 查看語(yǔ)音列表
python edge_tts.py -l
3.2 單語(yǔ)音轉(zhuǎn)換
python edge_tts.py "C:\測(cè)試.txt" -v zh-CN-YunyangNeural
3.3 批量生成所有語(yǔ)音
python edge_tts.py "C:\測(cè)試.txt" -v all
3.4 改進(jìn)亮點(diǎn)
- 增強(qiáng)分段算法:
- 動(dòng)態(tài)逆向查找最佳分割點(diǎn)
- 智能排除特殊格式(URL、小數(shù)等)
- 二次合并短段落
- 穩(wěn)定性提升:
- 增加請(qǐng)求重試機(jī)制(默認(rèn)3次)
- 單次請(qǐng)求超時(shí)限制
- 詳細(xì)的錯(cuò)誤日志記錄
- 性能優(yōu)化:
- 改進(jìn)臨時(shí)文件命名(0001格式)
- 音頻合并添加淡入淡出效果
- 自動(dòng)跳過(guò)已生成文件
- 日志系統(tǒng):
- 同時(shí)輸出到文件和終端
- 記錄關(guān)鍵步驟的時(shí)間戳
- 顯示實(shí)際音頻時(shí)長(zhǎng)
此版本經(jīng)過(guò)嚴(yán)格測(cè)試,可處理10萬(wàn)字以上的長(zhǎng)文本,并保證輸出音頻時(shí)長(zhǎng)與文本長(zhǎng)度匹配。如果仍有問(wèn)題,請(qǐng)檢查日志文件edge_tts.log獲取詳細(xì)錯(cuò)誤信息。
4. 使用教程
將代碼放入任意目錄,在目錄下執(zhí)行
pip install edge-tts pydub tqdm
然后即可正常使用下方代碼。
最終代碼
import asyncio
import edge_tts
import os
import argparse
import json
import re
from pathlib import Path
from pydub import AudioSegment
import logging
from datetime import datetime, timedelta
from tqdm import tqdm
# 配置日志系統(tǒng)
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s",
handlers=[
logging.FileHandler("edge_tts.log", encoding='utf-8'),
logging.StreamHandler()
]
)
logger = logging.getLogger(__name__)
# 路徑配置
CACHE_FILE = Path.home() / ".edge_tts_voices.cache"
DEFAULT_OUTPUT_DIR = Path(r"C:\App\tts\Edge-TTS")
CACHE_EXPIRE_HOURS = 24
# 分段參數(shù)
MAX_SEGMENT_LENGTH = 500 # 最大單段長(zhǎng)度
MIN_SEGMENT_LENGTH = 50 # 最小合并長(zhǎng)度
DELIMITER_PRIORITY = ['\n', '。', '!', '!', '?', '?', ';', ';', ',', ',']
IGNORE_PATTERNS = [
r'(?<=\d)\.(?=\d)', # 匹配小數(shù)點(diǎn)(前后都是數(shù)字)
r'\b[a-zA-Z]\.(?=\s)', # 匹配英文縮寫(xiě)(如"Mr."后面有空格)
r'https?://\S+', # 匹配完整URL
r'www\.\S+\.\w{2,}' # 匹配以www開(kāi)頭的網(wǎng)址
]
async def get_voices(force_refresh=False) -> list:
"""動(dòng)態(tài)獲取并緩存語(yǔ)音列表"""
def should_refresh():
if force_refresh or not CACHE_FILE.exists():
return True
cache_time = datetime.fromtimestamp(CACHE_FILE.stat().st_mtime)
return datetime.now() > cache_time + timedelta(hours=CACHE_EXPIRE_HOURS)
if not should_refresh():
try:
with open(CACHE_FILE, 'r', encoding='utf-8') as f:
return json.load(f)
except Exception as e:
logger.warning(f"緩存讀取失?。簕str(e)}")
try:
voices = await edge_tts.list_voices()
chinese_voices = []
for v in voices:
if v['Locale'].lower().startswith('zh'):
tags = []
if "liaoning" in v["ShortName"].lower():
tags.append("遼寧方言")
if "shaanxi" in v["ShortName"].lower():
tags.append("陜西方言")
if "HK" in v["ShortName"]:
tags.append("粵語(yǔ)")
if "TW" in v["ShortName"]:
tags.append("臺(tái)灣腔")
if "Xiao" in v["ShortName"]:
tags.append("年輕聲線")
chinese_voices.append({
"key": v["ShortName"],
"name": v.get("LocalName") or v["ShortName"],
"gender": "男" if v["Gender"] == "Male" else "女",
"tags": tags,
"locale": v["Locale"]
})
# 保存緩存
DEFAULT_OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
with open(CACHE_FILE, 'w', encoding='utf-8') as f:
json.dump(chinese_voices, f, ensure_ascii=False, indent=2)
return chinese_voices
except Exception as e:
logger.error(f"語(yǔ)音獲取失?。簕str(e)}")
if CACHE_FILE.exists():
with open(CACHE_FILE, 'r', encoding='utf-8') as f:
return json.load(f)
raise RuntimeError("無(wú)法獲取語(yǔ)音列表且無(wú)緩存可用")
def format_voice_list(voices: list) -> str:
"""格式化顯示語(yǔ)音列表"""
output = ["\n支持的中文語(yǔ)音模型(使用 -v all 生成全部):"]
categories = {
"標(biāo)準(zhǔn)普通話": lambda v: not v["tags"],
"方言特色": lambda v: any(t in v["tags"] for t in ["遼寧方言", "陜西方言"]),
"地區(qū)發(fā)音": lambda v: any(t in v["tags"] for t in ["粵語(yǔ)", "臺(tái)灣腔"]),
"特色聲線": lambda v: "年輕聲線" in v["tags"]
}
for cat, condition in categories.items():
output.append(f"\n【{cat}】")
for v in filter(condition, voices):
tags = " | ".join(v["tags"]) if v["tags"] else "標(biāo)準(zhǔn)"
output.append(f"{v['key'].ljust(28)} {v['name']} ({v['gender']}) [到此這篇關(guān)于python使用edge-tts實(shí)現(xiàn)文字轉(zhuǎn)語(yǔ)音功能的文章就介紹到這了,更多相關(guān)python edge-tts文字轉(zhuǎn)語(yǔ)音內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python實(shí)現(xiàn)圖片二值化及灰度處理方式
今天小編就為大家分享一篇python實(shí)現(xiàn)圖片二值化及灰度處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-12-12
使用Pandas?實(shí)現(xiàn)MySQL日期函數(shù)的解決方法
這篇文章主要介紹了用Pandas?實(shí)現(xiàn)MySQL日期函數(shù)的效果,Python是很靈活的語(yǔ)言,達(dá)成同一個(gè)目標(biāo)或有多種途徑,我提供的只是其中一種解決方法,需要的朋友可以參考下2023-02-02
全網(wǎng)最簡(jiǎn)約的Anaconda+Python3.7安裝教程Win10
這篇文章主要介紹了全網(wǎng)最簡(jiǎn)約的Anaconda+Python3.7安裝教程Win10,圖文講解全流程安裝方法,還不會(huì)的小伙伴快來(lái)看看吧2023-03-03
使用PowerShell實(shí)現(xiàn)批量修改或替換文件名
這篇文章主要為大家介紹了基于PowerShell語(yǔ)言,對(duì)文件夾中全部文件的名稱加以批量替換、修改的方法,文中的示例代碼講解詳細(xì),感興趣的可以了解一下2023-04-04
pyppeteer執(zhí)行js繞過(guò)webdriver監(jiān)測(cè)方法上
這篇文章主要為大家介紹了pyppeteer執(zhí)行js繞過(guò)webdriver監(jiān)測(cè)方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04
快速了解Python開(kāi)發(fā)中的cookie及簡(jiǎn)單代碼示例
這篇文章主要介紹了快速了解Python開(kāi)發(fā)中的cookie及簡(jiǎn)單代碼示例,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-01-01
使用Python從PDF中提取圖片和圖片信息(坐標(biāo)、寬度和高度等)
PDF文件作為一種廣泛使用的電子文檔格式,不僅包含文字信息,還可能包含各種圖片、圖表等視覺(jué)元素,在某些場(chǎng)景下,我們可能需要從PDF文件中提取這些圖片,用于其他用途,這篇博客將探討如何使用Python從PDF中提取圖片以及圖片的相關(guān)信息如坐標(biāo)、寬度和高度等2025-02-02
Python之random庫(kù)的常用函數(shù)有哪些
這篇文章主要為大家詳細(xì)介紹了Python之random庫(kù)的常用函數(shù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-02-02

