欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 美景 > 【无标题】

【无标题】

2025/8/18 12:58:00 来源:https://blog.csdn.net/sweet987250/article/details/139925138  浏览:    关键词:【无标题】

这里写自定义目录标题

  • 欢迎使用Markdown编辑器
    • 新的改变
    • 功能快捷键
    • 合理的创建标题,有助于目录的生成
    • 如何改变文本的样式
    • 插入链接与图片
    • 如何插入一段漂亮的代码片
    • 生成一个适合你的列表
    • 创建一个表格
      • 设定内容居中、居左、居右
      • SmartyPants
    • 创建一个自定义列表
    • 如何创建一个注脚
    • 注释也是必不可少的
    • KaTeX数学公式
    • 新的甘特图功能,丰富你的文章
    • UML 图表
    • FLowchart流程图
    • 导出与导入
      • 导出
      • 导入

import os
import re
import sys
import io
import json
import wave
from pathlib import Path
print('Starting...')
import torch
import torch._dynamo
torch._dynamo.config.suppress_errors = True
torch._dynamo.config.cache_size_limit = 64
torch._dynamo.config.suppress_errors = True
torch.set_float32_matmul_precision('high')
os.environ['KMP_DUPLICATE_LIB_OK'] = 'True'import soundfile as sf
import ChatTTS
import datetime
from dotenv import load_dotenv
from flask import Flask, request, render_template, jsonify,  send_from_directory,send_file,Response, stream_with_context
import logging
from logging.handlers import RotatingFileHandler
from waitress import serve
load_dotenv()from random import random
from modelscope import snapshot_download
import numpy as np
import time
import threading
from uilib.cfg import WEB_ADDRESS, SPEAKER_DIR, LOGS_DIR, WAVS_DIR, MODEL_DIR, ROOT_DIR
from uilib import utils,VERSION
from ChatTTS.utils.gpu_utils import select_devicefrom uilib.utils import is_chinese_os,modelscope_status
env_lang=os.getenv('lang','')
if env_lang=='zh':is_cn= True
elif env_lang=='en':is_cn=False
else:is_cn=is_chinese_os()CHATTTS_DIR= MODEL_DIR+'/pzc163/chatTTS'
# 默认从 modelscope 下载模型
# 如果已存在则不再下载和检测更新,便于离线内网使用
if not os.path.exists(CHATTTS_DIR+"/config/path.yaml") and not os.path.exists(MODEL_DIR+'/models--2Noise--ChatTTS'):# 可连接modelscopeif modelscope_status():print('modelscope ok')snapshot_download('pzc163/chatTTS',cache_dir=MODEL_DIR)else:print('from huggingface')CHATTTS_DIR=MODEL_DIR+'/models--2Noise--ChatTTS'import huggingface_hubos.environ['HF_HUB_CACHE']=MODEL_DIRos.environ['HF_ASSETS_CACHE']=MODEL_DIRhuggingface_hub.snapshot_download(cache_dir=MODEL_DIR,repo_id="2Noise/ChatTTS", allow_patterns=["*.pt", "*.yaml"])#print(f'{is_cn=}')  
#exit()       
chat = ChatTTS.Chat()
device=os.getenv('device','default')
chat.load_models(source="custom",custom_path=CHATTTS_DIR, device=None if device=='default' else device,compile=True if os.getenv('compile','true').lower()!='false' else False)# 如果希望从 huggingface.co下载模型,将以下注释删掉。将上方3行内容注释掉
# 如果已存在则不再下载和检测更新,便于离线内网使用
#CHATTTS_DIR=MODEL_DIR+'/models--2Noise--ChatTTS'
#if not os.path.exists(CHATTTS_DIR):#import huggingface_hub#os.environ['HF_HUB_CACHE']=MODEL_DIR#os.environ['HF_ASSETS_CACHE']=MODEL_DIR#huggingface_hub.snapshot_download(cache_dir=MODEL_DIR,repo_id="2Noise/ChatTTS", allow_patterns=["*.pt", "*.yaml"])# chat = ChatTTS.Chat()# chat.load_models(source="local",local_path=CHATTTS_DIR, compile=True if os.getenv('compile','true').lower()!='false' else False)# 配置日志
# 禁用 Werkzeug 默认的日志处理器
log = logging.getLogger('werkzeug')
log.handlers[:] = []
log.setLevel(logging.WARNING)app = Flask(__name__, static_folder=ROOT_DIR+'/static', static_url_path='/static',template_folder=ROOT_DIR+'/templates')root_log = logging.getLogger()  # Flask的根日志记录器
root_log.handlers = []
root_log.setLevel(logging.WARNING)
app.logger.setLevel(logging.WARNING) 
# 创建 RotatingFileHandler 对象,设置写入的文件路径和大小限制
file_handler = RotatingFileHandler(LOGS_DIR+f'/{datetime.datetime.now().strftime("%Y%m%d")}.log', maxBytes=1024 * 1024, backupCount=5)
# 创建日志的格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# 设置文件处理器的级别和格式
file_handler.setLevel(logging.WARNING)
file_handler.setFormatter(formatter)
# 将文件处理器添加到日志记录器中
app.logger.addHandler(file_handler)
app.jinja_env.globals.update(enumerate=enumerate)@app.route('/static/<path:filename>')
def static_files(filename):return send_from_directory(app.config['STATIC_FOLDER'], filename)@app.route('/')
def index():speakers=utils.get_speakers()return render_template(f"index{'' if is_cn else 'en'}.html",weburl=WEB_ADDRESS,speakers=speakers,version=VERSION)# 根据文本返回tts结果,返回 filename=文件名 url=可下载地址
# 请求端根据需要自行选择使用哪个
# params:
#
# text:待合成文字
# prompt:
# voice:音色
# custom_voice:自定义音色值
# skip_refine: 1=跳过refine_text阶段,0=不跳过
# temperature
# top_p
# top_k
# speed
# text_seed
# refine_max_new_token
# infer_max_new_token
# wavaudio_queue=[]@app.route('/tts', methods=['GET', 'POST'])
def tts():global audio_queue# 原始字符串text = request.args.get("text","").strip() or request.form.get("text","").strip()prompt = request.args.get("prompt","").strip() or request.form.get("prompt",'')# 默认值defaults = {"custom_voice": 0,"voice": "2222","temperature": 0.3,"top_p": 0.7,"top_k": 20,"skip_refine": 0,"speed":5,"text_seed":42,"refine_max_new_token": 384,"infer_max_new_token": 2048,"wav": 0,"is_stream":0}# 获取custom_voice = utils.get_parameter(request, "custom_voice", defaults["custom_voice"], int)voice = str(custom_voice) if custom_voice > 0 else utils.get_parameter(request, "voice", defaults["voice"], str)temperature = utils.get_parameter(request, "temperature", defaults["temperature"], float)top_p = utils.get_parameter(request, "top_p", defaults["top_p"], float)top_k = utils.get_parameter(request, "top_k", defaults["top_k"], int)skip_refine = utils.get_parameter(request, "skip_refine", defaults["skip_refine"], int)is_stream = utils.get_parameter(request, "is_stream", defaults["is_stream"], int)speed = utils.get_parameter(request, "speed", defaults["speed"], int)text_seed = utils.get_parameter(request, "text_seed", defaults["text_seed"], int)refine_max_new_token = utils.get_parameter(request, "refine_max_new_token", defaults["refine_max_new_token"], int)infer_max_new_token = utils.get_parameter(request, "infer_max_new_token", defaults["infer_max_new_token"], int)wav = utils.get_parameter(request, "wav", defaults["wav"], int)app.logger.info(f"[tts]{text=}\n{voice=},{skip_refine=}\n")if not text:return jsonify({"code": 1, "msg": "text params lost"})# 固定音色rand_spk=None# voice可能是 {voice}.csv or {voice}.pt or numberseed_path=f'{SPEAKER_DIR}/{voice}'print(f'{voice=}')if voice.endswith('.csv') and os.path.exists(seed_path):rand_spk=utils.load_speaker(voice)print(f'当前使用音色 {seed_path=}')elif voice.endswith('.pt') and os.path.exists(seed_path):#如果.env中未指定设备,则使用 ChatTTS相同算法找设备,否则使用指定设备rand_spk=torch.load(seed_path, map_location=select_device(4096) if device=='default' else torch.device(device))print(f'当前使用音色 {seed_path=}')# 否则 判断是否存在 {voice}.csvelif os.path.exists(f'{SPEAKER_DIR}/{voice}.csv'):rand_spk=utils.load_speaker(voice)print(f'当前使用音色 {SPEAKER_DIR}/{voice}.csv')if rand_spk is None:    print(f'当前使用音色:根据seed={voice}获取随机音色')voice=int(voice) if re.match(r'^\d+$',voice) else 2222torch.manual_seed(voice)std, mean = torch.load(f'{CHATTTS_DIR}/asset/spk_stat.pt').chunk(2)#rand_spk = chat.sample_random_speaker()rand_spk = torch.randn(768) * std + mean# 保存音色utils.save_speaker(voice,rand_spk)audio_files = []start_time = time.time()# 中英按语言分行text_list=[t.strip() for t in text.split("\n") if t.strip()]new_text=utils.split_text(text_list)if text_seed>0:torch.manual_seed(text_seed)wavs = chat.infer(new_text, use_decoder=True,stream=True if is_stream==1 else False)combined_wavdata=Noneend_time = time.time()inference_time = end_time - start_timeinference_time_rounded = round(inference_time, 2)print(f"推理时长: {inference_time_rounded} 秒")# 初始化一个空的numpy数组用于之后的合并combined_wavdata = np.array([], dtype=wavs[0][0].dtype)  # 确保dtype与你的wav数据类型匹配for wavdata in wavs:combined_wavdata = np.concatenate((combined_wavdata, wavdata[0]))sample_rate = 24000  # Assuming 24kHz sample rateaudio_duration = len(combined_wavdata) / sample_rateaudio_duration_rounded = round(audio_duration, 2)print(f"音频时长: {audio_duration_rounded} 秒")filename = datetime.datetime.now().strftime('%H%M%S_')+f"use{inference_time_rounded}s-audio{audio_duration_rounded}s-seed{voice}-te{temperature}-tp{top_p}-tk{top_k}-textlen{len(text)}-{str(random())[2:7]}" + ".wav"sf.write(WAVS_DIR+'/'+filename, combined_wavdata, 24000)audio_files.append({"filename": WAVS_DIR + '/' + filename,"url": f"http://{request.host}/static/wavs/{filename}","inference_time": inference_time_rounded,"audio_duration": audio_duration_rounded})result_dict={"code": 0, "msg": "ok", "audio_files": audio_files}try:if torch.cuda.is_available():torch.cuda.empty_cache()except Exception:pass# 兼容pyVideoTrans接口调用if len(audio_files)==1:result_dict["filename"]=audio_files[0]['filename']result_dict["url"]=audio_files[0]['url']if wav>0:return send_file(audio_files[0]['filename'], mimetype='audio/x-wav')else:return jsonify(result_dict)@app.route('/clear_wavs', methods=['POST'])
def clear_wavs():dir_path = 'static/wavs'  # wav音频文件存储目录success, message = utils.ClearWav(dir_path)if success:return jsonify({"code": 0, "msg": message})else:return jsonify({"code": 1, "msg": message})try:host = WEB_ADDRESS.split(':')print(f'Start:{WEB_ADDRESS}')threading.Thread(target=utils.openweb,args=(f'http://{WEB_ADDRESS}',)).start()serve(app,host=host[0], port=int(host[1]))
except Exception as e:print(e)

欢迎使用Markdown编辑器

你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。

新的改变

我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:

  1. 全新的界面设计 ,将会带来全新的写作体验;
  2. 在创作中心设置你喜爱的代码高亮样式,Markdown 将代码片显示选择的高亮样式 进行展示;
  3. 增加了 图片拖拽 功能,你可以将本地的图片直接拖拽到编辑区域直接展示;
  4. 全新的 KaTeX数学公式 语法;
  5. 增加了支持甘特图的mermaid语法1 功能;
  6. 增加了 多屏幕编辑 Markdown文章功能;
  7. 增加了 焦点写作模式、预览模式、简洁写作模式、左右区域同步滚轮设置 等功能,功能按钮位于编辑区域与预览区域中间;
  8. 增加了 检查列表 功能。

功能快捷键

撤销:Ctrl/Command + Z
重做:Ctrl/Command + Y
加粗:Ctrl/Command + B
斜体:Ctrl/Command + I
标题:Ctrl/Command + Shift + H
无序列表:Ctrl/Command + Shift + U
有序列表:Ctrl/Command + Shift + O
检查列表:Ctrl/Command + Shift + C
插入代码:Ctrl/Command + Shift + K
插入链接:Ctrl/Command + Shift + L
插入图片:Ctrl/Command + Shift + G
查找:Ctrl/Command + F
替换:Ctrl/Command + G

合理的创建标题,有助于目录的生成

直接输入1次#,并按下space后,将生成1级标题。
输入2次#,并按下space后,将生成2级标题。
以此类推,我们支持6级标题。有助于使用TOC语法后生成一个完美的目录。

如何改变文本的样式

强调文本 强调文本

加粗文本 加粗文本

标记文本

删除文本

引用文本

H2O is是液体。

210 运算结果是 1024.

插入链接与图片

链接: link.

图片: Alt

带尺寸的图片: Alt

居中的图片: Alt

居中并且带尺寸的图片: Alt

当然,我们为了让用户更加便捷,我们增加了图片拖拽功能。

如何插入一段漂亮的代码片

去博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片.

// An highlighted block
var foo = 'bar';

生成一个适合你的列表

  • 项目
    • 项目
      • 项目
  1. 项目1
  2. 项目2
  3. 项目3
  • 计划任务
  • 完成任务

创建一个表格

一个简单的表格是这么创建的:

项目Value
电脑$1600
手机$12
导管$1

设定内容居中、居左、居右

使用:---------:居中
使用:----------居左
使用----------:居右

第一列第二列第三列
第一列文本居中第二列文本居右第三列文本居左

SmartyPants

SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如:

TYPEASCIIHTML
Single backticks'Isn't this fun?'‘Isn’t this fun?’
Quotes"Isn't this fun?"“Isn’t this fun?”
Dashes-- is en-dash, --- is em-dash– is en-dash, — is em-dash

创建一个自定义列表

Markdown
Text-to- HTML conversion tool
Authors
John
Luke

如何创建一个注脚

一个具有注脚的文本。2

注释也是必不可少的

Markdown将文本转换为 HTML

KaTeX数学公式

您可以使用渲染LaTeX数学表达式 KaTeX:

Gamma公式展示 Γ ( n ) = ( n − 1 ) ! ∀ n ∈ N \Gamma(n) = (n-1)!\quad\forall n\in\mathbb N Γ(n)=(n1)!nN 是通过欧拉积分

Γ ( z ) = ∫ 0 ∞ t z − 1 e − t d t . \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,. Γ(z)=0tz1etdt.

你可以找到更多关于的信息 LaTeX 数学表达式here.

新的甘特图功能,丰富你的文章

2014-01-07 2014-01-09 2014-01-11 2014-01-13 2014-01-15 2014-01-17 2014-01-19 2014-01-21 已完成 进行中 计划一 计划二 现有任务 Adding GANTT diagram functionality to mermaid
  • 关于 甘特图 语法,参考 这儿,

UML 图表

可以使用UML图表进行渲染。 Mermaid. 例如下面产生的一个序列图:

张三 李四 王五 你好!李四, 最近怎么样? 你最近怎么样,王五? 我很好,谢谢! 我很好,谢谢! 李四想了很长时间, 文字太长了 不适合放在一行. 打量着王五... 很好... 王五, 你怎么样? 张三 李四 王五

这将产生一个流程图。:

链接
长方形
圆角长方形
菱形
  • 关于 Mermaid 语法,参考 这儿,

FLowchart流程图

我们依旧会支持flowchart的流程图:

Created with Raphaël 2.3.0 开始 我的操作 确认? 结束 yes no
  • 关于 Flowchart流程图 语法,参考 这儿.

导出与导入

导出

如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。

导入

如果你想加载一篇你写过的.md文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入,
继续你的创作。


  1. mermaid语法说明 ↩︎

  2. 注脚的解释 ↩︎

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词