commit
38cb125a80
6 changed files with 451 additions and 0 deletions
@ -0,0 +1,2 @@ |
|||
#!/bin/bash |
|||
nuitka3 --standalone --onefile --jobs=8 --include-module=cProfile,wave,cmath --show-memory --show-progress --include-package=httpx,PIL,sqlite3 --output-dir=build --include-data-dir=conf=conf --nofollow-import-to=numpy,os,time,matplotlib,scipy,nltk,datasets,huggingface_hub,fastapi,paddlespeech,paddlenlp,paddleslim,panda,numba,pygments,loguru,cffi ttsmain.py & >>packlog.txt |
@ -0,0 +1,203 @@ |
|||
[ |
|||
{ |
|||
"name": "ready", |
|||
"content": "开始!" |
|||
}, |
|||
{ |
|||
"name": "start", |
|||
"content": "开始" |
|||
}, |
|||
{ |
|||
"name": "add_person", |
|||
"content": "请举手识别" |
|||
}, |
|||
{ |
|||
"name": "t-7", |
|||
"content": "仰卧起坐" |
|||
}, |
|||
{ |
|||
"name": "t-0", |
|||
"content": "俯卧撑" |
|||
}, |
|||
{ |
|||
"name": "t-2", |
|||
"content": "单杠引体向上" |
|||
}, |
|||
{ |
|||
"name": "t-3", |
|||
"content": "曲臂悬垂" |
|||
}, |
|||
{ |
|||
"name": "t-5", |
|||
"content": "蛇形跑" |
|||
}, |
|||
{ |
|||
"name": "t-4", |
|||
"content": "跑步" |
|||
}, |
|||
{ |
|||
"name": "t-1", |
|||
"content": "仰卧卷腹" |
|||
}, |
|||
{ |
|||
"name": "un_identification", |
|||
"content": "请伸直手臂" |
|||
}, |
|||
{ |
|||
"name": "startup", |
|||
"content": "欢迎使用中能鸿达智能训考终端!" |
|||
}, |
|||
{ |
|||
"name": "recognize", |
|||
"content": "已识别!" |
|||
}, |
|||
{ |
|||
"name": "re_identification", |
|||
"content": "重新识别!" |
|||
}, |
|||
{ |
|||
"name": "face_little", |
|||
"content": "人脸识别不清,请靠近!" |
|||
}, |
|||
{ |
|||
"name": "face_start", |
|||
"content": "人脸采集开始!" |
|||
}, |
|||
{ |
|||
"name": "face_stop", |
|||
"content": "人脸采集完成!" |
|||
}, |
|||
{ |
|||
"name": "face_timeout", |
|||
"content": "人脸采集超时!" |
|||
}, |
|||
{ |
|||
"name": "recognize_timeout", |
|||
"content": "识别超时,请重新举手识别" |
|||
}, |
|||
{ |
|||
"name": "readying", |
|||
"content": "请全体准备!" |
|||
}, |
|||
{ |
|||
"name": "ready_timeout", |
|||
"content": "准备超时" |
|||
}, |
|||
{ |
|||
"name": "train_stop", |
|||
"content": "已停止训考!" |
|||
}, |
|||
{ |
|||
"name" : "pass", |
|||
"content": "合格!" |
|||
}, |
|||
{ |
|||
"name": "fail", |
|||
"content": "不合格!" |
|||
}, |
|||
{ |
|||
"name": "task_stop", |
|||
"content": "训考结束!" |
|||
}, |
|||
{ |
|||
"name": "max_person", |
|||
"content": "当前识别人数已超过最大值!" |
|||
}, |
|||
{ |
|||
"name": "countdown", |
|||
"content": "倒计时,3,2,1,开始" |
|||
}, |
|||
{ |
|||
"name": "area1", |
|||
"content": "区域一" |
|||
}, |
|||
{ |
|||
"name": "area2", |
|||
"content": "区域二" |
|||
}, |
|||
{ |
|||
"name": "area3", |
|||
"content": "区域三" |
|||
}, |
|||
{ |
|||
"name": "area4", |
|||
"content": "区域四" |
|||
}, |
|||
{ |
|||
"name": "area5", |
|||
"content": "区域五" |
|||
}, |
|||
{ |
|||
"name": "bend_knees", |
|||
"content": "弯膝" |
|||
}, |
|||
{ |
|||
"name": "hip", |
|||
"content": "撅臀" |
|||
}, |
|||
{ |
|||
"name": "waist", |
|||
"content": "塌腰" |
|||
}, |
|||
{ |
|||
"name": "shoulder", |
|||
"content": "肩高于肘" |
|||
}, |
|||
{ |
|||
"name": "feet", |
|||
"content": "脚未并拢" |
|||
}, |
|||
{ |
|||
"name": "body", |
|||
"content": "侧身" |
|||
}, |
|||
{ |
|||
"name": "elbow", |
|||
"content": "手肘弯曲" |
|||
}, |
|||
{ |
|||
"name": "bend_knees_e", |
|||
"content": "弯膝不足" |
|||
}, |
|||
{ |
|||
"name": "feet_floor", |
|||
"content": "脚掌离地" |
|||
}, |
|||
{ |
|||
"name": "hand_floor", |
|||
"content": "手掌离地" |
|||
}, |
|||
{ |
|||
"name": "up_hip", |
|||
"content": "翘臀" |
|||
}, |
|||
{ |
|||
"name": "shoulder_floor", |
|||
"content" : "肩未着地" |
|||
}, |
|||
{ |
|||
"name": "hand_move", |
|||
"content": "手未移动" |
|||
}, |
|||
{ |
|||
"name": "body_up", |
|||
"content": "起身不足" |
|||
}, |
|||
{ |
|||
"name": "double_hand", |
|||
"content": "双手离肩" |
|||
}, |
|||
{ |
|||
"name" : "swing", |
|||
"content": "摆浪" |
|||
}, |
|||
{ |
|||
"name": "bar", |
|||
"content": "搭杠" |
|||
}, |
|||
{ |
|||
"name": "hand_stright", |
|||
"content": "手未伸直" |
|||
} |
|||
|
|||
] |
@ -0,0 +1,76 @@ |
|||
[{ |
|||
"suname": "尉迟", |
|||
"speak": "<say-as pinyin='yu4'>尉</say-as>迟" |
|||
}, { |
|||
"suname": "皇甫", |
|||
"speak": "皇<say-as pinyin='fu3'>甫</say-as>" |
|||
}, { |
|||
"suname": "长孙", |
|||
"speak": "<say-as pinyin='zhang3'>长</say-as>孙" |
|||
}, |
|||
{ |
|||
"suname": "仇", |
|||
"speak": "<say-as pinyin='qiu2'>仇</say-as>" |
|||
}, |
|||
{ |
|||
"suname": "朴", |
|||
"speak": "<say-as pinyin='piao2'>朴</say-as>" |
|||
}, { |
|||
"suname": "单", |
|||
"speak": "<say-as pinyin='shan4'>单</say-as>" |
|||
}, { |
|||
"suname": "解", |
|||
"speak": "<say-as pinyin='xie4'>解</say-as>" |
|||
}, { |
|||
"suname": "区", |
|||
"speak": "<say-as pinyin='ou1'>区</say-as>" |
|||
}, { |
|||
"suname": "查", |
|||
"speak": "<say-as pinyin='zha1'>查</say-as>" |
|||
}, { |
|||
"suname": "繁", |
|||
"speak": "<say-as pinyin='po2'>繁</say-as>" |
|||
}, { |
|||
"suname": "瞿", |
|||
"speak": "<say-as pinyin='qu2'>瞿</say-as>" |
|||
}, { |
|||
"suname": "覃", |
|||
"speak": "<say-as pinyin='qin2'>覃</say-as>" |
|||
}, { |
|||
"suname": "曾", |
|||
"speak": "<say-as pinyin='zeng1'>曾</say-as>" |
|||
}, { |
|||
"suname": "员", |
|||
"speak": "<say-as pinyin='yun4'>员</say-as>" |
|||
}, { |
|||
"suname": "能", |
|||
"speak": "<say-as pinyin='nai4'>能</say-as>" |
|||
}, { |
|||
"suname": "阚", |
|||
"speak": "<say-as pinyin='kan4'>阚</say-as>" |
|||
}, { |
|||
"suname": "都", |
|||
"speak": "<say-as pinyin='du1'>都</say-as>" |
|||
}, { |
|||
"suname": "乜", |
|||
"speak": "<say-as pinyin='nie4'>乜</say-as>" |
|||
}, { |
|||
"suname": "缪", |
|||
"speak": "<say-as pinyin='miao4'>缪</say-as>" |
|||
}, { |
|||
"suname": "句", |
|||
"speak": "<say-as pinyin='gou1'>句</say-as>" |
|||
}, { |
|||
"suname": "阿", |
|||
"speak": "<say-as pinyin='e1'>阿</say-as>" |
|||
}, { |
|||
"suname": "盖", |
|||
"speak": "<say-as pinyin='ge3'>盖</say-as>" |
|||
}, { |
|||
"suname": "乐", |
|||
"speak": "<say-as pinyin='yue4'>乐</say-as>" |
|||
}, { |
|||
"suname": "种", |
|||
"speak": "<say-as pinyin='chong2'>种</say-as>" |
|||
} |
|||
] |
@ -0,0 +1,2 @@ |
|||
生成多音字的格式,注明拼音的文字和其它文字使用@间隔,文字和拼音用*间隔,示例如:覃*qin2@海洋 |
|||
生成命令: |
@ -0,0 +1,2 @@ |
|||
paddlepaddle-gpu==2.5.1 |
|||
paddlespeech==1.4.1 |
@ -0,0 +1,166 @@ |
|||
# coding:utf-8 |
|||
|
|||
import json |
|||
from paddlespeech.cli.tts.infer import TTSExecutor |
|||
import numpy as np |
|||
from scipy.io import wavfile |
|||
from pathlib import Path |
|||
import sys |
|||
import os |
|||
import re |
|||
from flask import Flask, request, jsonify |
|||
from concurrent.futures import ThreadPoolExecutor |
|||
|
|||
executor =ThreadPoolExecutor(1) |
|||
app = Flask(__name__) |
|||
current_file_path = os.fspath(Path(__file__).resolve().parent) |
|||
save_file_path = f"{os.path.join(os.fspath(Path(__file__).resolve().parent.parent),'data','preload')}" |
|||
tts=TTSExecutor() |
|||
@app.route('/buildvoice', methods=['POST']) |
|||
def buildvoice(): |
|||
# 获取 JSON 请求体 |
|||
data = request.get_json() |
|||
|
|||
# 从请求体中提取参数 |
|||
voice_text = data.get('voice_text') |
|||
file_name = data.get('file_name') |
|||
# 检查参数是否存在 |
|||
if not voice_text or not file_name: |
|||
response = { |
|||
'status': 'error', |
|||
'message': 'Missing voice_text or file_name', |
|||
'data': None |
|||
} |
|||
return jsonify(response), 400 |
|||
|
|||
current_directory = f"{os.path.join(current_file_path, 'conf', 'surname.json')}" |
|||
try: |
|||
if '@' in voice_text: |
|||
audio_data="<speak>" |
|||
text=voice_text.split('@') |
|||
for txt in text: |
|||
if '*' in txt: |
|||
audio_data += f"<say-as pinyin='{txt.split('*')[1]}'>{txt.split('*')[0]}</say-as>" |
|||
else: |
|||
audio_data+=txt |
|||
audio_data+='</speak>' |
|||
else : |
|||
if not os.path.isfile(current_directory): |
|||
audio_data=voice_text |
|||
else: |
|||
try: |
|||
with open(current_directory, 'r', encoding='utf-8') as file: |
|||
preload_data = json.load(file) |
|||
except json.JSONDecodeError as e: |
|||
#print(f"预加载姓氏读音配置文件格式错误: {str(e)}") |
|||
response = { |
|||
'status': 'error', |
|||
'message': f"预加载姓氏读音配置文件格式错误: {str(e)}", |
|||
'data': None |
|||
} |
|||
return jsonify(response), 400 |
|||
audio_data=voice_text |
|||
for item in preload_data: |
|||
if voice_text.startswith(item['suname']): |
|||
audio_data ="<speak>"+ re.sub("^" + re.escape(item['suname']), item['speak'], voice_text)+'</speak>' |
|||
break |
|||
save_voice(audio_data,f"{save_file_path}/{file_name}.wav") |
|||
# 响应内容 |
|||
response = { |
|||
'status': 'success', |
|||
'message': 'voice file generated successfully' |
|||
} |
|||
return jsonify(response), 200 |
|||
except json.JSONDecodeError as e: |
|||
response = { |
|||
'status': 'error', |
|||
'message': f"build voice file error: {str(e)}", |
|||
'data': None |
|||
} |
|||
return jsonify(response), 400 |
|||
|
|||
|
|||
@app.route('/initvoice', methods=['POST']) |
|||
def run_initvoice(): |
|||
executor.submit(initvoice) |
|||
response = { |
|||
'status': 'success', |
|||
'message': 'build init voice running.....' |
|||
} |
|||
return jsonify(response), 200 |
|||
|
|||
def initvoice(): |
|||
print(f"=====build voice file start=====") |
|||
current_directory = f"{os.path.join(current_file_path, 'conf', 'preload.json')}" |
|||
if not os.path.exists(save_file_path): |
|||
os.makedirs(save_file_path) |
|||
if not os.path.isfile(current_directory): |
|||
print("预加载语音配置文件不存在!") |
|||
sys.exit(1) |
|||
try: |
|||
with open(current_directory, 'r', encoding='utf-8') as file: |
|||
preload_data = json.load(file) |
|||
except json.JSONDecodeError as e: |
|||
print(f"预加载语音配置文件格式错误: {str(e)}") |
|||
sys.exit(1) |
|||
for item in preload_data: |
|||
save_voice(item['content'], f"{save_file_path}/{item['name']}.wav") |
|||
for i in range(150): |
|||
save_voice(f'{i}', f"{save_file_path}/{i}.wav") |
|||
|
|||
print(f"=====build voice file success=====") |
|||
|
|||
def save_voice(audio_data,file_path): |
|||
tts(text=audio_data, output=f"temp.wav",device='cpu', spk_id=0, am='speedyspeech_csmsc') |
|||
# 将增强音量的音频写入新文件 |
|||
sample_rate,data=wavfile.read("temp.wav") |
|||
new_data=data*2 |
|||
new_data=np.clip(new_data,-32768,32767).astype(np.int16) |
|||
wavfile.write(file_path,sample_rate,new_data) |
|||
# if __name__ == '__main__': |
|||
# args = sys.argv |
|||
# current_directory = f"{os.path.join(current_file_path, 'conf', 'surname.json')}" |
|||
|
|||
# print('生成多音字的格式,注明拼音的文字和其它文字使用@间隔,文字和拼音用*间隔,示例如:覃*qin2@海洋') |
|||
# if len(args)!=3: |
|||
# print("参数不合法,请检查:需要2个参数 第1个参数为语音文本 第2个参数为语音文件保存路径") |
|||
# sys.exit(-1) |
|||
# tts=TTSExecutor() |
|||
# if '@' in args[1]: |
|||
# audio_data="<speak>" |
|||
# text=args[1].split('@') |
|||
# for txt in text: |
|||
# if '*' in txt: |
|||
# audio_data += f"<say-as pinyin='{txt.split('*')[1]}'>{txt.split('*')[0]}</say-as>" |
|||
# else: |
|||
# audio_data+=txt |
|||
# audio_data+='</speak>' |
|||
# else : |
|||
# if not os.path.isfile(current_directory): |
|||
# audio_data=args[1] |
|||
# else: |
|||
# try: |
|||
# with open(current_directory, 'r', encoding='utf-8') as file: |
|||
# preload_data = json.load(file) |
|||
# except json.JSONDecodeError as e: |
|||
# print(f"预加载姓氏读音配置文件格式错误: {str(e)}") |
|||
# sys.exit(1) |
|||
# audio_data=args[1] |
|||
# for item in preload_data: |
|||
# if args[1].startswith(item['suname']): |
|||
# audio_data ="<speak>"+ re.sub("^" + re.escape(item['suname']), item['speak'], args[1])+'</speak>' |
|||
# break |
|||
# output_file = f"{os.path.join(current_file_path, 'files',args[2])}.wav" |
|||
# print('即将生成:{} 的语音文件,保存位置为{}.....'.format(audio_data,output_file)) |
|||
# tts(text=audio_data, output=f"temp.wav",device='cpu', spk_id=0, am='speedyspeech_csmsc') |
|||
# # 将增强音量的音频写入新文件 |
|||
# print('生成成功,增强音量中') |
|||
# sample_rate,data=wavfile.read("temp.wav") |
|||
# new_data=data*2 |
|||
# new_data=np.clip(new_data,-32768,32767).astype(np.int16) |
|||
# wavfile.write(output_file,sample_rate,new_data) |
|||
# print('语音文件已保存{}'.format(output_file)) |
|||
|
|||
|
|||
if __name__ == '__main__': |
|||
app.run(host='0.0.0.0',port=5000,debug=True) |
Loading…
Reference in new issue