android百度语音合成(含离线在线api合成方式,详细步骤+源码)(代码片段)

初学者-Study 初学者-Study     2022-12-11     369

关键词:

声明

  本文代码请使用真机运行,别用模拟器虚拟机,谢谢!

前言

  我之前写过百度的语音识别,也写过讯飞的语音识别与合成,而有读者看完后说没有百度的语音合成,想在用百度语音识别的同时使用百度的语音合成。所以就有了这篇文章,我的文章也是区别于其他人的文章,所以我有自己的风格。

感兴趣可以先扫码下载体验一下,再决定往不往下面看。

正文

  首先我们登录这个百度智能云,然后找到语音技术。

点击创建应用


这里选择包名,如果你选择不需要,则只能通过网络API来实现你的语音合成,而选择Android的话就不光可以使用API还能使用SDK,不过这样的话对APK的大小会有增加。

这里我选择的是Android,因此需要建一个Android项目。

一、创建项目


先把这个com.llw.speechsynthesis包名填进去。

立即创建

查看应用详情。

这几个值在后面会用到的,记下来。然后回到列表中,领取免费的使用额度。


注意看这个提示,说明这个额度是有期限的。

领取之后。

二、离线语音合成

点击左侧的离线合成SDK

选择应用后,点击确定。

可以看到激活的30天内,我是5月6号激活,可能你后面看文章的时候就已经是不能用了,所以不要拿到源码之后问我为什么用不了,那只能说明你没有看文章。

这里看这个是单台设备授权,所以你想要增多的话就要花钱了,点击下载SDK。

注意这个还要激活SDK才行的。激活是需要序列号的,那么这个序列号那里来呢?点击查看详情

下载序列号列表,下载后打开如下

现在这序列号就有了,下面回到

下载这个SDK

下载后解压,下面正式来配置这个离线的语音合成了。

1. 配置AndroidManifest.xml

打开项目的AndroidManifest.xml,添加权限。

	<uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />

然后适配api 28以上版本。

		<!--支持api level 28 以上编译-->
        <uses-library
            android:name="org.apache.http.legacy"
            android:required="false" />

添加位置如下图。

2. 配置SDK

打开刚才的SDK,进入到libs文件夹下

将这个jar包复制到你的项目的libs下。

注意到它这个现在是没有展开的,说明还没有加载进去,点击工具栏右上方的小象图标进行项目资源同步。

同步后的你的jar就加载到项目中了,就是可以展开的。

进入到main文件夹下

复制assets和jniLibs这两个文件夹到你的项目的main下面。

然后展开你的assets文件夹,打开auth.properties文件。修改里面的一些内容。

这里面的五个值都需要进行修改,前三个值是我们在创建平台应用时生成的,我当时说了你要记下来,就是为了这里使用。那么你只要一一的对应填写替换就可以了,而applicationId:就是我们之前填写的包名,最后的sn:就是下载的序列号,有两个,任意一个都可以。那么将上面的数据改了之后如下所示:

3. 离线SDK初始化

离线SDK第一次初始化的时候需要联网,进行网络鉴权,鉴权成功之后就可以断网使用了,先完成这个初始化操作。修activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <Button
        android:text="离线SDK合成"
        android:onClick="offlineSDK"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

然后在MainActivity中写入一个方法:

	/**
     * 离线SDK合成
     * @param view
     */
    public void offlineSDK(View view) 

    

当点击这个方法时会进入到离线SDK的页面,这个页面现在还没有的,不过我们的下载SDK里面有现成的,那就拿过来就用好了。

首先将layout下的activity_synth.xml文件复制到项目的layout下。


然后将res文件夹下的raw文件夹复制到你的项目的res下:


然后就是里面的一些配置类了。
将sample包下的选择的文件和文件夹复制到你的项目的包下。

4. 导包

然后依次打开里面的粘贴过来的类,首先是control包下的InitConfig类,里面是会有报错的,因为包名不一致。所以需要重新导包。

点击import左边的加号或者右边的省略号查看里面的导包信息

看到这里是报红的。删掉我标注的这一行错误的导包信息。然后往下滑动,到下方你点击报红的这个类,会出现一个提示如下图所示:可以通过快捷键Alt + Enter快速导包

导包之后这个类就不报错了,就能正常使用了

那么你刚才复制过来的类都需要重新打开一次,看看里面的包是否有异常,有的话就按刚才的方法来解决就好了。当你把所有的类检查一遍之后,确保都没有异常之后,就可以开始进行这个初始化了。

修改MainActivity中的代码

	/**
     * 离线SDK合成
     * @param view
     */
    public void offlineSDK(View view) 
        startActivity(new Intent(this,SynthActivity.class));
    

点击这个按钮跳转到SynthActivity中。别忘了要在AndroidManifest.xml中注册这个Activity。

5. 运行

下面运行一下:


是有声音的,不过这是GIF图,所以你只能看到我的演示效果。那么到此为止,这个离线合成就弄完了,具体的细节你要多看这个SDK的代码,我个人觉得代码太多了,有些乱。

三、在线语音合成 - SDK方式

1. 创建页面

在线合成的方式其实和离线差不了多少,在com.llw.speechsynthesis包下新建一个OnlineActivity,布局是activity_online.xml,布局代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="50dp"
        android:orientation="horizontal"
        android:weightSum="3">

        <Button
            android:id="@+id/speak"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_weight="1"
            android:lines="2"
            android:text="合成并播放"
            android:textSize="12dp" />

        <Button
            android:id="@+id/stop"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_weight="2"
            android:lines="2"
            android:text="停止合成引擎"
            android:textSize="12dp" />

    </LinearLayout>

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/btn"
        >

        <TextView
            android:id="@+id/showText"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="10dp"
            android:background="@android:color/darker_gray"
            android:minLines="3"
            android:scrollbars="vertical" />
    </ScrollView>

</LinearLayout>

下面再来看OnlineActivity的代码

2. 编辑代码

package com.llw.speechsynthesis;

import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.baidu.tts.chainofresponsibility.logger.LoggerProxy;
import com.baidu.tts.client.SpeechSynthesizer;
import com.baidu.tts.client.SpeechSynthesizerListener;
import com.baidu.tts.client.TtsMode;
import com.llw.speechsynthesis.control.InitConfig;
import com.llw.speechsynthesis.listener.UiMessageListener;
import com.llw.speechsynthesis.util.Auth;
import com.llw.speechsynthesis.util.AutoCheck;
import com.llw.speechsynthesis.util.FileUtil;
import com.llw.speechsynthesis.util.IOfflineResourceConst;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * 除了SDK,该类没有任何依赖,可以直接复制进你的项目
 * <p>
 * 默认TEMP_DIR = "/sdcard/baiduTTS"; // 重要!请手动将assets目录下的3个dat 文件复制到该目录
 * 确保 TEXT_FILENAME 和 MODEL_FILENAME 存在
 * Created by fujiayi on 2017/9/14.
 */

public class OnlineActivity extends AppCompatActivity implements IOfflineResourceConst 

    /**
     * 要合成的文本,可以自行改动。
     */
    private static final String TEXT = "欢迎使用百度语音合成,请在代码中修改合成文本";

    protected String appId;

    protected String appKey;

    protected String secretKey;

    protected String sn; // 纯离线合成SDK授权码;离在线合成SDK没有此参数

    //TtsMode.ONLINE 纯在线
    private TtsMode ttsMode = TtsMode.ONLINE;

    private boolean isOnlineSDK = TtsMode.ONLINE.equals(DEFAULT_SDK_TTS_MODE);
    // ================ 纯离线sdk或者选择TtsMode.ONLINE  以下参数无用;
    private static final String TEMP_DIR = "/sdcard/baiduTTS"; // 重要!请手动将assets目录下的3个dat 文件复制到该目录

    // 请确保该PATH下有这个文件
    private static final String TEXT_FILENAME = TEMP_DIR + "/" + TEXT_MODEL;

    // 请确保该PATH下有这个文件 ,m15是离线男声
    private static final String MODEL_FILENAME = TEMP_DIR + "/" + VOICE_MALE_MODEL;

    // ===============初始化参数设置完毕,更多合成参数请至getParams()方法中设置 =================

    protected SpeechSynthesizer mSpeechSynthesizer;

    // =========== 以下为UI部分 ==================================================

    private TextView mShowText;

    protected Handler mainHandler;

    private String desc; // 说明文件


    private static final String TAG = "MiniActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        appId = Auth.getInstance(this).getAppId();
        appKey = Auth.getInstance(this).getAppKey();
        secretKey = Auth.getInstance(this).getSecretKey();
        sn = Auth.getInstance(this).getSn(); // 纯离线合成必须有此参数;离在线合成SDK没有此参数
        desc = FileUtil.getResourceText(this, R.raw.mini_activity_description);
        setContentView(R.layout.activity_online);
        initView();
        initPermission();
        initTTs();
    

    /**
     * 注意此处为了说明流程,故意在UI线程中调用。
     * 实际集成中,该方法一定在新线程中调用,并且该线程不能结束。具体可以参考NonBlockSyntherizer的写法
     */
    private void initTTs() 
        LoggerProxy.printable(true); // 日志打印在logcat中
        boolean isSuccess;
        if (!isOnlineSDK) 
            // 检查2个离线资源是否可读
            isSuccess = checkOfflineResources();
            if (!isSuccess) 
                return;
             else 
                print("离线资源存在并且可读, 目录:" + TEMP_DIR);
            
        
        // 日志更新在UI中,可以换成MessageListener,在logcat中查看日志
        SpeechSynthesizerListener listener = new UiMessageListener(mainHandler);

        // 1. 获取实例
        mSpeechSynthesizer = SpeechSynthesizer.getInstance();
        mSpeechSynthesizer.setContext(this);

        // 2. 设置listener
        mSpeechSynthesizer.setSpeechSynthesizerListener(listener);

        // 3. 设置appId,appKey.secretKey
        int result = mSpeechSynthesizer.setAppId(appId);
        checkResult(result, "setAppId");
        result = mSpeechSynthesizer.setApiKey(appKey, secretKey);
        checkResult(result, "setApiKey");

        // 4. 如果是纯离线SDK需要离线功能的话
        if (!isOnlineSDK) 
            // 文本模型文件路径 (离线引擎使用), 注意TEXT_FILENAME必须存在并且可读
            mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_TTS_TEXT_MODEL_FILE, TEXT_FILENAME);
            // 声学模型文件路径 (离线引擎使用), 注意TEXT_FILENAME必须存在并且可读
            mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_TTS_SPEECH_MODEL_FILE, MODEL_FILENAME);

            mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_MIX_MODE, SpeechSynthesizer.MIX_MODE_DEFAULT);
            // 该参数设置为TtsMode.MIX生效。
            // MIX_MODE_DEFAULT 默认 ,wifi状态下使用在线,非wifi离线。在线状态下,请求超时6s自动转离线
            // MIX_MODE_HIGH_SPEED_SYNTHESIZE_WIFI wifi状态下使用在线,非wifi离线。在线状态下, 请求超时1.2s自动转离线
            // MIX_MODE_HIGH_SPEED_NETWORK , 3G 4G wifi状态下使用在线,其它状态离线。在线状态下,请求超时1.2s自动转离线
            // MIX_MODE_HIGH_SPEED_SYNTHESIZE, 2G 3G 4G wifi状态下使用在线,其它状态离线。在线状态下,请求超时1.2s自动转离线



        

        // 5. 以下setParam 参数选填。不填写则默认值生效
        // 设置在线发声音人: 0 普通女声(默认) 1 普通男声  3 情感男声<度逍遥> 4 情感儿童声<度丫丫>
        mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEAKER, "0");
        // 设置合成的音量,0-15 ,默认 5
        mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_VOLUME, "9");
        // 设置合成的语速,0-15 ,默认 5
        mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEED, "5");
        // 设置合成的语调,0-15 ,默认 5
        mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_PITCH, "5");

        // mSpeechSynthesizer.setAudioStreamType(AudioManager.MODE_IN_CALL); // 调整音频输出

        if (sn != null) 
            // 纯离线sdk这个参数必填;离在线sdk没有此参数
            mSpeechSynthesizer.setParam(PARAM_SN_NAME, sn);
        

        // x. 额外 : 自动so文件是否复制正确及上面设置的参数
        Map<String, String> params = new HashMap<>();
        // 复制下上面的 mSpeechSynthesizer.setParam参数
        // 上线时请删除AutoCheck的调用
        if (!isOnlineSDK) 
            params.put(SpeechSynthesizer.PARAM_TTS_TEXT_MODEL_FILE, TEXT_FILENAME);
            params.put(SpeechSynthesizer.PARAM_TTS_SPEECH_MODEL_FILE, MODEL_FILENAME);
        

        // 检测参数,通过一次后可以去除,出问题再打开debug
        InitConfig initConfig = new InitConfig(appId, appKey, secretKey, ttsMode, params, listener);
        AutoCheck.getInstance(getApplicationContext()).check(initConfig, new Handler() 
            @Override
            /**
             * 开新线程检查,成功后回调
             */
            public void handleMessage(Message msg) 
                if (msg.what == 100) 
                    AutoCheck autoCheck = (AutoCheck) msg.obj;
                    synchronized (autoCheck) 
                        String message = autoCheck.obtainDebugMessage();
                        print(message); // 可以用下面一行替代,在logcat中查看代码
                        // Log.w("AutoCheckMessage", message);
                    
                
            

        );

        // 6. 初始化
        result = mSpeechSynthesizer.initTts(ttsMode);
        checkResult(result, "initTts");

    

    /**
     * 在线SDK不需要调用,纯离线SDK会检查资源文件
     *
     * 检查 TEXT_FILENAME, MODEL_FILENAME 这2个文件是否存在,不存在请自行从assets目录里手动复制
     *
     * @return 检测是否成功
     */
    private boolean checkOfflineResources() 
        String[] filenames = TEXT_FILENAME, MODEL_FILENAME;
        for (String path : filenames) 
            File f = new 查看详情  

myeclipseci2019.4完美激活版(含离线包+激活工具+安装教程)

资金允许,请支持正版ps:MyEclipse目前已更新至2020.5.18,但是目前还没有有效的激活方式,本次文章以2019.4为例;该文章使用离线安装的方式进行安装,在线安装不保证不会出现各类小问题,离线安装包及激活工具在文末获取;该... 查看详情

iosapp处于后台/被杀死的状态仍可进行语言播报的实现方案(离线合成+serviceextension)

...und属性即可使通知播报一段自定义的收款到账语音。讯飞百度腾讯离线合成服务都是需要收费的采用在线合成再通过http下载的方式,讯飞和微信都有提供免费的服务。这个方案的缺点是依赖后台和当前的网络环境,有可能会导... 查看详情

在线将文字转成语音的方法都有哪些?

...购买完整版。另外一种方法就是使用在线的文字转语音,百度的在线文字转语音就特别好用。我们直接打开百度,在百度里输入文字在线转语音,然后点击百度一下。在搜索的结果中找,找到到百度的语音合成,点击进入后,点... 查看详情

百度语音合成api/sdk及demo(代码片段)

1、流程  1)换取token    用ApiKey和SecretKey。访问https://openapi.baidu.com/oauth/2.0/token换取token   //appKey=Va5yQRHl********LT0vuXV4//appSecret=0rDSjzQ20XUj5i********PQSzr5pVw2https://openapi.baidu.com/oauth/2 查看详情

iosapp处于后台/被杀死的状态仍可进行语言播报的实现方案

...und属性即可使通知播报一段自定义的收款到账语音。讯飞百度腾讯离线合成服务都是需要收费的采用在线合成再通过http下载的方式,讯飞和微信都有提供免费的服务。这个方案的缺点是依赖后台和当前的网络环境,有可能会导... 查看详情

androidtexttospeechtts中文文本转语音(语音合成)(代码片段)

简介TTS即从文本到语音(TextToSpeech)一,使用第三方提供的SDK或者API,例如:科大讯飞,百度,阿里等;二,使用Android系统自带的API:TextToSpeechTextToSpeech中的API文档(官方):TextToSpeech | 查看详情

vue实现百度语音合成(语音播报)(代码片段)

这里我完全依照百度提供的语音合成api来做:https://ai.baidu.com/docs#/TTS-Online-Node-SDK/top 直接去看node.jsSDK。1.换取access_token:参考:https://ai.baidu.com/docs#/TTS-API/top,在这里用浏览器换取token2.下载sdk依赖:npminstallbaidu-aip-sdk 完... 查看详情

连载9:用余弦信号合成方波信号

  查看详情

使用url在线语音合成

近期一直在做手机的项目,用到了语音合成与识别的功能。就找了几个网址做了分析,这里只实现了内容的合成。并不包括语音识别。首先看一下谷歌的语音合成地址:http://translate.google.cn/translate_tts?ie=UTF-8&q=这里为语音内容... 查看详情

[wpf学习]15.播放百度合成的语音(代码片段)

...能最简单、最轻量型的方法,但只能播放wav格式的语音。百度在线语音合成可以合成wav格式的语音,保存为本地文件,SoundPlayer出错,仔细看文档发现百度的wav就是pcm-16k(3为mp3格式(默认);4为pcm-16k;5为pcm-8k;6为wav(内容同pcm-16k... 查看详情

[wpf学习]15.播放百度合成的语音(代码片段)

...能最简单、最轻量型的方法,但只能播放wav格式的语音。百度在线语音合成可以合成wav格式的语音,保存为本地文件,SoundPlayer出错,仔细看文档发现百度的wav就是pcm-16k(3为mp3格式(默认);4为pcm-16k;5为pcm-8k;6为wav(内容同pcm-16k... 查看详情

如何开发一个在线朗读的功能----科大讯飞语音合成实战(代码片段)

...来潮,准备继续捡起。起因天天学习强国,不过强国APP的语音朗读不错,了解之后是科大讯飞支持的,于是开始撸码。https://www.xfyun.cn/doc/tts/online_tts/API.html注册为开发者,接口要求这些我就不赘述了,文档里面写的清楚。当然具... 查看详情

falsk基础语音识别与语音合成()(代码片段)

首先搜索http://ai.baidu.com/进入官网。下拉找到百度语音:然后创建一个语音应用:管理应用之后:语音合成:然后新建一个py文件:fromaipimportAipSpeechAPP_ID=‘14454183‘API_KEY=‘txNuGCIsenvEB93I70EsWwB4‘SECRET_KEY=‘dzdok3DcUeUxE28atFgiOQzxVd91BmQu... 查看详情

百度语音合成简单案例(将文字转化为相应的语音)(代码片段)

参考链接:http://ai.baidu.com/docs#/TTS-API/top 1.项目的目录结构2.效果图3核心代码TtsMain.javapackagecom.baidu.speech.restapi.ttsdemo;importcom.baidu.speech.restapi.common.DemoException;importcom.baidu.speech.restapi.common.ConnUtil;importcom.baidu.speech.restapi.common.TokenH... 查看详情

人工智能之语音(代码片段)

以下技术均依靠于百度大佬提供的接口操作!调用接口语言为python一,下载pipinstallbaidu-aip二,语音合成根据百度语言合成官网,调用即可:#!/usr/bin/envpython#-*-coding:utf8-*-fromaipimportAipSpeech"""你的APPIDAKSK"""#注册百度账号之后,创建... 查看详情

人工智能-语音合成-语音识别(代码片段)

  图灵机器人:http://www.tuling123.com 百度开发平台:http://ai.baidu.com/ 下载baidu-api如果已安装pip,执行pipinstallbaidu-aip即可。   ffmpeg  先下载文件,再配置到系统路径下载完安装包,解压后,将该绝对... 查看详情

百度语音合成ai(代码片段)

注意:不要使用Dw编辑PHP代码,会因为编码问题出错!!<?phprequire_once‘AipSpeech.php‘;//你的APPIDAKSKconstAPP_ID=‘112***00‘;constAPI_KEY=‘6EkSeI*****aFV4GjpB2q‘;constSECRET_KEY=‘mSPm*******qayf81XSbYBxu‘;$client=newAipSpeech 查看详情