关于java:华为语音合成服务为用户提供实时可替换多音调的语音播放体验

11次阅读

共计 5826 个字符,预计需要花费 15 分钟才能阅读完成。

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

语音合成,助力及时性内容送达

语音合成服务反对在线将文字信息转换为语音输入,已在寰球部署。该服务的劣势有——

  • 多语言、多音色:反对中文、英语、法语、西班牙语、德语、意大利语、俄语、波兰语、泰语、马来语语音合成,更有 2 种规范男声发音、6 种规范女声发音可供选择。
  • 语速、音量可调节:反对多种参数配置,可依据场景需要对发音人的语速、音量进行调整。
  • 集成形式灵便丰盛:提供离线 SDK、在线 SDK 疾速集成,充沛满足不同场景下的语音合成需要。

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

在智能硬件畛域,语音合成服务则能够集成到儿童故事机、智能机器人、平板设施等智能设施上,使人机交互更加天然、亲切。对于短视频 App 的内容创作者来说,在视频利用中指定文字就能够合成一些语音成果,放慢了短视频制作流程。

定制音色,满足用户个性化需要

近期,华为语音合成服务行将上线定制音色性能。用户能够录制并合成本人的声音到利用中,让素日里听小说、导航等生存学习场景更加乏味、亲切。家里有小朋友的父母还能够用本人的声音给孩子们讲故事,开释育儿疲劳的同时加深亲子互动陪伴。

开发实战

开发筹备
Maven 仓和 SDK 的配置步骤能够参考开发者网站中的利用开发介绍:
https://developer.huawei.com/…

  1. 配置集成的 SDK 包

     在利用的 build.gradle 文件中,dependencies 内增加 TTS 的 SDK 依赖:// 引入根底 SDK
    implementation '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'
  2. 配置 AndroidManifest.xml

     关上 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" />
  3. 代码开发(在线 TTS)

3.1 创立利用自定义的 activity 界面,用于抉择在线或者离线 TTS,并通过 api_key 或者 Access Token 设置利用鉴权信息

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 引擎,能够依据须要配置不同参数

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 回调,接管解决语音合成的后果

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 合成申请,及播放管制

String id = mlTtsEngine.speak(text, MLTtsEngine.QUEUE_APPEND));

mlTtsEngine.pause();
mlTtsEngine.resume();
mlTtsEngine.stop();

调用结束后,开释引擎
if (mlTtsEngine != null) {mlTtsEngine.stop();
    mlTtsEngine.shutdown();}
  1. 离线 TTS

4.1 离线性能须要新增下载发音人模型包的步骤

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());
    }
});

下载模型办法为:

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 最新技术资讯~

正文完
 0