在不能操作手机或总盯着手机看的情况下,如何及时获取资讯信息、方便阅读呢?用耳朵听不失为一种好方法。华为机器学习服务的语音合成服务,采用深度神经网络技术,提供高度拟人、流畅自然的语音合成服务。开发者可以在小说阅读、智能硬件、地图导航类应用中集成该能力,为用户提供实时、可替换、多音调的语音播放体验。

语音合成,助力及时性内容送达
语音合成服务支持在线将文字信息转换为语音输出,已在全球部署。该服务的优势有——
多语言、多音色:支持中文、英文、中英文混读合成,更有2种标准男声发音、6种标准女声发音可供选择。以下为音色试听:
语速、音量可调节:支持多种参数配置,可根据场景需求对发音人的语速、音量进行调整。
集成方式灵活丰富:提供离线SDK、在线SDK快速集成,充分满足不同场景下的语音合成需求。

语音合成服务可以应用于阅读播报、新闻播报、虚拟播报、地图播报、信息通知等及时性较强的场景。比如,用户在骑车、驾车使用地图导航时,路上不方便一直看手机。语音合成广播可以保证表达清晰,准确到达目的地;在司机端打车软件、餐饮叫号、排队软件等场景下,通过语音合成进行订单播报,让用户便捷获取通知信息;市场上很火的电子阅读类应用,提供语音播报和收听功能。用户可以很容易地实现“听书”。即使在锁屏状态下,也可以通过语音播报继续收听,消除地铁、公交、跑步等阅读环境的限制。一些不方便阅读的老人和小孩,同样可以通过“听书”,解决看不清、情绪陪伴等问题。

在智能硬件领域,语音合成服务则可以集成到儿童故事机、智能机器人、平板设备等智能设备上,使人机交互更加自然、亲切。对于短视频App的内容创作者来说,在视频应用中指定文字就可以合成一些语音效果,加快了短视频制作流程。
定制音色,满足用户个性化需求
近期,华为语音合成服务即将上线定制音色功能。用户可以录制并合成自己的声音到应用中,让平日里听小说、导航等生活学习场景更加有趣、亲切。家里有小朋友的父母还可以用自己的声音给孩子们讲故事,释放育儿疲劳的同时加深亲子互动陪伴。
开发准备
Maven仓和SDK的配置步骤可以参考开发者网站中的应用开发介绍:
d1dK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6V1k6i4k6W2L8r3!0H3k6i4u0Q4x3X3g2Z5N6h3q4%4k6h3W2Q4x3X3g2U0L8$3#2Q4x3V1k6U0L8$3&6K6N6h3#2W2M7W2)9J5c8X3y4F1i4K6u0r3k6r3!0U0i4K6u0r3k6r3g2$3k6h3I4G2M7r3#2W2L8Y4c8Q4x3V1k6Z5K9h3q4A6i4K6u0V1c8%4g2A6k6r3g2K6i4K6u0r3L8h3I4Q4x3X3c8@1N6s2y4Q4x3X3b7H3x3o6l9H3x3o6l9I4x3o6f1H3x3o6j5^5x3e0j5&6i4K6y4r3K9r3q4Q4y4h3k6K6L8%4g2J5j5$3g2Q4x3@1c8Z5L8i4x3I4
配置集成的SDK包
1 2 3 4 5 6 7 | 在应用的build.gradle文件中,dependencies内添加TTS的SDK依赖:// 引入基础SDKimplementation 'com.huawei.hms:ml-computer-voice-tts:3.3.0.274'// 引入离线语音合成bee语音包implementation 'com.huawei.hms:ml-computer-voice-tts-model-bee:3.3.0.274'// 引入离线语音合成eagle语音包implementation 'com.huawei.hms:ml-computer-voice-tts-model-eagle:3.3.0.274' |
配置AndroidManifest.xml
1 2 3 4 | 打开main文件夹中的AndroidManifest.xml文件,可以根据场景和使用需要,配置网络和读写权限,在<application>前添加<uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> |
代码开发(在线TTS)
3.1创建应用自定义的activity界面,用于选择在线或者离线TTS,并通过api_key或者Access Token设置应用鉴权信息
1 2 3 4 5 6 7 | public class MainActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); MLApplication.getInstance().setAccessToken("your access token");}} |
3.2 创建TTS配置及TTS 引擎,可以根据需要配置不同参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | MLTtsEngine mlTtsEngine;MLTtsConfig mlConfigs;mlConfigs = new MLTtsConfig() // Setting the language for synthesis. .setLanguage(MLTtsConstants.TTS_ZH_HANS) // Set the timbre. .setPerson(MLTtsConstants.TTS_SPEAKER_FEMALE_ZH) // Set the speech speed. Range: 0.2–4.0 1.0 indicates 1x speed. .setSpeed(1.0f) // Set the volume. Range: 0.2–4.0 1.0 indicates 1x volume. .setVolume(1.0f) // set the synthesis mode. .setSynthesizeMode(MLTtsConstants.TTS_ONLINE_MODE);mlTtsEngine = new MLTtsEngine(mlConfigs);//Sets the volume of the built-in player.mlTtsEngine.setPlayerVolume(20);设置回调(回调见3.3)// Pass the TTS callback to the TTS engine.mlTtsEngine.setTtsCallback(callback); |
3.3 配置TTS回调,接收处理语音合成的结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | MLTtsCallback callback = new MLTtsCallback() { String task = ""; String fileName = "audio_" + task; @Override public void onError(String taskId, MLTtsError err) { String str = taskId + " " + err; sendMsg(str); } @Override public void onWarn(String taskId, MLTtsWarn warn) { String str = taskId + " 提示:" + warn; sendMsg(str); } @Override public void onRangeStart(String taskId, int start, int end) { String str = taskId + " onRangeStart [" + start + "," + end + "]";// + temp.get(taskId).substring(start); sendMsg(taskId + " onRangeStart[" + start + "," + end + "]"); sendMsg1(taskId, start, end); } @Override public void onAudioAvailable(String taskId, MLTtsAudioFragment audioFragment, int offset, Pair<Integer, Integer> range, Bundle bundle) { if (!task.equals(taskId)) { task = taskId; fileName = "/sdcard/audio_" + task + ".pcm"; } writeTxtToFile(audioFragment.getAudioData(), fileName, true); } @Override public void onEvent(String taskId, int eventId, Bundle bundle) { StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append(taskId + " "); switch (eventId) { case MLTtsConstants.EVENT_PLAY_START: stringBuffer.append("onPlayStart "); break; case MLTtsConstants.EVENT_PLAY_STOP: stringBuffer.append("onPlayStop "); stringBuffer.append(bundle.getBoolean(MLTtsConstants.EVENT_PLAY_STOP_INTERRUPTED)); break; case MLTtsConstants.EVENT_PLAY_RESUME: stringBuffer.append("onPlayResume "); break; case MLTtsConstants.EVENT_PLAY_PAUSE: stringBuffer.append("onPlayPause "); break; case MLTtsConstants.EVENT_SYNTHESIS_COMPLETE: stringBuffer.append("onSynthesisComplete "); PCMCovWavUtil.convertWaveFile(fileName); break; case MLTtsConstants.EVENT_SYNTHESIS_START: stringBuffer.append("onSynthesisStart "); break; case MLTtsConstants.EVENT_SYNTHESIS_END: stringBuffer.append("onSynthesisEnd "); break; } Log.d(TAG, "onEvent: " + stringBuffer.toString()); }}; |
3.4 调用speak合成请求,及播放控制
1 2 3 4 5 6 7 8 9 10 11 | String id = mlTtsEngine.speak(text, MLTtsEngine.QUEUE_APPEND));mlTtsEngine.pause();mlTtsEngine.resume();mlTtsEngine.stop();调用完毕后,释放引擎if (mlTtsEngine != null) { mlTtsEngine.stop(); mlTtsEngine.shutdown();} |
4.1 离线功能需要新增下载发音人模型包的步骤
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | private MLLocalModelManager mLocalModelManager;mLocalModelManager = MLLocalModelManager.getInstance();MLTtsLocalModel mLocalModel = new MLTtsLocalModel.Factory('发音人').create();mLocalModelManager.isModelExist(mLocalModel).addOnSuccessListener(new OnSuccessListener<Boolean>() { @Override public void onSuccess(Boolean aBoolean) { if (aBoolean) { mlTtsEngine.speak(text, MLTtsEngine.QUEUE_APPEND) } else { downloadModel(true); } }}).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { Log.e(TAG, e.getMessage()); }}); |
下载模型方法为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | private void downloadModel(final boolean needSpeak) { MLModelDownloadStrategy request = new MLModelDownloadStrategy.Factory().needWifi().create(); MLModelDownloadListener modelDownloadListener = new MLModelDownloadListener() { @Override public void onProcess(long alreadyDownLength, long totalLength) { showProcess(alreadyDownLength, "Model download is complete", totalLength); } }; mLocalModelManager.downloadModel(mLocalModel, request, modelDownloadListener) .addOnSuccessListener(new OnSuccessListener<Void>() { @Override public void onSuccess(Void aVoid) { Log.i(TAG, "downloadModel: " + mLocalModel.getModelName() + " success"); showToast("downloadModel Success"); updateconfig(); if (needSpeak) { speak(); } } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { Log.e(TAG, "downloadModel failed: " + e.getMessage()); showToast(e.getMessage()); } });} |
其他使用和在线TTS一致
了解更多详情>>
访问华为开发者联盟官网
获取开发指导文档
华为移动服务开源仓库地址:GitHub、Gitee
关注我们,第一时间了解 HMS Core 最新技术资讯~