讯飞离线语音合成(语记)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lihongxiangleo/article/details/53817866

讯飞语音的合成有三种方式:

1.在线语音合成(免费)

2.离线使用讯飞语记合成(免费,需要在本地下载语记APP)

3.使用离线合成SDK(收费)

公司这次的需求是做一个听书的功能,就是将文字合成语音播放出来,综合考虑选择第一种和第二种方案。离线合成的SDK也太特么贵了,按装机量来算的,每台几块钱,我等屌丝还是不考虑了。(^__^)
由于官方文档有点零散,所以自己总结了一下集成步骤:

1.在官网上申请应用,获取对应的 appid,下载所需要对应的 SDK,这里我下载的是在线语音合成的 SDK。

2.将 SDK 中的 jar 包和 .so 库复制到项目当中,AndroidStudio 默认是没有 jniLibs 目录的我们要自己在 main 目录下手动创建该文件。
1

3.在Application类初始化

    public class AppApplication extends Application {
        private static AppApplication mContext;

        @Override
        public void onCreate() {
            super.onCreate();
            mContext = this;
            StringBuffer buffer = new StringBuffer();
            buffer.append("appid=58579f0a");
            //buffer.append(",");
            //buffer.append(SpeechConstant.ENGINE_MODE + "=" + SpeechConstant.MODE_MSC);
            SpeechUtility.createUtility(this, buffer.toString());
        }

        public static AppApplication getContext() {
            return mContext;
        }
    }

4.添加用户权限:

<!--连接网络权限,用于执行云端语音能力 -->
<uses-permission android:name="android.permission.INTERNET"/>

<!--获取手机录音机使用权限,听写、识别、语义理解需要用到此权限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO"/>

<!--读取网络信息状态 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

<!--获取当前wifi状态 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

<!--允许程序改变网络连接状态 -->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>

<!--读取手机信息权限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

<!--读取联系人权限,上传联系人需要用到此权限 -->
<uses-permission android:name="android.permission.READ_CONTACTS"/>

5.测试代码:

package com.example.lihongxiangleo.testxunfei;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.iflytek.cloud.ErrorCode;
import com.iflytek.cloud.InitListener;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechSynthesizer;
import com.iflytek.cloud.SpeechUtility;
import com.iflytek.cloud.SynthesizerListener;
import com.iflytek.cloud.util.ResourceUtil;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private Toast mToast;
    private EditText mVoiceContent;
    private SpeechSynthesizer mSynthesizer;
    // 默认本地发音人
    public String voicerLocal = "xiaochun";
    private InitListener mTtsInitListner = new InitListener() {
        @Override
        public void onInit(int code) {
            if (code != ErrorCode.SUCCESS) {
                showTost("初始化失败,错误码:" + code);
            } else {

            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //获取本地语记中的语音资源
//        String result = SpeechUtility.getUtility().getParameter(SpeechConstant.PLUS_LOCAL_TTS);
        initView();
        //1.创建SpeechSynthesizer对象, 第二个参数:本地合成时传InitListener
        mSynthesizer = SpeechSynthesizer.createSynthesizer(AppApplication.getContext(), mTtsInitListner);
    }

    private void initView() {
        Button btReading = (Button) findViewById(R.id.bt_reading);
        Button btMore = (Button) findViewById(R.id.bt_more);
        btReading.setOnClickListener(this);
        btMore.setOnClickListener(this);
        mVoiceContent = (EditText) findViewById(R.id.et_voice_content);
        mToast = Toast.makeText(AppApplication.getContext(), "", Toast.LENGTH_SHORT);
    }


    private void setSpeakParam() {
        //清空参数
        mSynthesizer.setParameter(SpeechConstant.PARAMS, null);
        //设置使用本地引擎
        mSynthesizer.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_LOCAL);
        //设置发音人资源路径 使用离线合成SDK时使用
        //mSynthesizer.setParameter(ResourceUtil.TTS_RES_PATH, getResourcePath());
        //设置发音人
        mSynthesizer.setParameter(SpeechConstant.VOICE_NAME, voicerLocal);
        //设置合成速度
        mSynthesizer.setParameter(SpeechConstant.SPEED, "50");
        //设置合成音量
        mSynthesizer.setParameter(SpeechConstant.VOLUME, "100");//设置音量,范围0~100
        //设置播放合成音频打断音乐播放,默认为true
        mSynthesizer.setParameter(SpeechConstant.KEY_REQUEST_FOCUS, "true");
        // 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限
        // 注:AUDIO_FORMAT参数语记需要更新版本才能生效
        mSynthesizer.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");
        mSynthesizer.setParameter(SpeechConstant.TTS_AUDIO_PATH, Environment.getExternalStorageDirectory() + "/msc/tts.wav");
        // 设置播放器音频流类型
        mSynthesizer.setParameter(SpeechConstant.STREAM_TYPE, "3");
    }

    private SynthesizerListener listener = new SynthesizerListener() {
        @Override
        public void onSpeakBegin() {
            //开始播放
        }

        @Override
        public void onSpeakPaused() {
            //播放暂停
        }

        @Override
        public void onSpeakResumed() {
            //继续播放
        }

        @Override
        public void onBufferProgress(int percent, int beginPos, int endPos, String info) {
            //合成进度
        }

        @Override
        public void onSpeakProgress(int percent, int beginPos, int endPos) {
            //播放进度
        }

        @Override
        public void onCompleted(SpeechError speechError) {
            //播放完成
        }

        @Override
        public void onEvent(int i, int i1, int i2, Bundle bundle) {

        }
    };

    //获取发音人资源路径
    private String getResourcePath() {
        StringBuffer tempBuffer = new StringBuffer();
        //合成通用资源
        tempBuffer.append(ResourceUtil.generateResourcePath(this, ResourceUtil.RESOURCE_TYPE.assets, "tts/common.jet"));
        tempBuffer.append(";");
        //发音人资源
        tempBuffer.append(ResourceUtil.generateResourcePath(this, ResourceUtil.RESOURCE_TYPE.assets, "tts/" + voicerLocal + ".jet"));
        return tempBuffer.toString();
    }

    private void showTost(final String text) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mToast.setText(text);
                mToast.show();
            }
        });
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.bt_reading:
                //检查《语记》是否安装
                // 如未安装,获取《语记》下载地址进行下载。安装完成后即可使用服务。
                if (!SpeechUtility.getUtility().checkServiceInstalled()) {
                    String url = SpeechUtility.getUtility().getComponentUrl();
                    Uri uri = Uri.parse(url);
                    Intent it = new Intent(Intent.ACTION_VIEW, uri);
                    startActivity(it);
                } else {
                    setSpeakParam();
                    //3.开始合成
                    String content = mVoiceContent.getText().toString().trim();
                    if (!TextUtils.isEmpty(content)) {
                        int code = mSynthesizer.startSpeaking(content, listener);
                        if (code != ErrorCode.SUCCESS) {
                            showTost("语音合成失败,错误码: " + code);
                        }
                    }
                }
                break;

            case R.id.bt_more:
                //跳转到发音人设置页面进行发音人下载
                SpeechUtility.getUtility().openEngineSettings(SpeechConstant.ENG_TTS);
                break;
        }
    }
}

注意

SpeechConstant.MODE_MSC 参数意思是使用离线包资源,如果离线包资源找不到会走网络识别,如果设置这种模式是不会使用语记(语音+)的如果使用离线包,就需要这条参数。所以我们一开初始化的时候注释掉了

// param.append(",");
// param.append(SpeechConstant.ENGINE_MODE + "=" + SpeechConstant.MODE_MSC);
展开阅读全文

没有更多推荐了,返回首页