百度语音合成Demo(纯在线模式)

环境:Android Studio , Mac

第一步:

开通百度语音服务按提示操作即可

第二步

环境配置 
下载SDK和NDK库 
1.com.baidu.tts_x.x.x.xxxxx_xxxxx.jar 位于 app/libs 目录下。(引入jar包)

这里写图片描述

这里写图片描述

2.armeabi,armeabi-v7a,arm64-v8a,x86,x86_64 5个架构目录位于app\src\main\jniLibs 目录下,如果为了节省安装包体积,可以只使用armeabi目录,性能损失微小。(我只保留了armeabi目录)。

第三步:

实现监听器SpeechSynthesizerListener

package com.demo.tts.listener;

import android.util.Log;

import com.baidu.tts.client.SpeechError;
import com.baidu.tts.client.SpeechSynthesizerListener;
/**
 * SpeechSynthesizerListener 简单地实现,仅仅记录日志
 * Created by xiaowen on 2017/5/19.
 */

public class MessageListener implements SpeechSynthesizerListener{
    private static final String TAG = "MessageListener";

    /**
     * 播放开始,每句播放开始都会回调
     *
     * @param utteranceId
     */
    @Override
    public void onSynthesizeStart(String utteranceId) {
        sendMessage("准备开始合成,序列号:" + utteranceId);
    }

    /**
     * 语音流 16K采样率 16bits编码 单声道 。
     *
     * @param utteranceId
     * @param bytes       二进制语音 ,注意可能有空data的情况,可以忽略
     * @param progress    如合成“百度语音问题”这6个字, progress肯定是从0开始,到6结束。 但progress无法和合成到第几个字对应。
     */
    @Override
    public void onSynthesizeDataArrived(String utteranceId, byte[] bytes, int progress) {
        //  Log.i(TAG, "合成进度回调, progress:" + progress + ";序列号:" + utteranceId );
    }

    /**
     * 合成正常结束,每句合成正常结束都会回调,如果过程中出错,则回调onError,不再回调此接口
     *
     * @param utteranceId
     */
    @Override
    public void onSynthesizeFinish(String utteranceId) {
        sendMessage("合成结束回调, 序列号:" + utteranceId);
    }

    @Override
    public void onSpeechStart(String utteranceId) {
        sendMessage("播放开始回调, 序列号:" + utteranceId);
    }

    /**
     * 播放进度回调接口,分多次回调
     *
     * @param utteranceId
     * @param progress    如合成“百度语音问题”这6个字, progress肯定是从0开始,到6结束。 但progress无法保证和合成到第几个字对应。
     */
    @Override
    public void onSpeechProgressChanged(String utteranceId, int progress) {
        //  Log.i(TAG, "播放进度回调, progress:" + progress + ";序列号:" + utteranceId );
    }

    /**
     * 播放正常结束,每句播放正常结束都会回调,如果过程中出错,则回调onError,不再回调此接口
     *
     * @param utteranceId
     */
    @Override
    public void onSpeechFinish(String utteranceId) {
        sendMessage("播放结束回调, 序列号:" + utteranceId);
    }

    /**
     * 当合成或者播放过程中出错时回调此接口
     *
     * @param utteranceId
     * @param speechError 包含错误码和错误信息
     */
    @Override
    public void onError(String utteranceId, SpeechError speechError) {
        sendErrorMessage("错误发生:" + speechError.description + ",错误编码:"
                + speechError.code + ",序列号:" + utteranceId);
    }

    private void sendMessage(String message) {
        sendMessage(message, false);
    }

    private void sendErrorMessage(String message) {
        sendMessage(message, true);
    }

    protected void sendMessage(String message, boolean isError) {
        if (isError) {
            Log.e(TAG, message);
        } else {
            Log.i(TAG, message);
        }

    }
}

 
 
  • 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
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102

第四步:

封装SpeechSynthesizer的操作

package com.demo.tts;

import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.media.AudioManager;
import android.os.Build;
import android.util.Log;

import com.baidu.tts.client.SpeechSynthesizer;
import com.baidu.tts.client.SpeechSynthesizerListener;
import com.baidu.tts.client.TtsMode;
import com.demo.tts.listener.MessageListener;

import java.util.ArrayList;

/**
 * Created by xiaowen on 2017/11/3.
 */

public class Speek {


    // ================== 初始化参数设置开始 ==========================
    /**
     * 发布时请替换成自己申请的appId appKey 和 secretKey。注意如果需要离线合成功能,请在您申请的应用中填写包名。
     */
    private String appId = "10318618";

    private String appKey = "cOvGbUOyDr0gVyML07543vnY";

    private String secretKey = "5280e6434339c695eee267ff373567a4";

    // TtsMode.MIX; 离在线融合,在线优先; TtsMode.ONLINE 纯在线; 没有纯离线
    private TtsMode ttsMode = TtsMode.ONLINE;

    protected SpeechSynthesizer mSpeechSynthesizer;

    private static final String TAG = "Speek";

    private Activity activity;

    private static boolean isPermissionRequested = false;

    public Speek(Activity activity){
        this.activity=activity;
        Permission();
        initTTs();
    }

    public void Speeking(String text){
            int result = mSpeechSynthesizer.speak(text);
            checkResult(result, "speak");
    }

    /**
     * 初始化TTS
     */
    private void initTTs() {
        SpeechSynthesizerListener listener=new MessageListener();
        //获取 SpeechSynthesizer 实例
        mSpeechSynthesizer = SpeechSynthesizer.getInstance();
        //设置使用环境
        mSpeechSynthesizer.setContext(activity);
        //注册监听其
        mSpeechSynthesizer.setSpeechSynthesizerListener(listener);
        /**
         * 授权检验接口
         * 测试AppId,AppKey AppSecret填写正确,语音合成服务是否开通。
         * 在线合成模式下,验证权限。首次验证时比较耗时,第一次调用成功,之后可以不必调用。
         */
        mSpeechSynthesizer.auth(TtsMode.ONLINE);  // 纯在线
        /**
         * 设置 App Id和 App Key 及 App Secret
         * 用户在语音官网或者百度云网站上申请语音合成的应用后,会有appId appKey及appSecret
         */
        int result =  mSpeechSynthesizer.setAppId(appId);
        checkResult(result, "setAppId");
        result = mSpeechSynthesizer.setApiKey(appKey, secretKey);
        checkResult(result, "setApiKey");

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

        //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自动转离线

        /**
         * 初始化合成引擎
         * 设置合成的参数后,需要调用此方法初始化
         */
        result = mSpeechSynthesizer.initTts(ttsMode);
        checkResult(result, "initTts");

        //设置音频流类型
        mSpeechSynthesizer.setAudioStreamType(AudioManager.MODE_IN_CALL);


    }

    /**
     * 获取权限(Android6.0 以上需要动态获取权限)
     */
    private void Permission() {
        if (Build.VERSION.SDK_INT >= 23 && !isPermissionRequested) {

            String permissions[] = {
                    Manifest.permission.INTERNET,
                    Manifest.permission.ACCESS_NETWORK_STATE,
                    Manifest.permission.MODIFY_AUDIO_SETTINGS,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    Manifest.permission.WRITE_SETTINGS,
                    Manifest.permission.READ_PHONE_STATE,
                    Manifest.permission.ACCESS_WIFI_STATE,
                    Manifest.permission.CHANGE_WIFI_STATE
            };

            ArrayList<String> toApplyList = new ArrayList<String>();

            for (String perm : permissions) {
                if (PackageManager.PERMISSION_GRANTED != activity.checkSelfPermission(perm)) {
                    toApplyList.add(perm);
                    //进入到这里代表没有权限.
                }
            }
            if(toApplyList.size()==0)
            {
                return;
            }
            else
            {
                activity.requestPermissions(toApplyList.toArray(new String[toApplyList.size()]), 0);
            }
        }
    }

    private void print(String message) {
        Log.i(TAG, message);
    }
    private void checkResult(int result, String method) {
        if (result != 0) {
            print("error code :" + result + " method:" + method + ", 错误码文档:http://yuyin.baidu.com/docs/tts/122 ");
        }
    }
    public void Destory(){
        if (mSpeechSynthesizer != null){
            mSpeechSynthesizer.stop();
            mSpeechSynthesizer.release();
            mSpeechSynthesizer = null;
            print("释放资源成功");
        }
    }
}
 
 
  • 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
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161

测试Activity

package com.demo.map;

import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import com.demo.tts.Speek;

/**
 * Created by xiaowen on 2017/11/5.
 */

public class TTsActivity extends Activity {

    private Button mBtnPlay;
    private EditText mEdtWords;
    private Speek speek;
    private String words;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tts);
        speek=new Speek(this);
        initView();
    }
    private void initView(){
        mBtnPlay= (Button) findViewById(R.id.play);
        mEdtWords= (EditText) findViewById(R.id.words);

        mBtnPlay.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                words=mEdtWords.getText().toString();
                if(!words.equals(""))
                {
                    speek.Speeking(words);
                }
                else
                {
                    speek.Speeking("请告诉我,您需要我说些什么");
                }
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //释放资源
        speek.Destory();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值