基于python文案转语音并输出-自媒体等职业副业均可使用,不受他人限制

查看 81|回复 6
作者:zhengduimen   
开发背景:
目前自媒体比较火爆,有很多书单、视频等推广方式可以作为副业盈利,之前每次搞的时候都需要不停的网上找一些在线文字转语音的平台将文案复制上去然后生成下载,好多还是付费的,挺无奈的,然后就想着自己能不能搞,然后的然后就有了下面的东西
先看效果:


voice.jpg (128.74 KB, 下载次数: 0)
下载附件
2024-8-30 17:00 上传

代码:
[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=20  x

各类语音模型演示效果.zip
(146.04 KB, 下载次数: 5)
2024-8-30 17:01 上传
点击文件名下载附件
各类语音模型演示效果,可下载试听
下载积分: 吾爱币 -1 CB

代码内部需要的库请自行下载,注意当文案内容过长时,由于控制台输入限制会出现缺失,建议直接改代码,将文案复制进去然后执行生成。

女性, 男性

JackChen1688   

感觉还行下载下来看看
JackChen1688   

我想问下lz  这个 mergeVideoAndVoice 是什么
JackChen1688   

噢,代码没贴完啊,还说来看看效果呢
zhengduimen
OP
  


JackChen1688 发表于 2024-8-31 09:17
噢,代码没贴完啊,还说来看看效果呢

那个没用 干掉就行 你说的那个脚本是我用来合成视频的 跟文案转语音没关系。
zhengduimen
OP
  


JackChen1688 发表于 2024-8-31 09:15
我想问下lz  这个 mergeVideoAndVoice 是什么

看名字应该能理解它是干嘛的吧 mergevideoandvoice
ericwise   


JackChen1688 发表于 2024-8-31 09:15
我想问下lz  这个 mergeVideoAndVoice 是什么

合并视频及语音
您需要登录后才可以回帖 登录 | 立即注册

返回顶部