Android 使用讯飞语音SDK

时间:2023-02-02 01:00:43

最近一直忙着写代码,每天的空闲时间不多。先占位,慢慢填坑。

讯飞开放平台:
http://www.xfyun.cn/

注册为开发者,然后参照文档一步步走下去。

由于是商业SDK,平台有诸多限制,免费的话只能联网,并且有限制次数,应用通过审核后无请求次数限制。
(补充:离线语音合成也可以免费,需要安装讯飞+应用。)

1.在线合成

写了一个Service,传入要说的话,然后就可以语音播报:

package com.tchip.carlauncher.service;

import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.widget.RadioGroup;
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.SynthesizerListener;
import com.iflytek.library.ApkInstaller;
import com.iflytek.library.TtsSettings;

/** * Created by AlexZhou on 2015/4/21. 9:45 */
public class SpeakService extends Service {

    private static String TAG = SpeakService.class.getSimpleName();
    private SpeechSynthesizer mTts; // 语音合成对象
    private String voicer = "xiaoyan"; // 默认发音人
    private String[] cloudVoicersEntries;
    private String[] cloudVoicersValue;

    private int mPercentForBuffering = 0; // 缓冲进度
    private int mPercentForPlaying = 0; // 播放进度

    private RadioGroup mRadioGroup; // 云端/本地单选按钮
    private String mEngineType = SpeechConstant.TYPE_CLOUD; // 引擎类型
    // 语音+安装助手类
    ApkInstaller mInstaller;

    private Toast mToast;
    private SharedPreferences mSharedPreferences;
    private String content = "你好";

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        Bundle extras = intent.getExtras();
        if (extras != null) {
            content = extras.getString("content");
        }
        // 初始化合成对象
        mTts = SpeechSynthesizer.createSynthesizer(this, mTtsInitListener);
        mSharedPreferences = getSharedPreferences(TtsSettings.PREFER_NAME,
                MODE_PRIVATE);
        mToast = Toast.makeText(this, "", Toast.LENGTH_SHORT);

        // mInstaller = new ApkInstaller(SpeakService.this);

        // 设置参数
        setParam();
        int code = mTts.startSpeaking(content, mTtsListener);
        if (code != ErrorCode.SUCCESS) {
            if (code == ErrorCode.ERROR_COMPONENT_NOT_INSTALLED) {
                // 未安装则跳转到提示安装页面 mInstaller.install();
            } else {
                // 语音合成失败,错误码:code
            }
        }

        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    /** * 初始化监听。 */
    private InitListener mTtsInitListener = new InitListener() {
        @Override
        public void onInit(int code) {
            Log.d(TAG, "InitListener init() code = " + code);
            if (code != ErrorCode.SUCCESS) {
                // 初始化失败,错误码: code
            } else {
                // 初始化成功,之后可以调用startSpeaking方法
                // 注:有的开发者在onCreate方法中创建完合成对象之后马上就调用startSpeaking进行合成,
                // 正确的做法是将onCreate中的startSpeaking调用移至这里
            }
        }
    };

    /** * 合成回调监听。 */
    private SynthesizerListener mTtsListener = 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) {
            // 合成进度
            mPercentForBuffering = percent;
        }

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

        @Override
        public void onCompleted(SpeechError error) {
            if (error == null) {
                // 播放完成
                stopSelf();
            } else if (error != null) {
            }
        }

        @Override
        public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {

        }
    };

    private void showTip(final String str) {
        mToast.setText(str);
        mToast.show();
    }

    private void setParam() {
        // 清空参数
        mTts.setParameter(SpeechConstant.PARAMS, null);
        // 设置合成
        if (mEngineType.equals(SpeechConstant.TYPE_CLOUD)) {
            mTts.setParameter(SpeechConstant.ENGINE_TYPE,
                    SpeechConstant.TYPE_CLOUD);
            // 设置发音人
            mTts.setParameter(SpeechConstant.VOICE_NAME, voicer);
            // 设置语速
            mTts.setParameter(SpeechConstant.SPEED,
                    mSharedPreferences.getString("speed_preference", "50"));
            // 设置音调
            mTts.setParameter(SpeechConstant.PITCH,
                    mSharedPreferences.getString("pitch_preference", "50"));
            // 设置音量
            mTts.setParameter(SpeechConstant.VOLUME,
                    mSharedPreferences.getString("volume_preference", "50"));
            // 设置播放器音频流类型
            mTts.setParameter(SpeechConstant.STREAM_TYPE,
                    mSharedPreferences.getString("stream_preference", "3"));
        } else {
            mTts.setParameter(SpeechConstant.ENGINE_TYPE,
                    SpeechConstant.TYPE_LOCAL);
            // 设置发音人 voicer为空默认通过语音+界面指定发音人。
            mTts.setParameter(SpeechConstant.VOICE_NAME, "");
        }
    }
}

2.离线合成

private String mEngineType = SpeechConstant.TYPE_LOCAL;

3.语义理解

// 设置参数
            setParam();

            if (mSpeechUnderstander.isUnderstanding()) { // 开始前检查状态
                mSpeechUnderstander.stopUnderstanding();
                // 停止录音
            } else {
                ret = mSpeechUnderstander
                        .startUnderstanding(mRecognizerListener);
                if (ret != 0) {
                    // 语义理解失败,错误码:ret
                } else {
                    showTip(getString(R.string.text_begin));
                }
            }

3.1 最近一周天气JSON解析

String jsonString = result.getResultString();
                if (!TextUtils.isEmpty(jsonString)) {
                    JSONObject jsonObject;
                    try {
                        jsonObject = new JSONObject(jsonString);
                        JSONArray mJSONArray = jsonObject.getJSONObject("data")
                                .getJSONArray("result");
                        for (int i = 0; i < 7; i++) {
                            JSONObject jsonDay = mJSONArray.getJSONObject(i);
                            String tempRange = jsonDay.getString("tempRange"); // 31℃~26℃
                            String tempArray[] = tempRange.split("~");
                            editor.putString("postTime",
                                    jsonDay.getString("lastUpdateTime"));

                            editor.putString("day" + i + "air",
                                    jsonDay.getString("airQuality"));

                            editor.putString("day" + i + "weather",
                                    jsonDay.getString("weather"));
                            editor.putString("day" + i + "tmpHigh",
                                    tempArray[0]);
                            editor.putString("day" + i + "tmpLow", tempArray[1]);
                            editor.putString(
                                    "day" + i + "wind",
                                    jsonDay.getString("wind")
                                            + jsonDay.getString("windLevel"));

                            editor.commit();
                        }

3.2 语音交互

JSONObject jsonObject;
                                jsonObject = new JSONObject(text);
                                String strQuestion = jsonObject
                                        .getString("text");
                                tvQuestion.setText(strQuestion);

                                String strService = jsonObject
                                        .getString("service");
                                if ("openQA".equals(strService)
                                        || "datetime".equals(strService)
                                        || "chat".equals(strService)) {
                                    String strAnswer = jsonObject
                                            .getJSONObject("answer").getString(
                                                    "text");
                                    tvAnswer.setText(strAnswer);
                                    startSpeak(strAnswer);
                                } else if ("baike".equals(strService)) {
                                    String strAnswer = jsonObject
                                            .getJSONObject("answer").getString(
                                                    "text");
                                    tvAnswer.setText(strAnswer);
                                } else if ("weather".equals(strService)) {

                                    JSONArray mJSONArray = jsonObject
                                            .getJSONObject("data")
                                            .getJSONArray("result");
                                    JSONObject todayJSON = mJSONArray
                                            .getJSONObject(0);
                                    String tempRange = todayJSON
                                            .getString("tempRange");
                                    String weather = todayJSON
                                            .getString("weather");
                                    String city = todayJSON.getString("city");
                                    String strAnswer = city + "天气:" + weather
                                            + ",温度" + tempRange;
                                    tvAnswer.setText(strAnswer);
                                    startSpeak(strAnswer);
                                }

Android 使用讯飞语音SDK 转载请注明出处:周木水的CSDN博客