关于tts:微软TTStexttospeech文字转语音免费开源库edgetts语音合成实践Python310

不能否定,微软Azure在TTS(text-to-speech文字转语音)这个人工智能细分畛域的影响力是统治级的,一如ChatGPT在NLP畛域的得心应手,予取予求。君不见简直所有的抖音营销号口播均采纳微软的语音合成技术,其影响力由此可见一斑,仅有的白璧微瑕之处就是价格略高,尽管国内也能够应用科大讯飞语音合成进行平替,但咱们只想要最好的那一个,本次咱们应用收费的开源库edge-tts来实现文本转语音操作,薅微软edge的羊毛。 TTS文本转语音根底应用形式首先装置edge-tts库: pip3 install edge-tts装置胜利后,间接在终端运行edge-tts命令: edge-tts显示帮忙菜单即代表装置胜利: ➜ Downloads edge-tts usage: edge-tts [-h] [-t TEXT] [-f FILE] [-v VOICE] [-l] [--rate RATE] [--volume VOLUME] [-O OVERLAPPING] [--write-media WRITE_MEDIA] [--write-subtitles WRITE_SUBTITLES] [--proxy PROXY]随后输出命令: edge-tts --list-voices该命令能够将Edge浏览器中,内置的语言角色列表列出来: Name: af-ZA-AdriNeural Gender: Female Name: af-ZA-WillemNeural Gender: Male Name: am-ET-AmehaNeural Gender: Male Name: am-ET-MekdesNeural Gender: Female Name: ar-AE-FatimaNeural Gender: Female Name: ar-AE-HamdanNeural Gender: Male Name: ar-BH-AliNeural Gender: Male Name: ar-BH-LailaNeural Gender: Female Name: ar-DZ-AminaNeural Gender: Female Name: ar-DZ-IsmaelNeural Gender: Male Name: ar-EG-SalmaNeural Gender: Female Name: ar-EG-ShakirNeural Gender: Male Name: ar-IQ-BasselNeural Gender: Male Name: ar-IQ-RanaNeural Gender: Female Name: ar-JO-SanaNeural Gender: Female Name: ar-JO-TaimNeural Gender: Male Name: ar-KW-FahedNeural Gender: Male Name: ar-KW-NouraNeural Gender: Female Name: ar-LB-LaylaNeural Gender: Female Name: ar-LB-RamiNeural Gender: Male Name: ar-LY-ImanNeural Gender: Female Name: ar-LY-OmarNeural Gender: Male Name: ar-MA-JamalNeural Gender: Male Name: ar-MA-MounaNeural Gender: Female Name: ar-OM-AbdullahNeural Gender: Male Name: ar-OM-AyshaNeural Gender: Female Name: ar-QA-AmalNeural Gender: Female Name: ar-QA-MoazNeural Gender: Male Name: ar-SA-HamedNeural Gender: Male Name: ar-SA-ZariyahNeural Gender: Female Name: ar-SY-AmanyNeural Gender: Female Name: ar-SY-LaithNeural Gender: Male Name: ar-TN-HediNeural Gender: Male Name: ar-TN-ReemNeural Gender: Female Name: ar-YE-MaryamNeural Gender: Female Name: ar-YE-SalehNeural Gender: Male Name: az-AZ-BabekNeural Gender: Male Name: az-AZ-BanuNeural Gender: Female Name: bg-BG-BorislavNeural Gender: Male Name: bg-BG-KalinaNeural Gender: Female Name: bn-BD-NabanitaNeural Gender: Female Name: bn-BD-PradeepNeural Gender: Male Name: bn-IN-BashkarNeural Gender: Male Name: bn-IN-TanishaaNeural Gender: Female Name: bs-BA-GoranNeural Gender: Male Name: bs-BA-VesnaNeural Gender: Female Name: ca-ES-EnricNeural Gender: Male Name: ca-ES-JoanaNeural Gender: Female Name: cs-CZ-AntoninNeural Gender: Male Name: cs-CZ-VlastaNeural Gender: Female Name: cy-GB-AledNeural Gender: Male Name: cy-GB-NiaNeural Gender: Female Name: da-DK-ChristelNeural Gender: Female Name: da-DK-JeppeNeural Gender: Male Name: de-AT-IngridNeural Gender: Female Name: de-AT-JonasNeural Gender: Male Name: de-CH-JanNeural Gender: Male Name: de-CH-LeniNeural Gender: Female Name: de-DE-AmalaNeural Gender: Female Name: de-DE-ConradNeural Gender: Male Name: de-DE-KatjaNeural Gender: Female Name: de-DE-KillianNeural Gender: Male Name: el-GR-AthinaNeural Gender: Female Name: el-GR-NestorasNeural Gender: Male Name: en-AU-NatashaNeural Gender: Female Name: en-AU-WilliamNeural Gender: Male Name: en-CA-ClaraNeural Gender: Female Name: en-CA-LiamNeural Gender: Male Name: en-GB-LibbyNeural Gender: Female Name: en-GB-MaisieNeural Gender: Female Name: en-GB-RyanNeural Gender: Male Name: en-GB-SoniaNeural Gender: Female Name: en-GB-ThomasNeural Gender: Male Name: en-HK-SamNeural Gender: Male Name: en-HK-YanNeural Gender: Female Name: en-IE-ConnorNeural Gender: Male Name: en-IE-EmilyNeural Gender: Female Name: en-IN-NeerjaExpressiveNeural Gender: Female Name: en-IN-NeerjaNeural Gender: Female Name: en-IN-PrabhatNeural Gender: Male Name: en-KE-AsiliaNeural Gender: Female Name: en-KE-ChilembaNeural Gender: Male Name: en-NG-AbeoNeural Gender: Male Name: en-NG-EzinneNeural Gender: Female Name: en-NZ-MitchellNeural Gender: Male Name: en-NZ-MollyNeural Gender: Female Name: en-PH-JamesNeural Gender: Male Name: en-PH-RosaNeural Gender: Female Name: en-SG-LunaNeural Gender: Female Name: en-SG-WayneNeural Gender: Male Name: en-TZ-ElimuNeural Gender: Male Name: en-TZ-ImaniNeural Gender: Female Name: en-US-AnaNeural Gender: Female Name: en-US-AriaNeural Gender: Female Name: en-US-ChristopherNeural Gender: Male Name: en-US-EricNeural Gender: Male Name: en-US-GuyNeural Gender: Male Name: en-US-JennyNeural Gender: Female Name: en-US-MichelleNeural Gender: Female Name: en-US-RogerNeural Gender: Male Name: en-US-SteffanNeural Gender: Male Name: en-ZA-LeahNeural Gender: Female Name: en-ZA-LukeNeural Gender: Male Name: es-AR-ElenaNeural Gender: Female Name: es-AR-TomasNeural Gender: Male Name: es-BO-MarceloNeural Gender: Male Name: es-BO-SofiaNeural Gender: Female Name: es-CL-CatalinaNeural Gender: Female Name: es-CL-LorenzoNeural Gender: Male Name: es-CO-GonzaloNeural Gender: Male Name: es-CO-SalomeNeural Gender: Female Name: es-CR-JuanNeural Gender: Male Name: es-CR-MariaNeural Gender: Female Name: es-CU-BelkysNeural Gender: Female Name: es-CU-ManuelNeural Gender: Male Name: es-DO-EmilioNeural Gender: Male Name: es-DO-RamonaNeural Gender: Female Name: es-EC-AndreaNeural Gender: Female Name: es-EC-LuisNeural Gender: Male Name: es-ES-AlvaroNeural Gender: Male Name: es-ES-ElviraNeural Gender: Female Name: es-ES-ManuelEsCUNeural Gender: Male Name: es-GQ-JavierNeural Gender: Male Name: es-GQ-TeresaNeural Gender: Female Name: es-GT-AndresNeural Gender: Male Name: es-GT-MartaNeural Gender: Female Name: es-HN-CarlosNeural Gender: Male Name: es-HN-KarlaNeural Gender: Female Name: es-MX-DaliaNeural Gender: Female Name: es-MX-JorgeNeural Gender: Male Name: es-MX-LorenzoEsCLNeural Gender: Male Name: es-NI-FedericoNeural Gender: Male Name: es-NI-YolandaNeural Gender: Female Name: es-PA-MargaritaNeural Gender: Female Name: es-PA-RobertoNeural Gender: Male Name: es-PE-AlexNeural Gender: Male Name: es-PE-CamilaNeural Gender: Female Name: es-PR-KarinaNeural Gender: Female Name: es-PR-VictorNeural Gender: Male Name: es-PY-MarioNeural Gender: Male Name: es-PY-TaniaNeural Gender: Female Name: es-SV-LorenaNeural Gender: Female Name: es-SV-RodrigoNeural Gender: Male Name: es-US-AlonsoNeural Gender: Male Name: es-US-PalomaNeural Gender: Female Name: es-UY-MateoNeural Gender: Male Name: es-UY-ValentinaNeural Gender: Female Name: es-VE-PaolaNeural Gender: Female Name: es-VE-SebastianNeural Gender: Male Name: et-EE-AnuNeural Gender: Female Name: et-EE-KertNeural Gender: Male Name: fa-IR-DilaraNeural Gender: Female Name: fa-IR-FaridNeural Gender: Male Name: fi-FI-HarriNeural Gender: Male Name: fi-FI-NooraNeural Gender: Female Name: fil-PH-AngeloNeural Gender: Male Name: fil-PH-BlessicaNeural Gender: Female Name: fr-BE-CharlineNeural Gender: Female Name: fr-BE-GerardNeural Gender: Male Name: fr-CA-AntoineNeural Gender: Male Name: fr-CA-JeanNeural Gender: Male Name: fr-CA-SylvieNeural Gender: Female Name: fr-CH-ArianeNeural Gender: Female Name: fr-CH-FabriceNeural Gender: Male Name: fr-FR-DeniseNeural Gender: Female Name: fr-FR-EloiseNeural Gender: Female Name: fr-FR-HenriNeural Gender: Male Name: ga-IE-ColmNeural Gender: Male Name: ga-IE-OrlaNeural Gender: Female Name: gl-ES-RoiNeural Gender: Male Name: gl-ES-SabelaNeural Gender: Female Name: gu-IN-DhwaniNeural Gender: Female Name: gu-IN-NiranjanNeural Gender: Male Name: he-IL-AvriNeural Gender: Male Name: he-IL-HilaNeural Gender: Female Name: hi-IN-MadhurNeural Gender: Male Name: hi-IN-SwaraNeural Gender: Female Name: hr-HR-GabrijelaNeural Gender: Female Name: hr-HR-SreckoNeural Gender: Male Name: hu-HU-NoemiNeural Gender: Female Name: hu-HU-TamasNeural Gender: Male Name: id-ID-ArdiNeural Gender: Male Name: id-ID-GadisNeural Gender: Female Name: is-IS-GudrunNeural Gender: Female Name: is-IS-GunnarNeural Gender: Male Name: it-IT-DiegoNeural Gender: Male Name: it-IT-ElsaNeural Gender: Female Name: it-IT-IsabellaNeural Gender: Female Name: ja-JP-KeitaNeural Gender: Male Name: ja-JP-NanamiNeural Gender: Female Name: jv-ID-DimasNeural Gender: Male Name: jv-ID-SitiNeural Gender: Female Name: ka-GE-EkaNeural Gender: Female Name: ka-GE-GiorgiNeural Gender: Male Name: kk-KZ-AigulNeural Gender: Female Name: kk-KZ-DauletNeural Gender: Male Name: km-KH-PisethNeural Gender: Male Name: km-KH-SreymomNeural Gender: Female Name: kn-IN-GaganNeural Gender: Male Name: kn-IN-SapnaNeural Gender: Female Name: ko-KR-InJoonNeural Gender: Male Name: ko-KR-SunHiNeural Gender: Female Name: lo-LA-ChanthavongNeural Gender: Male Name: lo-LA-KeomanyNeural Gender: Female Name: lt-LT-LeonasNeural Gender: Male Name: lt-LT-OnaNeural Gender: Female Name: lv-LV-EveritaNeural Gender: Female Name: lv-LV-NilsNeural Gender: Male Name: mk-MK-AleksandarNeural Gender: Male Name: mk-MK-MarijaNeural Gender: Female Name: ml-IN-MidhunNeural Gender: Male Name: ml-IN-SobhanaNeural Gender: Female Name: mn-MN-BataaNeural Gender: Male Name: mn-MN-YesuiNeural Gender: Female Name: mr-IN-AarohiNeural Gender: Female Name: mr-IN-ManoharNeural Gender: Male Name: ms-MY-OsmanNeural Gender: Male Name: ms-MY-YasminNeural Gender: Female Name: mt-MT-GraceNeural Gender: Female Name: mt-MT-JosephNeural Gender: Male Name: my-MM-NilarNeural Gender: Female Name: my-MM-ThihaNeural Gender: Male Name: nb-NO-FinnNeural Gender: Male Name: nb-NO-PernilleNeural Gender: Female Name: ne-NP-HemkalaNeural Gender: Female Name: ne-NP-SagarNeural Gender: Male Name: nl-BE-ArnaudNeural Gender: Male Name: nl-BE-DenaNeural Gender: Female Name: nl-NL-ColetteNeural Gender: Female Name: nl-NL-FennaNeural Gender: Female Name: nl-NL-MaartenNeural Gender: Male Name: pl-PL-MarekNeural Gender: Male Name: pl-PL-ZofiaNeural Gender: Female Name: ps-AF-GulNawazNeural Gender: Male Name: ps-AF-LatifaNeural Gender: Female Name: pt-BR-AntonioNeural Gender: Male Name: pt-BR-FranciscaNeural Gender: Female Name: pt-PT-DuarteNeural Gender: Male Name: pt-PT-RaquelNeural Gender: Female Name: ro-RO-AlinaNeural Gender: Female Name: ro-RO-EmilNeural Gender: Male Name: ru-RU-DmitryNeural Gender: Male Name: ru-RU-SvetlanaNeural Gender: Female Name: si-LK-SameeraNeural Gender: Male Name: si-LK-ThiliniNeural Gender: Female Name: sk-SK-LukasNeural Gender: Male Name: sk-SK-ViktoriaNeural Gender: Female Name: sl-SI-PetraNeural Gender: Female Name: sl-SI-RokNeural Gender: Male Name: so-SO-MuuseNeural Gender: Male Name: so-SO-UbaxNeural Gender: Female Name: sq-AL-AnilaNeural Gender: Female Name: sq-AL-IlirNeural Gender: Male Name: sr-RS-NicholasNeural Gender: Male Name: sr-RS-SophieNeural Gender: Female Name: su-ID-JajangNeural Gender: Male Name: su-ID-TutiNeural Gender: Female Name: sv-SE-MattiasNeural Gender: Male Name: sv-SE-SofieNeural Gender: Female Name: sw-KE-RafikiNeural Gender: Male Name: sw-KE-ZuriNeural Gender: Female Name: sw-TZ-DaudiNeural Gender: Male Name: sw-TZ-RehemaNeural Gender: Female Name: ta-IN-PallaviNeural Gender: Female Name: ta-IN-ValluvarNeural Gender: Male Name: ta-LK-KumarNeural Gender: Male Name: ta-LK-SaranyaNeural Gender: Female Name: ta-MY-KaniNeural Gender: Female Name: ta-MY-SuryaNeural Gender: Male Name: ta-SG-AnbuNeural Gender: Male Name: ta-SG-VenbaNeural Gender: Female Name: te-IN-MohanNeural Gender: Male Name: te-IN-ShrutiNeural Gender: Female Name: th-TH-NiwatNeural Gender: Male Name: th-TH-PremwadeeNeural Gender: Female Name: tr-TR-AhmetNeural Gender: Male Name: tr-TR-EmelNeural Gender: Female Name: uk-UA-OstapNeural Gender: Male Name: uk-UA-PolinaNeural Gender: Female Name: ur-IN-GulNeural Gender: Female Name: ur-IN-SalmanNeural Gender: Male Name: ur-PK-AsadNeural Gender: Male Name: ur-PK-UzmaNeural Gender: Female Name: uz-UZ-MadinaNeural Gender: Female Name: uz-UZ-SardorNeural Gender: Male Name: vi-VN-HoaiMyNeural Gender: Female Name: vi-VN-NamMinhNeural Gender: Male Name: zh-CN-XiaoxiaoNeural Gender: Female Name: zh-CN-XiaoyiNeural Gender: Female Name: zh-CN-YunjianNeural Gender: Male Name: zh-CN-YunxiNeural Gender: Male Name: zh-CN-YunxiaNeural Gender: Male Name: zh-CN-YunyangNeural Gender: Male Name: zh-CN-liaoning-XiaobeiNeural Gender: Female Name: zh-CN-shaanxi-XiaoniNeural Gender: Female Name: zh-HK-HiuGaaiNeural Gender: Female Name: zh-HK-HiuMaanNeural Gender: Female Name: zh-HK-WanLungNeural Gender: Male Name: zh-TW-HsiaoChenNeural Gender: Female Name: zh-TW-HsiaoYuNeural Gender: Female Name: zh-TW-YunJheNeural Gender: Male Name: zu-ZA-ThandoNeural Gender: Female Name: zu-ZA-ThembaNeural Gender: Male一望而知,简直反对所有支流的通用语,Gender字段为合成语音的性别,Male代表男性,Female代表女性,zh结尾的就是中文语音角色,这里以微软的小伊为例子: ...

March 7, 2023 · 7 min · jiezi

Flutter中 TTS(播放文本功能)的使用

请支持原文:http://tryenough.com/flutter-tts需求在flutter中指定一段文字,播放语音。实现1.添加库引用我们这里使用Dart的 tts库,首先在配置文件中添加这个库的引用:在pubspec.yaml文件中添加如下代码引用:dependencies: tts: ^1.0.2执行命令,获取该库:flutter packages get请支持原文:http://tryenough.com/flutter-tts使用时引入头文件:import ‘package:tts/tts.dart’;2.创建tts_helper类,作为使用tts的帮助类import ‘package:tts/tts.dart’;import ‘dart:async’;import ‘dart:io’;/// Singleton tool class for tts/// Use TtsHelper step:////// Method : #isLanguageAvailable judge language, here language is _languageMap’s values like “en-US”,instead of the type of ’en’ etc..////// Method : #getTtsLanguage help you convert “en” to “en-US”.////// Method : #setLanguage help you set Language , but “en-US” is default value////// use example:/// TtsHelper.instance.speak(“speech content”);/// or/// TtsHelper.instance.setLanguageAndSpeak(“speech content”, “en-US”);/// …class TtsHelper { // Locale to tss language map static final Map<String, String> _languageMap = { ’en’: “en-US”, ‘zh’: “zh-CN”, “ar”: “ar-SA”, “cs”: “cs-CZ”, “da”: “da-DK”, “de”: “de-DE”, “el”: “el-GR”, “es”: “es-ES”, “fi”: “fi-FI”, “fr”: “fr-CA”, “he”: “he-IL”, “hi”: “hi-IN”, “hu”: “hu-HU”, “id”: “id-ID”, “it”: “it-IT”, “ja”: “ja-JP”, “ko”: “ko-KR”, “nl”: “nl-BE”, “no”: “no-NO”, “pl”: “pl-PL”, “pt”: “pt-BR”, “ro”: “ro-RO”, “ru”: “ru-RU”, “sk”: “sk-SK”, “sv”: “sv-SE”, “th”: “th-TH”, “tr”: “tr-TR”, ’en-US’: “en-US”, ‘zh-CN’: “zh-CN”, “ar-SA”: “ar-SA”, “cs-CZ”: “cs-CZ”, “da-DK”: “da-DK”, “de-DE”: “de-DE”, “el-GR”: “el-GR”, “es-ES”: “es-ES”, “fi-FI”: “fi-FI”, “fr-CA”: “fr-CA”, “he-IL”: “he-IL”, “hi-IN”: “hi-IN”, “hu-HU”: “hu-HU”, “id-ID”: “id-ID”, “it-IT”: “it-IT”, “ja-JP”: “ja-JP”, “ko-KR”: “ko-KR”, “nl-BE”: “nl-BE”, “no-NO”: “no-NO”, “pl-PL”: “pl-PL”, “pt-BR”: “pt-BR”, “ro-RO”: “ro-RO”, “ru-RU”: “ru-RU”, “sk-SK”: “sk-SK”, “sv-SE”: “sv-SE”, “th-TH”: “th-TH”, “tr-TR”: “tr-TR”, }; static final String _defaultL = “en-US”; List<String> _languages; static TtsHelper _instance; static TtsHelper get instance => _getInstance(); factory TtsHelper() =>_getInstance(); static TtsHelper _getInstance() { if (_instance == null) { _instance = new TtsHelper._internal(); } return _instance; } TtsHelper._internal() { // Initialize _initPlatformState(); } _initPlatformState() async { _languages = await Tts.getAvailableLanguages(); // If getAvailableLanguages is null, add “en-US” to _languages. if (_languages == null) { _languages = [_defaultL]; } // Default set en-US language _setLanguage(_defaultL); } String _getTtsLanguage(String localeStr) { if(localeStr == null || localeStr.isEmpty || !_languageMap.containsKey(localeStr)) { return _defaultL; } return _languageMap[localeStr]; } // Return whether the result if set language is successful Future<bool> _setLanguage (String lang) async { String language = _getTtsLanguage(lang); if (language == null || language.isEmpty) { language = _defaultL; } if(Platform.isIOS && !_languages.contains(language)) { return false; } final bool isSet = await Tts.setLanguage(language); return isSet; } // Returns whether the supported language is supported Future<bool> _isLanguageAvailable (String language) async { final bool isSupport = await Tts.isLanguageAvailable(language); return isSupport; } void speak (String text) async { if (text == null || text.isEmpty) { return;} Tts.speak(text); } void setLanguageAndSpeak(String text, String language) async { String ttsL = _getTtsLanguage(language); var setResult = await _setLanguage(ttsL); if(setResult != null) { var available = await _isLanguageAvailable(ttsL); if(available != null) { speak(text); } } }}请支持原文:http://tryenough.com/flutter-tts3.添加测试页面import ‘package:flutter_tts/tts_helper.dart’;import ‘package:flutter/material.dart’;class VoiceSetPage extends StatefulWidget { VoiceSetPage({Key key, this.title}) : super(key: key); final String title; @override _VoiceSetPageState createState() => _VoiceSetPageState();}class VoiceSetPageState extends State<VoiceSetPage> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Colors.blue, title: Text(widget.title), elevation: 5.0, // shadow the bottom of AppBar ), body: Center( child: ListView( children: <Widget>[ ListTile( title: Text( ’test vioce’, style: TextStyle(fontWeight: FontWeight.w500, fontSize: 20.0), ), onTap: () { showAlertDialog(context); TtsHelper.instance.setLanguageAndSpeak(“你好我是声音播放器”, “zh”); }, ), Divider( height: 1, ) ], ), ), ); }}void showAlertDialog(BuildContext context) { NavigatorState navigator = context.rootAncestorStateOfType(const TypeMatcher<NavigatorState>()); debugPrint(“navigator is null?” + (navigator == null).toString()); showDialog( context: context, builder: () => new AlertDialog( title: new Text(“Dialog Title”), content: new Text(“This is my content”), actions: <Widget>[ new FlatButton( child: new Text(“CANCEL”), onPressed: () { Navigator.of(context).pop(); }, ), new FlatButton( child: new Text(“OK”), onPressed: () { Navigator.of(context).pop(); }, ) ]));}4.在main中添加测试入口import ‘package:flutter/material.dart’;import ‘package:flutter_tts/voice_set_page.dart’;void main() => runApp(MyApp());class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: ‘Flutter Demo’, theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(title: ‘Flutter Demo Home Page’), ); }}class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => _MyHomePageState();}class _MyHomePageState extends State<MyHomePage> { void _incrementCounter() { Navigator.push(context, MaterialPageRoute(builder: (context) => VoiceSetPage(title: “Setting”))); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( ‘点击浮动按钮跳转到语音测试页’, ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, tooltip: ‘跳转’, child: Icon(Icons.add), ), // This trailing comma makes auto-formatting nicer for build methods. ); }}测试可用,希望能帮助到你。请支持原文:http://tryenough.com/flutter-tts完成demo下载地址:http://tryenough.com/flutter-tts ...

April 4, 2019 · 4 min · jiezi

小程序--语音合成tts 对接多平台(讯飞,思必驰,百度)

小程序功能特点文本转语音多平台多发音人可选可调语速可提供音频下载良心产品无广告????小程序码已对接在线语音识别服务思必驰dui平台 (超过40个免费可选发音人)讯飞开放平台 (5个免费可选发音人)百度语音(4个免费发音人可选)小程序截图服务端主要代码class TTSController extends Controller { async tts () { let params = this.ctx.query let result = null // 根据plat参数来调用不同的接口 if (params.plat === ‘xf’) { result = await this.ctx.service.xftts.getTts(params) } else if (params.plat === ‘baidu’) { result = await this.ctx.service.baidutts.getTts(params) } else { result = await this.ctx.service.aispeechtts.getTts(params) } // 设置response的类型,这样客户端接收到的就是一个文件流 this.ctx.response.type = ‘audio/mpeg’ this.ctx.body = result }}小程序客户端template代码(使用的mpvue)<template> <div class=“container”> <div class=“preview”> <textarea :class=“textAreaFocus? ‘focus’ : ‘’” auto-height @focus=“bindTextAreaFocus” @blur=“bindTextAreaBlur” placeholder=“请输入文本” v-model=“text” maxlength=“256”/> </div> <div class=“setting”> <picker @change=“bindPlatChange” v-model=“platIndex” range-key=“name” :range=“platArr”> <div class=“item”> <div class=“label”>选择平台</div> <div class=“value voice”> {{platArr[platIndex].name}} </div> </div> </picker> <picker @change=“bindPickerChange” v-model=“index” range-key=“name” :range=“array”> <div class=“item”> <div class=“label”>选择发音人</div> <div class=“value voice”> {{array[index].name}} </div> </div> </picker> <div class=“item speed”> <div class=“label”>调节语速</div> <div class=“value”> <slider @change=“onSpeedChange” :value=“speedObj.default” :step=‘speedObj.step’ activeColor="#6F8FFF" :min=“speedObj.min” :max=“speedObj.max” show-value /> </div> </div> </div> <div style=“height: 140rpx;"> <div class=“btn-group”> <div class=“item”><button @click=“audioPlay” type=“main”>播放合成语音</button> </div> <div class=“item”> <button @click=“audioDownload” type=“submain”>复制链接下载</button> </div> </div> </div> <div class=“desc”> 说明:tts是英文 text to speech的缩写,即文本转语音技术 <contact-button type=“default-light” session-from=“weapp”>联系客服 </contact-button> </div> </div></template>script 代码<script>import voiceIdArray from ‘./voiceIdArray’export default { data () { return { array: voiceIdArray.aispeech, platArr: [{id: ‘xf’, name: ‘科大讯飞’}, {id: ‘aispeech’, name: ‘思必驰’}, {id: ‘baidu’, name: ‘百度’}], platIndex: 1, index: 26, text: 改革春风吹满地,吹满地,春风吹满地。\n中国人民真争气,真争气,人民真争气。\n这个世界太疯狂,耗子都给猫当伴娘。\n齐德隆,齐东强。\n齐德隆的咚得隆咚锵。, voiceId: ’lili1f_diantai’, speed: 1, textAreaFocus: false, audioCtx: null, ttsServer: ‘https://tts.server.com’, audioSrc: ‘’, downloadUrl: ‘’, xfSpeedObj: { min: 0, max: 100, default: 50, step: 1 }, aispeechSpeedObj: { min: 0.7, max: 2, default: 1, step: 0.1 }, baiduSpeedObj: { min: 0, max: 9, default: 5, step: 1 }, speedObj: {} } }, watch: { platIndex (newVal, oldVal) { if (newVal === 2) { this.array = voiceIdArray.baidu this.index = 0 this.speedObj = this.baiduSpeedObj } if (newVal === 1) { this.array = voiceIdArray.aispeech this.index = 26 this.speedObj = this.aispeechSpeedObj } if (newVal === 0) { this.array = voiceIdArray.xf this.index = 0 this.speedObj = this.xfSpeedObj } } }, onShareAppMessage () { return { title: ‘文本转语音服务,多发音人可选’ } }, methods: { onSpeedChange (e) { this.speedObj.default = e.target.value }, bindPlatChange (e) { this.platIndex = e.target.value * 1 }, bindPickerChange (e) { this.index = e.target.value }, getAudioSrc () { if (this.text === ‘’) { return false } const speed = this.speedObj.default const voiceId = this.array[this.index].id const plat = this.platArr[this.platIndex].id return encodeURI(${this.ttsServer}/tts?plat=${plat}&amp;voiceId=${voiceId}&amp;speed=${speed}&amp;text=${this.text}) }, getDownloadUrl () { const plat = this.platArr[this.platIndex].id const voiceId = this.array[this.index].id wx.showLoading({ title: ‘加载中’ }) wx.request({ url: ‘https://tts.server.com/getdownloadurl', data: { plat: plat, voiceId: voiceId, speed: this.speedObj.default, text: this.text }, header: { ‘content-type’: ‘application/json’ // 默认值 }, success (res) { wx.hideLoading() wx.setClipboardData({ data: res.data.short_url, success (res) { wx.showToast({ title: ‘链接已复制请用浏览器下载(ios端无法下载)’, icon: ’none’, duration: 3000 }) } }) } }) }, audioPlay () { this.audioCtx.src = this.getAudioSrc() if (!this.audioCtx.src) { wx.showToast({ title: ‘请先输入文本’, icon: ’none’, duration: 2000 }) return false } wx.showLoading({ title: ‘加载中’ }) this.audioCtx.play() }, audioDownload () { this.getDownloadUrl() }, bindTextAreaBlur (e) { this.textAreaFocus = false this.text = e.target.value }, bindTextAreaFocus () { this.textAreaFocus = true } }, created () { this.speedObj = this.aispeechSpeedObj }, mounted () { this.audioCtx = wx.createInnerAudioContext() this.audioCtx.onEnded((res) => { wx.hideLoading() }) this.audioCtx.onPlay((res) => { wx.hideLoading() }) wx.showShareMenu({ withShareTicket: true }) }}</script>接口对接过程中,百度的是最方便的因为有sdk可以直接使用,讯飞的最麻烦需要自己做参数加密,思必驰dui的虽然没提供SDK但是文档写的比较详细对接过程也很方便快速。目前无法解决的就是,小程序内无法直接下载的问题,只能提供链接,然后用户自己打开浏览器进行下载(iPhone似乎无解)。 ...

January 21, 2019 · 3 min · jiezi