在这个信息爆炸的时代,人们越来越渴望以独特而有效的方式传递信息。声音,作为人类最自然的沟通方式之一,拥有着无可比拟的力量和魅力。它能够跨越语言和文化的障碍,触动人心,激发情感,甚至改变世界。现在,我们为你带来了一项革命性的声音合成技术 —— 让你的声音成为你最强大的宣传工具!
想象一下,你的声音可以无限复制,传播到世界的每一个角落。无论是商业广告、教育培训、有声读物还是个人品牌推广,高质量的语音合成都能为你提供无与伦比的帮助。我们的声音合成技术不仅可以模仿真人发声,还能根据不同的场景和需求调整语调、情感和速度,确保每一次传递都是精准而动人的。
我们的技术优势在于其高度的自然性和灵活性。通过深度学习算法,我们的声音合成系统可以理解并模拟人类的语音特征,生成几乎无法区分的合成声音。这意味着你可以用自己或他人的声音制作内容,而无需担心听众会发现任何不自然的痕迹。此外,我们的技术还支持多语种和方言,让你的信息能够触及更广泛的受众群体。
应用场景广泛,从企业宣传到个人表达,从教育课程到娱乐内容,我们的声音合成技术都能提供完美的解决方案。企业可以利用定制的语音形象来加强品牌形象,提升客户体验;教育工作者可以创建互动式学习材料,提高教学效果;内容创作者可以通过独特的声音风格吸引更多的关注和订阅;甚至个人用户也可以利用这项技术来保存亲人的声音或是为自己创建一个虚拟助手。
我们致力于不断推动声音合成技术的发展,以满足不断变化的市场需求。我们的团队由一群热爱音频技术的专家组成,他们不断地研究最新的科技趋势,以确保我们的产品和服务始终处于行业领先地位。我们相信,通过我们的努力,声音将成为连接人与人、人与世界的桥梁。
现在就加入我们,让我们一起探索声音的无限可能。无论你是想扩大你的业务影响力,还是想为你的创作增添一抹独特的色彩,我们的声音合成技术都将是你最佳的选择。联系我们,开启你的声音之旅,让世界听见你的声音!
<template>
<div class="One-container">
<div>
<el-tag type="success">
<span style="font-weight: bold;font-size: larger">
请点击开始录音后朗读==>:刚烤好的面包散发着诱人的香味,连带着整个早晨都变得温暖而充满活力,一天的忙碌从这美好的早餐开始。
</span>
</el-tag>
<br><br>
<el-button type="primary" @click="startRecordAudio">开始录音</el-button>
<span style="margin-left: 10px;margin-right: 10px;">录音时长:{{ recorder.duration.toFixed(4) }}</span>
<el-button type="danger" @click="stopRecordAudio">停止录音</el-button>
<el-button type="warning" @click="playRecordAudio">播放录音</el-button>
<el-button type="warning" @click="downloadWAVRecordAudioData">下载WAV录音文件</el-button>
<el-button type="primary" @click="uploadWAVData">上传录音并训练发音</el-button>
<el-dialog
:visible.sync="loading"
title="发音音色正在训练"
lock-scroll
:close-on-click-modal="false"
top="10%"
width="30%">
<!-- :showClose="false"-->
<span>正在训练中,请稍后...</span>
</el-dialog>
<br/><br/>
<hr/>
<!--发音音色列表展示-->
<el-row :gutter="10" style="border-bottom: 1px dashed grey">
<el-col :span="4" v-for="item in itemList">
<el-card style="height: 102px;">
<img src="../css_assets/7.png" style="width: 15%">
<div style="display: inline-block;vertical-align: top;margin-left: 20px;width: 120px;">
{{ item.time.substring(item.time.length - 8) }}<br>
<span
style="padding-left: 5px;padding-right: 5px; font-size: 12px;background-color: dodgerblue;color: white">
一句复刻
</span>
<span style="margin-left: 10px;font-size: 12px;color: #409EFF;">个性音色</span>
<br>
<el-radio v-model="radio" :label=item.number>使用</el-radio>
<el-popconfirm
confirm-button-text="确定"
cancel-button-text="取消"
icon="el-icon-info"
icon-color="red"
title="确认要删除吗?"
@confirm="confirmDelete(item.id)">
<span slot="reference"
style="background-color: red;color: white;font-size: 12px;padding-left: 5px;padding-right: 5px;cursor: pointer">
删除
</span>
</el-popconfirm>
</div>
</el-card>
</el-col>
</el-row>
<!-- 合成界面-->
<!-- 合成文本区域 -->
<div>
<el-input type="textarea" v-model="ttsText" rows="15"
style="font-family: 'Microsoft YaHei';font-size: medium;font-weight: bold"
:maxlength="2000" show-word-limit placeholder="请输入不超过2000个汉字的文本进行合成">
</el-input>
</div>
<br>
<el-button type="primary" size="medium" @click="clickTts" style="margin-left:10px;">合成与播放</el-button>
<el-button type="success" size="medium" @click="clickWav">下载并保存</el-button>
<span
style="margin-left: 10px;color: lightgray">温馨提示:我行[=hang2]推出,其中[=hang2]可以标记 行 发hang2声。
</span>
</div>
</div>
</template>
@PostMapping("/upload_train") // 训练发音音色
public Res upload_train(Document document) throws Exception {
String originName = document.getMultipartFile().getOriginalFilename();
String type = FileUtil.extName(originName);
long size = document.getMultipartFile().getSize();
// 1、存到磁盘、存储数据库
File uploadDir = new File(MyUtils.getFinalPath());
System.err.println(uploadDir);
if (!uploadDir.exists()) {
System.out.println(uploadDir.mkdir()); //不存在创建新目录
}
// 2、最终文件路径
String fileUUID = IdUtil.fastSimpleUUID() + "." + type;
String url = blackIp + "/document/" + fileUUID;
String preview = blackIp + "/document/pre_see/" + fileUUID;
File uploadFile = new File(uploadDir + "/" + fileUUID);
//3、获取md5
if (!uploadFile.exists()) {
document.getMultipartFile().transferTo(uploadFile); // 这时候才存磁盘!!!!!
}
// System.out.println("存储是否成功?" + uploadFile.exists());
String md5 = SecureUtil.md5(uploadFile);
// 4、判断数据库里md5是否存在
document.setMd5(md5);
QueryWrapper<Document> documentQueryWrapper = new QueryWrapper<>();
documentQueryWrapper.eq("md5", document.getMd5());
List<Document> documentList = documentMapper.selectList(documentQueryWrapper); // 新的方式
System.out.println(documentList);
if (!documentList.isEmpty()) {
url = documentList.get(0).getUrl(); // 存在的话,url直接从已存在数据库信息拿到
preview = documentList.get(0).getPreview();
System.out.println(uploadFile.delete());// 删除本地存储的文件
}
// 5、存数据库
Document insertDocument = new Document();
insertDocument.setUrl(url);
insertDocument.setPreview(preview);
insertDocument.setName(originName);
insertDocument.setType(type);
insertDocument.setSize(size / 1024);
insertDocument.setMd5(md5);
documentMapper.insert(insertDocument);
// 可以拿到url进行训练
String token = MyUtils.getOneToken();
String taskId = MyUtils.createTask(token);
// 记得修改为url
MyUtils.addAudio(token, taskId, url);
MyUtils.submitTask(token, taskId);
// 轮询查看训练进度
while (true) {
MyUtils.ResProcess resProcess = MyUtils.getProcess(token, taskId);
int trainStatus = resProcess.data.trainStatus;
if (trainStatus == -1) {
System.out.println("还在训练中,请等待......");
} else if (trainStatus == 1) {
System.out.println("训练成功,请用该音库开始测试语音合成:" + resProcess.data.assetId);
Timbre tempTimbre = new Timbre();
tempTimbre.setName(document.getUserName());
tempTimbre.setNumber(resProcess.data.assetId);
tempTimbre.setTime(new Date());
timbreMapper.insert(tempTimbre);
break;
} else if (trainStatus == 0) {
System.err.println("训练失败,请根据任务id 排查失败原因:" + taskId);
//注意:上传的音频要和您选择的训练文本一致,否则会训练失败!!!请核对addAudio里的textId、textSegId文本与音频数据一致!
System.err.println("训练失败原因" + resProcess.data.failedDesc);
return Res.error(Constants.CODE_600, "训练失败" + resProcess.data.failedDesc);
}
}
return Res.success();
}