android语音合成Demo

#基与科大讯飞的语音合成开发

##在线简易版效果图:
这里写图片描述

在线合成简易版源码地址:http://download.csdn.net/detail/kwunyamshan/9705929

##官方效果图:
这里写图片描述

官方摘出源码地址(在线与本地):旧下载链接被下载次数过多官方调高了分值,并且用户没法控制分值所以搞了个新链,代码相同只是删除了build 放心使用
新下载链接:https://download.csdn.net/download/kwunyamshan/11259959
旧下载链接 : https://download.csdn.net/download/kwunyamshan/9705915

##注意

下载的SDK中so库资源文件和appid是一一对应的,绝对不能混用。每个appid试用期35天、3个装机量。
你需要自己下载SDK,更换string中配置的appid,jniLibs下的so库与jar包,另:唤醒还需要替换assets文件夹下的.jet文件。

如何创建应用下载sdk请参考:http://blog.csdn.net/kwunyamshan/article/details/53320164

初始化
	1.这是很重要并且是必须的一步操作,实际上初始化的操作是异步进行的,如果初始化还没有完成你就开始调用了语音识别,是会出现很多问题的,建议在你程序刚刚启动的时候调用
/**
 * @author idulcimer
 */
public class SpeechApp extends Application {

    @Override
    public void onCreate() {
        // 应用程序入口处调用,避免手机内存过小,杀死后台进程后通过历史intent进入Activity造成SpeechUtility对象为null
        // 如在Application中调用初始化,需要在Mainifest中注册该Applicaiton
        // 注意:此接口在非主进程调用会返回null对象,如需在非主进程使用语音功能,请增加参数:SpeechConstant.FORCE_LOGIN+"=true"
        // 参数间使用半角“,”分隔。
        // 设置你申请的应用appid,请勿在'='与appid之间添加空格及空转义符

        // 注意: appid 必须和下载的SDK保持一致,否则会出现10407错误

        SpeechUtility.createUtility(SpeechApp.this, "appid=" + getString(R.string.app_id));

        // 以下语句用于设置日志开关(默认开启),设置成false时关闭语音云SDK日志打印
        // Setting.setShowLog(false);
        super.onCreate();
    }

}

	2.导入so库,这是我项目的so库你们需要用自己的so库和jar包

这里写图片描述

	3.清单文件
<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"/>
    <!--外存储写权限, 构建语法需要用到此权限 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <!--外存储读权限,构建语法需要用到此权限 -->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <!--配置权限,用来记录应用配置信息 -->
    <uses-permission android:name="android.permission.WRITE_SETTINGS"/>
    <!--手机定位信息,用来为语义等功能提供定位, 提供更精准的服务-->
    <!--定位信息是敏感信息, 可通过Setting.setLocationEnable(false)关闭定位请求 -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <!--如需使用人脸识别,还要添加:摄相头权限, 拍照需要用到-->
    <uses-permission android:name="android.permission.CAMERA" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:name=".global.SpeechApp"
        android:theme="@style/AppTheme">
        <activity android:name=".ui.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".settings.TtsSettings"/>
    </application>
	4.主代码
package com.android.idulcimer.speechsynthesizer2.ui;

import android.content.Context;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import com.android.idulcimer.speechsynthesizer2.R;
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;

public class MainActivity extends AppCompatActivity {
    public static final String TAG = "MainActivity";
    // 语音合成对象
    private SpeechSynthesizer mTts;
    private EditText et_text;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        // 初始化合成对象
        mTts = SpeechSynthesizer.createSynthesizer(MainActivity.this, mTtsInitListener);
        //设置参数
        setParam();
    }

    /**
     * 初始化布局
     */
    private void initView() {

        et_text = (EditText) findViewById(R.id.et_text);
    }


    /**
     * 初始化监听。
     */
    private InitListener mTtsInitListener = new InitListener() {


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


    /**
     * 参数设置
     *
     * @return
     */
    private void setParam() {
        // 清空参数
        mTts.setParameter(SpeechConstant.PARAMS, null);

        // 设置在线合成发音人
        /*合成发音人列表
        1、 语言为中英文的发音人可以支持中英文的混合朗读。
        2、 英文发音人只能朗读英文,中文无法朗读。
        3、 汉语发音人只能朗读中文,遇到英文会以单个字母的方式进行朗读。
        4、 使用新引擎参数会获得更好的合成效果。

        发音人名称 属性 语言 参数名称 新引擎参数 备注
        小燕 青年女声 中英文(普通话) xiaoyan 默认
        小宇 青年男声 中英文(普通话) xiaoyu
        凯瑟琳 青年女声 英文 catherine
        亨利 青年男声 英文 henry
        玛丽 青年女声 英文 vimary
        小研 青年女声 中英文(普通话) vixy
        小琪 青年女声 中英文(普通话) vixq xiaoqi
        小峰 青年男声 中英文(普通话) vixf
        小梅 青年女声 中英文(粤语) vixm xiaomei
        小莉 青年女声 中英文(台湾普通话) vixl xiaolin
        小蓉 青年女声 汉语(四川话) vixr xiaorong
        小芸 青年女声 汉语(东北话) vixyun xiaoqian
        小坤 青年男声 汉语(河南话) vixk xiaokun
        小强 青年男声 汉语(湖南话) vixqa xiaoqiang
        小莹 青年女声 汉语(陕西话) vixying
        小新 童年男声 汉语(普通话) vixx xiaoxin
        楠楠 童年女声 汉语(普通话) vinn nannan
        老孙 老年男声 汉语(普通话) vils
        Mariane 法语 Mariane
        Allabent 俄语 Allabent
        Gabriela 西班牙语 Gabriela
        Abha 印地语 Abha
        XiaoYun 越南语 XiaoYun*/
        mTts.setParameter(SpeechConstant.VOICE_NAME, "vinn");
        //设置合成语速    在线0-100  本地0-200
        mTts.setParameter(SpeechConstant.SPEED, "60");
        //设置合成音调   0-100
        mTts.setParameter(SpeechConstant.PITCH, "50");
        //设置合成音量    0-100
        mTts.setParameter(SpeechConstant.VOLUME, "100");
        //设置云端
        mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
        //设置播放器音频流类型
        //mTts.setParameter(SpeechConstant.STREAM_TYPE, "3");
        // 设置播放合成音频打断音乐播放,默认为true
        mTts.setParameter(SpeechConstant.KEY_REQUEST_FOCUS, "true");

        // 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限
        // 注:AUDIO_FORMAT参数语记需要更新版本才能生效
        mTts.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");
        mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH, Environment.getExternalStorageDirectory() + "/msc/tts.wav");
    }


    // 开始合成
    // 收到onCompleted 回调时,合成结束、生成合成音频
    // 合成的音频格式:只支持pcm格式
    public void startSpeak(View view) {
        String text = et_text.getText().toString().trim();
        if (text != null) {
            int code = mTts.startSpeaking(text, mTtsListener);
            if (code != ErrorCode.SUCCESS) {
                if (code == ErrorCode.ERROR_COMPONENT_NOT_INSTALLED) {
                    //未安装则跳转到提示安装页面
                } else {
                    showToast(this, "语音合成失败,错误码: " + code);
                }
            }
        }


    }

    // 取消合成
    public void stopSpeak(View view) {
        mTts.pauseSpeaking();
    }

    // 暂停播放
    public void pauseSpeak(View view) {
        mTts.pauseSpeaking();
    }

    //继续播放
    public void resumeSpeak(View view) {
        mTts.resumeSpeaking();
    }


    /**
     * 合成回调监听。
     */
    private SynthesizerListener mTtsListener = new SynthesizerListener() {

        @Override
        public void onSpeakBegin() {
            Log.i(TAG, "开始播放");
        }

        @Override
        public void onSpeakPaused() {
            Log.i(TAG, "暂停播放");
        }

        //恢复播放回调接口
        @Override
        public void onSpeakResumed() {
            Log.i(TAG, "继续播放");
        }

        //缓冲进度回调
        //percent为缓冲进度0~100, beginPos为缓冲音频在文本中开始位置, endPos表示缓冲音频在文本中结束位置, info为附加信息。
        @Override
        public void onBufferProgress(int percent, int beginPos, int endPos,
                                     String info) {
            // 合成进度
            showToast(MainActivity.this, "缓冲进度为" + percent );
        }

        @Override
        public void onSpeakProgress(int percent, int beginPos, int endPos) {
            // 播放进度
            showToast(MainActivity.this, "播放进度为" + percent );

        }

        //会话结束回调接口,没有错误时, error为null
        @Override
        public void onCompleted(SpeechError error) {
            if (error == null) {
                Log.i(TAG, "播放完成");
            } else if (error != null) {
                Log.i(TAG, "合成错误:" + error.getPlainDescription(true));
            }
        }

        @Override
        public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
            // 以下代码用于获取与云端的会话id,当业务出错时将会话id提供给技术支持人员,可用于查询会话日志,定位出错原因
            // 若使用本地能力,会话id为null
            //	if (SpeechEvent.EVENT_SESSION_ID == eventType) {
            //		String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);
            //		Log.d(TAG, "session id =" + sid);
            //	}
        }
    };


    /**
     *   吐司工具
     */
    private static Toast toast;

    public static void showToast(Context context, String text) {
        if (toast == null) {
            toast = Toast.makeText(context, text, Toast.LENGTH_SHORT);
        } else {
            toast.setText(text);//如果不为空,则直接改变当前toast的文本
        }
        toast.show();
    }
}


##目录结构
这里写图片描述

##效果图

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值