[Asm] 纯文本查看 复制代码
# -*- coding: utf-8 -*-
import asyncio
import os
from edge_tts import Communicate
import time
# 调用合并视频和音频的函数 这个函数自用的 非官方 用于合成音视频 该脚本并不需要此函数 因此注释掉
# import mergeVideoAndVoice
from tqdm import tqdm # 引入 tqdm 库用于显示进度条
#检测输入值
def get_non_empty_input(prompt):
"""
获取用户输入的非空字符串,若输入为空则提示用户重新输入。
"""
while True:
value = input(prompt).strip()
if value:
return value
else:
print("输入不能为空,请重新输入。")
#文字转语音方法
async def text_to_speech(text, title, voice, voice_dir):
try:
beginTime = time.time()
communicate = Communicate(text, voice)
endTime = time.time()
temp_audio_file = os.path.join(voice_dir, f"{title}.mp3.temp")
# 计算耗时
elapsedTime = endTime - beginTime
# 打印耗时
print(f"耗时: {elapsedTime} 秒")
#进度条开始前记录下时间
beginProceTime = time.time()
formatted_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(beginProceTime))
print(f"进度条开始: {formatted_time}")
# 使用 tqdm 创建进度条
with tqdm(total=100, desc="音频生成进度") as pbar:
# 运行并等待语音合成完成并保存到临时文件
await communicate.save(temp_audio_file)
# 模拟进度更新
for i in range(100):
await asyncio.sleep(0.1) # 模拟耗时操作
pbar.update(1)
# print(f"当前进度:{i}")
if i == 99:
endProceTime = time.time()
formatted_time_end = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(endProceTime))
print(f"进度条结束: {formatted_time_end} 秒")
proceTime = endProceTime - beginProceTime
print(f"总耗时: {proceTime} 秒")
final_audio_file = os.path.join(voice_dir, f"{title}.mp3")
os.rename(temp_audio_file, final_audio_file)
return final_audio_file
except Exception as e:
# 处理异常
print(f"生成音频文件时发生错误: {e}")
return None
async def main(videoRealPath, videoRealName, text):
isNeedInput = get_non_empty_input("请确认音频保存路径是否需要输入 Y:需要 N:不需要 (不需要输入请确认脚本路径配置正确): ")
print("视频完整路径:" + videoRealPath + " 视频名称:" + videoRealName + " 文案:" + text)
title = videoRealName
voice_options = {
'1': 'zh-CN-XiaoxiaoNeural', # 晓晓,女性
'2': 'zh-CN-YunxiNeural', # 云希,男性
'3': 'zh-CN-YunyangNeural', # 云扬,男性
'4': 'zh-CN-YunjianNeural', # 云健,男性
'5': 'zh-CN-XiaoyiNeural', # 晓忆,女性
'6': 'zh-CN-XiaohanNeural', # 晓涵,女性
'7': 'zh-CN-XiaomengNeural', # 晓萌,女性
'8': 'zh-CN-XiaomoNeural', # 晓墨,女性
'9': 'zh-CN-XiaoqiuNeural', # 晓秋,女性
'10': 'zh-CN-XiaoruiNeural', # 晓睿,女性
'11': 'zh-CN-XiaoshuangNeural', # 晓霜,女性
'12': 'zh-CN-XiaoyanNeural', # 晓颜,女性
'13': 'zh-CN-XiaoyouNeural', # 晓悠,女性
'14': 'zh-CN-XiaoyuMultilingualNeural', # 晓宇,多语言
'15': 'zh-CN-XiaozhenNeural', # 晓真,女性
'16': 'zh-CN-YunfengNeural', # 云风,男性
'17': 'zh-CN-YunhaoNeural', # 云浩,男性
'18': 'zh-CN-YunjieNeural', # 云杰,男性
'19': 'zh-CN-YunxiaNeural', # 云霞,男性
'20': 'zh-CN-YunyeNeural', # 云野,男性
'21': 'zh-CN-YunyiMultilingualNeural', # 云一,多语言
'22': 'zh-CN-YunzeNeural', # 云泽,男性
'23': 'zh-CN-YunfanMultilingualNeural', # 云凡,多语言
'24': 'zh-CN-YunxiaoMultilingualNeural', # 云晓,多语言
'25': 'zh-CN-XiaochenMultilingualNeural', # 晓晨,多语言
'26': 'zh-CN-XiaoxiaoDialectsNeural', # 晓晓,方言
'27': 'zh-CN-XiaoxiaoMultilingualNeural', # 晓晓,多语言
'28': 'zh-CN-XiaoyuMultilingualNeural', # 晓宇,多语言
'29': 'zh-CN-XiaobeiNeural', # 晓北,女性
'30': 'zh-CN-guangxi-YunqiNeural1.3', # 广西,云奇,男性
'31': 'zh-CN-henan-YundengNeural3', # 河南,云登,男性
'32': 'zh-CN-liaoning-XiaobeiNeural1.3', # 辽宁,晓北,女性
'33': 'zh-CN-liaoning-YunbiaoNeural1.3', # 辽宁,云彪,男性
'34': 'zh-CN-shaanxi-XiaoniNeural1.3', # 陕西,晓妮,女性
'35': 'zh-CN-shandong-YunxiangNeural3', # 山东,云翔,男性
'36': 'zh-CN-sichuan-YunxiNeural1.3', # 四川,云希,男性
'37': 'zh-HK-HiuMaanNeural', # 香港,晓曼,女性
'38': 'zh-HK-WanLungNeural', # 香港,云龙,男性
'39': 'zh-HK-HiuGaaiNeural', # 香港,晓佳,女性
'40': 'zh-TW-HsiaoChenNeural', # 台湾,晓晨,女性
'41': 'zh-TW-YunJheNeural', # 台湾,云哲,男性
'42': 'zh-TW-HsiaoYuNeural' # 台湾,晓宇,女性
}
for key, value in voice_options.items():
print(f"{key}: {value}")
voice_choice = get_non_empty_input("请输入语音音色的编号: ")
voice = voice_options.get(voice_choice, 'zh-CN-YunxiNeural') # 使用默认音色或用户选择的音色
if isNeedInput in ("Y", "y"):
voice_dir = get_non_empty_input("请输入音频保存路径:")
else:
voice_dir = "/Users/ljj/Documents/mayun/video/voice"
if not os.path.exists(voice_dir):
print("音频保存路径不存在,创建并使用")
os.makedirs(voice_dir)
# 使用 edge-tts 生成音频文件
audio_file = await text_to_speech(text, title,voice,voice_dir)
if audio_file is None:
print("音频文件生成失败,等待 10 秒后重试")
await asyncio.sleep(10)
for retry_count in range(3): # 重试 3 次
audio_file = await text_to_speech(text, title, voice, voice_dir)
if audio_file:
break
print(f"重试 {retry_count + 1} 次失败,等待 5 秒后继续")
await asyncio.sleep(5)
# 如果音频文件生成成功并且大小符合要求
if audio_file and os.path.getsize(audio_file) > 1024: # 例如,检查文件大小是否大于 1KB
mergeVideoAndVoice.main(videoRealPath, audio_file, videoRealName)
else:
print("音频文件过小或生成失败,等待后重试")
await asyncio.sleep(5) # 等待一段时间后重试
if audio_file and os.path.getsize(audio_file) > 1024:
mergeVideoAndVoice.main(videoRealPath, audio_file, videoRealName)
if __name__ == "__main__":
isNeedInput = get_non_empty_input("请确认是否需要输入 Y:需要 N:不需要 (不需要输入请确认脚本路径配置正确): ")
isAuto = get_non_empty_input("是否全模型自动生成 Y:需要 N:不需要: ")
if isNeedInput in("Y","y"):
title = get_non_empty_input("请输入音频标题:")
text = get_non_empty_input("请输入文案,若文案过长无法再控制台输入请直接将文案在代码中赋值:")
voice_dir = get_non_empty_input("请输入音频保存完整路径:")
elif isNeedInput in("N","n"):
title="测试"
text='测试语音效果' # 这里是文字转语音的文案,代码中不限制长度 ,但注意控制台赋值粘贴本身有长度限制,如果文案较长,请直接在代码中处理
voice_dir='/Users/ljj/Documents/mayun/video/voice' # 这里是文字转语音的文案,不限制长度
else:
print("输入错误")
exit()
# 6~18 20~28 30 31 33 35 36 模型似乎是收费模型 无法使用
voice_options = {
'1': 'zh-CN-XiaoxiaoNeural', # 晓晓,女性
'2': 'zh-CN-YunxiNeural', # 云希,男性
'3': 'zh-CN-YunyangNeural', # 云扬,男性
'4': 'zh-CN-YunjianNeural', # 云健,男性
'5': 'zh-CN-XiaoyiNeural', # 晓忆,女性
'6': 'zh-CN-XiaohanNeural', # 晓涵,女性
'7': 'zh-CN-XiaomengNeural', # 晓萌,女性
'8': 'zh-CN-XiaomoNeural', # 晓墨,女性
'9': 'zh-CN-XiaoqiuNeural', # 晓秋,女性
'10': 'zh-CN-XiaoruiNeural', # 晓睿,女性
'11': 'zh-CN-XiaoshuangNeural', # 晓霜,女性
'12': 'zh-CN-XiaoyanNeural', # 晓颜,女性
'13': 'zh-CN-XiaoyouNeural', # 晓悠,女性
'14': 'zh-CN-XiaoyuMultilingualNeural', # 晓宇,多语言
'15': 'zh-CN-XiaozhenNeural', # 晓真,女性
'16': 'zh-CN-YunfengNeural', # 云风,男性
'17': 'zh-CN-YunhaoNeural', # 云浩,男性
'18': 'zh-CN-YunjieNeural', # 云杰,男性
'19': 'zh-CN-YunxiaNeural', # 云霞,男性
'20': 'zh-CN-YunyeNeural', # 云野,男性
'21': 'zh-CN-YunyiMultilingualNeural', # 云一,多语言
'22': 'zh-CN-YunzeNeural', # 云泽,男性
'23': 'zh-CN-YunfanMultilingualNeural', # 云凡,多语言
'24': 'zh-CN-YunxiaoMultilingualNeural', # 云晓,多语言
'25': 'zh-CN-XiaochenMultilingualNeural', # 晓晨,多语言
'26': 'zh-CN-XiaoxiaoDialectsNeural', # 晓晓,方言
'27': 'zh-CN-XiaoxiaoMultilingualNeural', # 晓晓,多语言
'28': 'zh-CN-XiaoyuMultilingualNeural', # 晓宇,多语言
'29': 'zh-CN-XiaobeiNeural', # 晓北,女性
'30': 'zh-CN-guangxi-YunqiNeural', # 广西,云奇,男性
'31': 'zh-CN-henan-YundengNeural', # 河南,云登,男性
'32': 'zh-CN-liaoning-XiaobeiNeural', # 辽宁,晓北,女性
'33': 'zh-CN-liaoning-YunbiaoNeural', # 辽宁,云彪,男性
'34': 'zh-CN-shaanxi-XiaoniNeural', # 陕西,晓妮,女性
'35': 'zh-CN-shandong-YunxiangNeural', # 山东,云翔,男性
'36': 'zh-CN-sichuan-YunxiNeural', # 四川,云希,男性
'37': 'zh-HK-HiuMaanNeural', # 香港,晓曼,女性
'38': 'zh-HK-WanLungNeural', # 香港,云龙,男性
'39': 'zh-HK-HiuGaaiNeural', # 香港,晓佳,女性
'40': 'zh-TW-HsiaoChenNeural', # 台湾,晓晨,女性
'41': 'zh-TW-YunJheNeural', # 台湾,云哲,男性
'42': 'zh-TW-HsiaoYuNeural' # 台湾,晓宇,女性
}
#这里是循环自动生成 - 看那个语音好听 x>=6 x<=18 x>=20 x<=28 不可用 估计是语音平台收费的 其余应该是属于开源可用的,没那时间去接入了 剩下这么多 够用了
if isAuto in("Y","y"):
for key, value in voice_options.items():
lastTitle = title+"_"+key
voice = value
print("")
print(f"第{key}: {value}模型正在初始化处理功能,请稍等...")
asyncio.run(text_to_speech(text,lastTitle,voice, voice_dir))
else:
# 这里是手动选择生成
for key, value in voice_options.items():
print(f"{key}: {value}")
voice_choice = get_non_empty_input("请输入语音音色的编号: ")
title = title+"_"+voice_choice
voice = voice_options.get(voice_choice, 'zh-CN-YunxiNeural') # 使用默认音色或用户选择的音色
print("正在初始化处理功能,请稍等...")
asyncio.run(text_to_speech(text, title,voice, voice_dir))