android studio集成百度语音合成

 离开老师的指导有一段时间了,每天都会给自己找点事情做,或则简单的安排计划一下,收货不多不少刚刚好。
 这是2017年的第一篇比较正式的博客,也算是我在CSDN上的第一次吧!哈哈。今天记录的是最近在集成百度语音上的一些步骤和小部分总结。最开始准备使用讯飞语音的,然而在下载集成后多次测试都没有反应,感觉是哪儿出现了问题,并且讯飞语音在语音唤醒上面也有限制,最后无意间发现了百度语音,就尝试着试试,当然目前只完成了语音合成部分,接下来当然会去玩玩语音识别和唤醒咯。

步骤如下:

  1. Android Studio新建一个Mudule,比如我的:MyTest_AutoAnswer,你可以随意叫啥名。
  2. 登录网址百度语音开发者平台注册账号并创建应用。http://yuyin.baidu.com/ 。
  3. 进入离线下载资源,先开通服务,再下载。我这里仅仅下载的为语音合成部分的离在线融合SDK–安卓版本。
  4. 进入应用管理在该项目的右边点开管理包名,并在应用包名处输入android Studio中创建的应用包名,比如我的为:com.bk120.mytest_autoanswer。保存修改。此处可以不用下载什么临时授权文件,我就没下载因为你已经把包名都填上了。
  5. 同理点击查看Key,查看当前应用的所需的主要三个参数 AppId APIKey SecretKey,后面会用得到。
  6. 将我们前面几步中下载的SDk解压,为如下目录结构:
     BaiduTtsSample:为一个模板代码,eclipse版本的,我就是借鉴里面稍微修改了一下。
     data:为百度语音资源,声音文件,它为一个必须文件,中英文资源。最后使用是放在手机物理存储下的。
     doc:为一个pdf的简介使用方法以及网络的使用Api文档说明。我们用不到,可以下去读一读的。
     libs:为资源jar包和语音引擎文件.so库。也是我们集成必须使用到的。
    7.接下来的步骤是,我们家语音资源和libs下的资源方法android studio我们的项目里面。将data里面的文件全部复制到Asserts文件夹下。将libs下的两个jar文件复制到项目的libs中,并添加Add As library关联。在项目中的main路径下新建一个jnilibs文件夹,用于放置剩余的libs下的文件。所以后的文件目录为:
     libs下面多余的两个okhttp和okio是我的网络访问的库,此处没有影响,不用添加的。
    8.最后在AndroidManifest文件中申明如下权限,我申请的比较多,因为做了一个网络判断的事件处理,没事全部Ctrl+C就好没影响的。










   

到此,集成就结束了,接下来就是如何使用。当然可以参照BaiduTtsSample文件夹下的src里面的一个MainActvity的写法。也可以按照我下面的总结的工具类来直接使用,方便快捷省事。

工具类如下


package com.bk120.mytest_autoanswer;

import android.content.Context;
import android.os.Environment;
import com.baidu.tts.client.SpeechError;
import com.baidu.tts.client.SpeechSynthesizer;
import com.baidu.tts.client.SpeechSynthesizerListener;
import com.baidu.tts.client.SynthesizerTool;
import com.baidu.tts.client.TtsMode;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
/*** Created by bk120 on 2017/1/3.
 * 语音合成工具类
 */

public class VoiceUtils {
//需配置部分
//AppId
private String APPID="9156383";
//ApiKey
private String APIKEY="BZQ1owOxjYzf0ADT1agq8SxU";
//SecretKey
private String SECRETKEY="43b8a384182f2af0b935cf4ee9dce03f";
配置结束

private SpeechSynthesizer mSpeechSynthesizer;
private String mSampleDirPath;
private static final String SAMPLE_DIR_NAME = "baiduTTS";
private static final String SPEECH_FEMALE_MODEL_NAME = "bd_etts_speech_female.dat";
private static final String SPEECH_MALE_MODEL_NAME = "bd_etts_speech_male.dat";
private static final String TEXT_MODEL_NAME = "bd_etts_text.dat";
private static final String LICENSE_FILE_NAME = "temp_license.txt";
private static final String ENGLISH_SPEECH_FEMALE_MODEL_NAME = "bd_etts_speech_female_en.dat";
private static final String ENGLISH_SPEECH_MALE_MODEL_NAME = "bd_etts_speech_male_en.dat";
private static final String ENGLISH_TEXT_MODEL_NAME = "bd_etts_text_en.dat";
//初始化
public  void init(Context context,int speaker){
    initialEnv(context);
    initialTts(context,speaker);
}
//获取解析器
public SpeechSynthesizer getSyntheszer(){
    return mSpeechSynthesizer;
}
//初始化配置文件
private void initialEnv(Context context) {
    if (mSampleDirPath == null) {
        String sdcardPath = Environment.getExternalStorageDirectory().toString();
        mSampleDirPath = sdcardPath + "/" + SAMPLE_DIR_NAME;
    }
    makeDir(mSampleDirPath);
    copyFromAssetsToSdcard(context,false, SPEECH_FEMALE_MODEL_NAME, mSampleDirPath + "/" + SPEECH_FEMALE_MODEL_NAME);
    copyFromAssetsToSdcard(context,false, SPEECH_MALE_MODEL_NAME, mSampleDirPath + "/" + SPEECH_MALE_MODEL_NAME);
    copyFromAssetsToSdcard(context,false, TEXT_MODEL_NAME, mSampleDirPath + "/" + TEXT_MODEL_NAME);
    copyFromAssetsToSdcard(context,false, LICENSE_FILE_NAME, mSampleDirPath + "/" + LICENSE_FILE_NAME);
    copyFromAssetsToSdcard(context,false, "english/" + ENGLISH_SPEECH_FEMALE_MODEL_NAME, mSampleDirPath + "/"
            + ENGLISH_SPEECH_FEMALE_MODEL_NAME);
    copyFromAssetsToSdcard(context,false, "english/" + ENGLISH_SPEECH_MALE_MODEL_NAME, mSampleDirPath + "/"
            + ENGLISH_SPEECH_MALE_MODEL_NAME);
    copyFromAssetsToSdcard(context,false, "english/" + ENGLISH_TEXT_MODEL_NAME, mSampleDirPath + "/"
            + ENGLISH_TEXT_MODEL_NAME);
}

private void makeDir(String dirPath) {
    File file = new File(dirPath);
    if (!file.exists()) {
        file.mkdirs();
    }
}
/**
 * 将资源语音文件复制到手机SD卡中
 * @param isCover 是否覆盖已存在的目标文件
 * @param source
 * @param dest
 */
private void copyFromAssetsToSdcard(Context context,boolean isCover, String source, String dest) {
    File file = new File(dest);
    if (isCover || (!isCover && !file.exists())) {
        InputStream is = null;
        FileOutputStream fos = null;
        try {
            is = context.getResources().getAssets().open(source);
            String path = dest;
            fos = new FileOutputStream(path);
            byte[] buffer = new byte[1024];
            int size = 0;
            while ((size = is.read(buffer, 0, 1024)) >= 0) {
                fos.write(buffer, 0, size);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            try {
                if (is != null) {
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
//初始化解析器
private void initialTts(Context context,int speaker) {
    this.mSpeechSynthesizer = SpeechSynthesizer.getInstance();
    this.mSpeechSynthesizer.setContext(context);
    this.mSpeechSynthesizer.setSpeechSynthesizerListener(new MyListnener());
    // 文本模型文件路径 (离线引擎使用)
    this.mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_TTS_TEXT_MODEL_FILE, mSampleDirPath + "/"
            + TEXT_MODEL_NAME);
    // 声学模型文件路径 (离线引擎使用)
    this.mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_TTS_SPEECH_MODEL_FILE, mSampleDirPath + "/"
            + SPEECH_FEMALE_MODEL_NAME);
    // 请替换为语音开发者平台上注册应用得到的App ID (离线授权)
    this.mSpeechSynthesizer.setAppId(APPID);
    // 请替换为语音开发者平台注册应用得到的apikey和secretkey (在线授权)
    this.mSpeechSynthesizer.setApiKey(APIKEY,
            SECRETKEY);
    // 发音人(在线引擎),可用参数为0,1,2,3。。。(服务器端会动态增加,各值含义参考文档,以文档说明为准。0--普通女声,4--情感女声,3--普通男声,6--特殊男声。。。)
    this.mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEAKER, speaker+"");
    // 设置Mix模式的合成策略
    this.mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_MIX_MODE, SpeechSynthesizer.MIX_MODE_DEFAULT);
    // 授权检测接口(只是通过AuthInfo进行检验授权是否成功。)
    // 初始化tts
    mSpeechSynthesizer.initTts(TtsMode.MIX);
    // 加载离线英文资源(提供离线英文合成功能)
    mSpeechSynthesizer.loadEnglishModel(mSampleDirPath + "/" + ENGLISH_TEXT_MODEL_NAME, mSampleDirPath
                    + "/" + ENGLISH_SPEECH_FEMALE_MODEL_NAME);

}
//合成监听器
class MyListnener implements SpeechSynthesizerListener{
    @Override
    public void onSynthesizeStart(String s) {
        //合成准备工作
    }
    @Override
    public void onSynthesizeDataArrived(String s, byte[] bytes, int i) {
        //合成数据和进度的回调接口,分多次回调
    }
    @Override
    public void onSynthesizeFinish(String s) {
        //合成正常结束,每句合成正常结束都会回调,如果过程中出错,则回调onError,不再回调此接口
    }
    @Override
    public void onSpeechStart(String s) {
        //播放开始,每句播放开始都会回调
    }
    @Override
    public void onSpeechProgressChanged(String s, int i) {
        //播放进度回调接口,分多次回调
    }
    @Override
    public void onSpeechFinish(String s) {
        // 播放正常结束,每句播放正常结束都会回调,如果过程中出错,则回调onError,不再回调此接口
    }
    @Override
    public void onError(String s, SpeechError speechError) {
        //当合成或者播放过程中出错时回调此接口
    }
}
}  

 该工具类我就不多解释了,唯一需要配置的地方在前面获取到的AppId,ApiKey和SecretKey直接替换成你自己的就可以了。该工具类做的事就是第一步将由于资源文件及Asserts下面的文件复制到SD卡上,然后初始化一个语音合成器SpeechSynthesizer。并提供放回的方法getSyntheszer供外部使用。合成监听器SpeechSynthesizerListener能处理各个阶段的事件。当然这个工具类不好,存在构造器还需要传入参数,有待改进,int speaker 为发声人,从0到7都可以使用,男声,女声,自己可以试着玩玩。

在MainActivity使用:

  1. 布局文件我们用一个输入框EditText和四个按钮来测试不同的发声。
    布局文件:






    

2.Activity中直接获取EditText对象并处理点击事件,如下:
MainActivity中:


package com.bk120.mytest_autoanswer;

import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import com.baidu.tts.client.SpeechSynthesizer;

public class MainActivity extends Activity {
    private EditText mInput;
    private SpeechSynthesizer mSpeechSynthesizer;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mInput= (EditText) this.findViewById(R.id.mainactivity_et);
}
//普通女声
public void puTongWoman(View view){
    speak(0);
}
//特殊女声
public void qingGanWoman(View view){
    speak(4);
}
//普通男声
public void puTongMan(View view){
    speak(3);
}
//特殊男声
public void qingGanMan(View view){
    speak(6);
}
private void speak(int speaker) {
    //若是每次都这样是不是会有内存问题呢?需要思考改进
    VoiceUtils utils=new VoiceUtils();
    utils.init(this,speaker);
    mSpeechSynthesizer=utils.getSyntheszer();
    String text = this.mInput.getText().toString();
    //需要合成的文本text的长度不能超过1024个GBK字节。
    if (TextUtils.isEmpty(mInput.getText())) {
        text = "你好!";
        mInput.setText(text);
    }
   this.mSpeechSynthesizer.speak(text);
}
//释放缓存
@Override
protected void onDestroy() {
    this.mSpeechSynthesizer.release();
    super.onDestroy();
}
}  

通过上面的步骤语音合成就算完事了,在没有网络连接的情况下默认speaker为0–普通女声,即点击所有按钮都是普通女声朗读出文本框中的文字,英文中文都可以,网络状态下其他按钮才能发出不同的声音。

 结果就是这样,点击按钮就能听见朗读声音咯。图中的按钮和输入框shape文件如下,文件名分别为btn_shape和et_shape,都放在res下的drawable文件夹中,适可参考Ctrl+C吧!
btn_shape:






  

et_shape:






 第一次写这个东东,是不是太详细了竟然写了老久了,这打字速度有点坑啊,还要多锻炼!

你可能感兴趣的:(第三方库集成使用)