• 讯飞语音开发集成地址http://www.xfyun.cn/ 解压后的doc文件夹下的msc develop 文件中有详细集成步骤 获取AppId1.先要注册开发者账户, 添加我的应用 , 下载sdk(语音听写)2.下载后将sdk解压, 把案例导入工程中运行看...

    讯飞语音开发集成地址http://www.xfyun.cn/ 解压后的doc文件夹下的msc develop 文件中有详细集成步骤

    获取AppId

    1.先要注册开发者账户, 添加我的应用 , 下载sdk(语音听写)

    2.下载后将sdk解压, 把案例导入工程中运行看看效果

    3.将libs下的两个jar包添加到libs目录下, 将同路径下的其它 .so文件(与c进行交互)复制到main路径下新建的 jniLibs(L要大写)目录下(别忘了jar包要add) , 将assert目录拷贝到main目录下 

    注意 : 这些都是自己创建的应用生成的, 在申请appid时就与自己的应用绑定了, 拷贝别人的是没有用的

    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" />  
          
            <!--SD卡读写的权限(如果需要保存音频文件到本地的话)-->  
            <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />  
            <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  
            <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />  

    5.创建类 , 以下是代码: initSpeech()方法下的APPID需要改成上面介绍中自己应用生成的appId

    import android.app.Activity ;
    import android.os.Bundle ;
    import android.util.Log ;
    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.RecognizerListener ;
    import com.iflytek.cloud.RecognizerResult ;
    import com.iflytek.cloud.SpeechConstant ;
    import com.iflytek.cloud.SpeechError ;
    import com.iflytek.cloud.SpeechRecognizer ;
    import com.iflytek.cloud.SpeechSynthesizer ;
    import com.iflytek.cloud.SpeechUtility ;
    import com.iflytek.cloud.SynthesizerListener ;
    import com.iflytek.cloud.ui.RecognizerDialog ;
    import com.iflytek.cloud.ui.RecognizerDialogListener ;
    
    import org.json.JSONException ;
    import org.json.JSONObject ;
    
    import java.util.HashMap ;
    import java.util.LinkedHashMap ;
    
    public class MainActivity extends Activity implements View.OnClickListener {
    
        private static final String TAG = MainActivity.class .getSimpleName();
        private EditText et_input;
        private Button btn_startspeech, btn_startspeektext ;
    
        // 用HashMap存储听写结果
        private HashMap<String, String> mIatResults = new LinkedHashMap<String , String>();
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super .onCreate(savedInstanceState) ;
            initView() ;
            initSpeech() ;
        }
    
        private void initView() {
            setContentView(R.layout.activity_main) ;
            et_input = (EditText) findViewById(R.id.et_input );
            btn_startspeech = (Button) findViewById(R.id.btn_startspeech );
            btn_startspeektext = (Button) findViewById(R.id.btn_startspeektext );
            btn_startspeech .setOnClickListener(this) ;
            btn_startspeektext .setOnClickListener(this) ;
        }
    
        private void initSpeech() {
            // 将“12345678”替换成您申请的 APPID,申请地址: http://www.xfyun.cn
            // 请勿在 “ =”与 appid 之间添加任务空字符或者转义符
            SpeechUtility. createUtility( this, SpeechConstant. APPID + "=56ffe0ae" ); 
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.btn_startspeech: //语音识别(把声音转文字)
                    startSpeechDialog();
                    break;
                case R.id. btn_startspeektext:// 语音合成(把文字转声音)
                    speekText();
                    break;
            }
    
        }
    
        private void speekText() {
            //1. 创建 SpeechSynthesizer 对象 , 第二个参数: 本地合成时传 InitListener
            SpeechSynthesizer mTts = SpeechSynthesizer.createSynthesizer( this, null);
    //2.合成参数设置,详见《 MSC Reference Manual》 SpeechSynthesizer 类
    //设置发音人(更多在线发音人,用户可参见 附录 13.2
            mTts.setParameter(SpeechConstant. VOICE_NAME, "vixyun" ); // 设置发音人
            mTts.setParameter(SpeechConstant. SPEED, "50" );// 设置语速
            mTts.setParameter(SpeechConstant. VOLUME, "80" );// 设置音量,范围 0~100
            mTts.setParameter(SpeechConstant. ENGINE_TYPE, SpeechConstant. TYPE_CLOUD); //设置云端
    //设置合成音频保存位置(可自定义保存位置),保存在 “./sdcard/iflytek.pcm”
    //保存在 SD 卡需要在 AndroidManifest.xml 添加写 SD 卡权限
    //仅支持保存为 pcm 和 wav 格式, 如果不需要保存合成音频,注释该行代码
            mTts.setParameter(SpeechConstant. TTS_AUDIO_PATH, "./sdcard/iflytek.pcm" );
    //3.开始合成
            mTts.startSpeaking( et_input.getText().toString(), new MySynthesizerListener()) ;
    
        }
    
        class MySynthesizerListener implements SynthesizerListener {
    
            @Override
            public void onSpeakBegin() {
                showTip(" 开始播放 ");
            }
    
            @Override
            public void onSpeakPaused() {
                showTip(" 暂停播放 ");
            }
    
            @Override
            public void onSpeakResumed() {
                showTip(" 继续播放 ");
            }
    
            @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 error) {
                if (error == null) {
                    showTip("播放完成 ");
                } else if (error != null ) {
                    showTip(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 void startSpeechDialog() {
            //1. 创建RecognizerDialog对象
            RecognizerDialog mDialog = new RecognizerDialog(this, new MyInitListener()) ;
            //2. 设置accent、 language等参数
            mDialog.setParameter(SpeechConstant. LANGUAGE, "zh_cn" );// 设置中文
            mDialog.setParameter(SpeechConstant. ACCENT, "mandarin" );
            // 若要将UI控件用于语义理解,必须添加以下参数设置,设置之后 onResult回调返回将是语义理解
            // 结果
            // mDialog.setParameter("asr_sch", "1");
            // mDialog.setParameter("nlp_version", "2.0");
            //3.设置回调接口
            mDialog.setListener( new MyRecognizerDialogListener()) ;
            //4. 显示dialog,接收语音输入
            mDialog.show() ;
        }
    
        class MyRecognizerDialogListener implements RecognizerDialogListener {
    
            /**
             * @param results
             * @param isLast  是否说完了
             */
            @Override
            public void onResult(RecognizerResult results, boolean isLast) {
                String result = results.getResultString(); //为解析的
                showTip(result) ;
                System. out.println(" 没有解析的 :" + result);
    
                String text = JsonParser.parseIatResult(result) ;//解析过后的
                System. out.println(" 解析后的 :" + text);
    
                String sn = null;
                // 读取json结果中的 sn字段
                try {
                    JSONObject resultJson = new JSONObject(results.getResultString()) ;
                    sn = resultJson.optString("sn" );
                } catch (JSONException e) {
                    e.printStackTrace();
                }
    
                mIatResults .put(sn, text) ;//没有得到一句,添加到
    
                StringBuffer resultBuffer = new StringBuffer();
                for (String key : mIatResults.keySet()) {
                    resultBuffer.append(mIatResults .get(key));
                }
    
                et_input.setText(resultBuffer.toString());// 设置输入框的文本
                et_input .setSelection(et_input.length()) ;//把光标定位末尾
            }
    
            @Override
            public void onError(SpeechError speechError) {
    
            }
        }
    
        class MyInitListener implements InitListener {
    
            @Override
            public void onInit(int code) {
                if (code != ErrorCode.SUCCESS) {
                    showTip("初始化失败 ");
                }
    
            }
        }
    
        /**
         * 语音识别
         */
        private void startSpeech() {
            //1. 创建SpeechRecognizer对象,第二个参数: 本地识别时传 InitListener
            SpeechRecognizer mIat = SpeechRecognizer.createRecognizer( this, null); //语音识别器
            //2. 设置听写参数,详见《 MSC Reference Manual》 SpeechConstant类
            mIat.setParameter(SpeechConstant. DOMAIN, "iat" );// 短信和日常用语: iat (默认)
            mIat.setParameter(SpeechConstant. LANGUAGE, "zh_cn" );// 设置中文
            mIat.setParameter(SpeechConstant. ACCENT, "mandarin" );// 设置普通话
            //3. 开始听写
            mIat.startListening( mRecoListener);
        }
    
    
        // 听写监听器
        private RecognizerListener mRecoListener = new RecognizerListener() {
            // 听写结果回调接口 (返回Json 格式结果,用户可参见附录 13.1);
    //一般情况下会通过onResults接口多次返回结果,完整的识别内容是多次结果的累加;
    //关于解析Json的代码可参见 Demo中JsonParser 类;
    //isLast等于true 时会话结束。
            public void onResult(RecognizerResult results, boolean isLast) {
                Log.e (TAG, results.getResultString());
                System.out.println(results.getResultString()) ;
                showTip(results.getResultString()) ;
            }
    
            // 会话发生错误回调接口
            public void onError(SpeechError error) {
                showTip(error.getPlainDescription(true)) ;
                // 获取错误码描述
                Log. e(TAG, "error.getPlainDescription(true)==" + error.getPlainDescription(true ));
            }
    
            // 开始录音
            public void onBeginOfSpeech() {
                showTip(" 开始录音 ");
            }
    
            //volume 音量值0~30, data音频数据
            public void onVolumeChanged(int volume, byte[] data) {
                showTip(" 声音改变了 ");
            }
    
            // 结束录音
            public void onEndOfSpeech() {
                showTip(" 结束录音 ");
            }
    
            // 扩展用接口
            public void onEvent(int eventType, int arg1 , int arg2, Bundle obj) {
            }
        };
    
        private void showTip (String data) {
            Toast.makeText( this, data, Toast.LENGTH_SHORT).show() ;
        }
    }

    6.json解析类:

    import org.json.JSONArray ;
    import org.json.JSONObject ;
    import org.json.JSONTokener ;
    
    /**
    * Json结果解析类
    */
    public class JsonParser {
    
         public static String parseIatResult(String json) {
              StringBuffer ret = new StringBuffer() ;
              try {
                  JSONTokener tokener = new JSONTokener(json) ;
                  JSONObject joResult = new JSONObject(tokener) ;
    
                  JSONArray words = joResult.getJSONArray("ws" );
                  for (int i = 0; i < words.length(); i++) {
                       // 转写结果词,默认使用第一个结果
                                           JSONArray items = words.getJSONObject(i).getJSONArray("cw" );
                       JSONObject obj = items.getJSONObject(0 );
                       ret.append(obj.getString("w" ));
    //                  如果需要多候选结果,解析数组其他字段
    //                 for(int j = 0; j < items.length(); j++)
    //                 {
    //                      JSONObject obj = items.getJSONObject(j);
    //                      ret.append(obj.getString("w"));
    //                 }
                  }
              } catch (Exception e) {
                  e.printStackTrace();
              }
              return ret.toString();
         }
    
         public static String parseGrammarResult(String json) {
              StringBuffer ret = new StringBuffer() ;
              try {
                  JSONTokener tokener = new JSONTokener(json) ;
                  JSONObject joResult = new JSONObject(tokener) ;
    
                  JSONArray words = joResult.getJSONArray("ws" );
                  for (int i = 0; i < words.length(); i++) {
                       JSONArray items = words.getJSONObject(i).getJSONArray("cw" );
                       for (int j = 0; j < items.length() ; j++)
                       {
                            JSONObject obj = items.getJSONObject(j);
                            if (obj.getString("w").contains( "nomatch"))
                            {
                                 ret.append( "没有匹配结果.") ;
                                 return ret.toString();
                             }
                            ret.append( "【结果】" + obj.getString("w" ));
                             ret.append("【置信度】 " + obj.getInt("sc" ));
                             ret.append("\n ");
                       }
                  }
              } catch (Exception e) {
                  e.printStackTrace();
                  ret.append(" 没有匹配结果 .");
              }
              return ret.toString();
         }
    
         public static String parseLocalGrammarResult(String json) {
              StringBuffer ret = new StringBuffer() ;
              try {
                  JSONTokener tokener = new JSONTokener(json) ;
                  JSONObject joResult = new JSONObject(tokener) ;
    
                  JSONArray words = joResult.getJSONArray("ws" );
                  for (int i = 0; i < words.length(); i++) {
                       JSONArray items = words.getJSONObject(i).getJSONArray("cw" );
                       for (int j = 0; j < items.length() ; j++)
                       {
                            JSONObject obj = items.getJSONObject(j);
                            if (obj.getString("w").contains( "nomatch"))
                            {
                                 ret.append( "没有匹配结果.") ;
                                 return ret.toString();
                             }
                            ret.append( "【结果】" + obj.getString("w" ));
                             ret.append("\n ");
                       }
                  }
                  ret.append("【置信度】 " + joResult.optInt("sc" ));
    
              } catch (Exception e) {
                  e.printStackTrace();
                  ret.append(" 没有匹配结果 .");
              }
              return ret.toString();
         }
    }

    7.布局文件:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:layout_height="match_parent"
        tools:context="com.lingtian.yuyinbobao.MainActivity">
        <EditText
            android:id="@+id/et_input"
            android:layout_margin="10dp"
            android:layout_width="match_parent"
            android:layout_height="80dp"
            android:hint="请输入文本信息 ..." />
    
        <Button
            android:id="@+id/btn_startspeech"
            android:text="点击按钮语音输入 "
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
        <Button
            android:id="@+id/btn_startspeektext"
            android:text="语音合成(把文字转声音) "
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
    
    </LinearLayout>

    展开全文
  • android集成科大讯飞语音听写和语音合成 集成科大讯飞语音听写和语音合成,语音听写只是语音识别下面的一部分,别弄混淆了,由于科大讯飞暂未开放gradle引包方式,所以目前集成还是手动引包。我的流程是点击语音...
    android集成科大讯飞语音听写和语音合成


            集成科大讯飞语音听写和语音合成,语音听写只是语音识别下面的一部分,别弄混淆了,由于科大讯飞暂未开放gradle引包方式,所以目前集成还是手动引包。我的流程是点击语音合成按钮然后播放语音,点击语音合成按钮说话然后识别出文字。

    1、语音合成:文字转语音

    2、语音听写:语音转文字,可以使用原生UI,也可以不使用,区别就是在于两者的监听方法不一样而已。

    集成步骤:

    一、下载语音听写和语音合成sdk包(离线语音是要收费的,所以选择在线语言)



    二、sdk引入项目,androidstudio项目目录结构如图所示,我的是webview加载的h5界面发起的语音请求,就算是原生,思路也一样,做好动态权限,不然是没有权限的,如果只是测试那你去手动开启麦克风权限也可以,但是不是科学的办法

    1、原libs下面的Msc.jar引入android libs下面

    2、iflytek引入assets下面

    3、原libs下面的除Msc.jar其他包引入android 的jniLibs下面

    4、build.gradle依赖里面加入

    //科大讯飞语音包
    implementation files('libs/Msc.jar')
    5、项目目录结构大致如下所示


    三、加入权限,6.0之后需要做动态权限,不然只在清单文件里面申请是开启不了权限的。动态权限可以参考http://blog.csdn.net/u013144287/article/details/79298358这篇文章

    <!--连接网络权限,用于执行云端语音能力 -->
    <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" />

    四、初始化即创建语音配置对象,只有初始化后才可以使用MSC的各项服务。建议将初始化放在程序入口处(如Application、Activity的onCreate方法),初始化代码如下:这个代码写在activity里面

    // 将“12345678”替换成您申请的APPID,申请地址:http://www.xfyun.cn
    // 请勿在“=”与appid之间添加任何空字符或者转义符
    SpeechUtility.createUtility(context, SpeechConstant.APPID +"=12345678");

    五、语音合成和语音听写代码写法(代码直接写在一个工具类JavaScriptUtils里面,只不过是利用构造函数把activity的context传过来而已)

    //语音听写对象
    private SpeechRecognizer mAsr;
    //语音合成对象
    private SpeechSynthesizer mTts;
    //语音识别动画效果
    private RecognizerDialog iatDialog;
    //存储所有的语音识别文字
    private String voiceResult = "";
    
    
     /**
         * 语音合成 文字转声音
         */
        @JavascriptInterface
        public void speechSynthesizerVoice(String strTextToSpeech){
         //初始化语音合成
            mTts= SpeechSynthesizer.createSynthesizer(mContext, new InitListener() {
                @Override
                public void onInit(int i) {
                    System.out.println("语音合成错误码:"+ i);
                }
            });
            mTts.setParameter(SpeechConstant.VOICE_NAME, "xiaoyan");//设置发音人
            mTts.setParameter(SpeechConstant.SPEED, "50");//设置语速
            mTts.setParameter(SpeechConstant.VOLUME, "80");//设置音量,范围0~100
            mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD); //设置云端
            mTts.startSpeaking(strTextToSpeech, mSynListener);
        }
    
        /**
         * 语音合成监听器
         */
        SynthesizerListener mSynListener = new SynthesizerListener(){
            //会话结束回调接口,没有错误时,error为null
            public void onCompleted(SpeechError error) {
                mHandler.sendEmptyMessage(6007);
            }
            //缓冲进度回调
            //percent为缓冲进度0~100,beginPos为缓冲音频在文本中开始位置,endPos表示缓冲音频在文本中结束位置,info为附加信息。
            public void onBufferProgress(int percent, int beginPos, int endPos, String info) {}
            //开始播放
            public void onSpeakBegin() {}
            //暂停播放
            public void onSpeakPaused() {}
            //播放进度回调
            //percent为播放进度0~100,beginPos为播放音频在文本中开始位置,endPos表示播放音频在文本中结束位置.
            public void onSpeakProgress(int percent, int beginPos, int endPos) {}
            //恢复播放回调接口
            public void onSpeakResumed() {}
            //会话事件回调接口
            public void onEvent(int arg0, int arg1, int arg2, Bundle arg3) {}
        };
        /**
         * 语音听写 声音转文字
         */
        @JavascriptInterface
        public void speechRecognizerVoice() {
        //初始化语音听写对象
            mAsr = SpeechRecognizer.createRecognizer(mContext, new InitListener() {
                @Override
                public void onInit(int i) {
                    System.out.println("语音听写对象错误码" + i);
                }
            });
            //初始化语音UI
    //        iatDialog = new RecognizerDialog(mContext, new InitListener() {
    //            @Override
    //            public void onInit(int i) {
    //                System.out.println("语音ui" + i);
    //            }
    //        });
            // 清空参数
            mAsr.setParameter(SpeechConstant.PARAMS, null);
            // 设置听写引擎
            mAsr.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
            // 设置返回结果格式
            mAsr.setParameter(SpeechConstant.RESULT_TYPE, "json");
            // 设置语言
            mAsr.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
            // 设置语言区域
            mAsr.setParameter(SpeechConstant.ACCENT, "mandarin");
            // 设置语音前端点:静音超时时间,即用户多长时间不说话则当做超时处理
            mAsr.setParameter(SpeechConstant.VAD_BOS,"5000");
            // 设置语音后端点:后端点静音检测时间,即用户停止说话多长时间内即认为不再输入, 自动停止录音
            mAsr.setParameter(SpeechConstant.VAD_EOS,  "5000");
            //3.设置回调接口
    //        iatDialog.setListener(new RecognizerDialogListener() {
    //            @Override
    //            public void onResult(RecognizerResult recognizerResult, boolean isLast) {
    //                if (!isLast) {
    //                    //解析语音
    //                    String result = parseVoice(recognizerResult.getResultString());
    //                    System.out.println("--------------------------------" + result);
    //                }
    //            }
    //
    //            @Override
    //            public void onError(SpeechError speechError) {
    //                System.out.println(speechError.getErrorCode() + "*******" + speechError.getErrorDescription());
    //            }
    //        });
    //        //4.开始听写
    //        iatDialog.show();
    
            mAsr.startListening(new RecognizerListener() {
                @Override
                public void onVolumeChanged(int i, byte[] bytes) {
                    Message message = new Message();
                    message.what = 6005;
                    message.obj = i;
                    mHandler.sendMessage(message);
                }
    
                @Override
                public void onBeginOfSpeech() {
                    System.out.println("开始讲话");
                }
    
                @Override
                public void onEndOfSpeech() {
                    System.out.println("结束讲话");
                }
    
                @Override
                public void onResult(RecognizerResult recognizerResult, boolean b) {
                    if (!b) {
                        //解析语音
                        voiceResult = voiceResult + parseVoice(recognizerResult.getResultString());
                    }else{
                        Message message = new Message();
                        message.what = 6006;
                        message.obj = voiceResult;
                        mHandler.sendMessage(message);
                    }
                }
    
                @Override
                public void onError(SpeechError speechError) {
    
                }
    
                @Override
                public void onEvent(int i, int i1, int i2, Bundle bundle) {
    
                }
            });
        }
    
        /**
         * 取消语音识别
         */
        @JavascriptInterface
        public void cancelSpeechRecognizerVoice(){
            if(mAsr != null){
                mAsr.cancel();
            }
        }
    
        /**
         * 停止语音识别
         */
        @JavascriptInterface
        public void stopSpeechRecognizerVoice(){
            if(mAsr != null){
                mAsr.stopListening();
            }
        }
    
        /**
         * 解析语音json
         */
        public String parseVoice(String resultString) {
            Gson gson = new Gson();
            Voice voiceBean = gson.fromJson(resultString, Voice.class);
    
            StringBuffer sb = new StringBuffer();
            ArrayList<Voice.WSBean> ws = voiceBean.ws;
            for (Voice.WSBean wsBean : ws) {
                String word = wsBean.cw.get(0).w;
                sb.append(word);
            }
            return sb.toString();
        }
    
        /**
         * 语音对象封装
         */
        public class Voice {
    
            public ArrayList<WSBean> ws;
    
            public class WSBean {
                public ArrayList<CWBean> cw;
            }
    
            public class CWBean {
                public String w;
            }
        }

    上面方法是提供给js调用的,这是h5才会这么干,不过思路差不多哈哈,语音听写里面注释的部分就是调用原生科大讯飞UI,测试时候调用起来是这样的



    自此,也就集成成功了


    展开全文
  • 一个Android开发集成科大讯飞语音识别+语音合成功能的小Demo
  • 一、使用讯飞语音开放平台在线语音合成SDK。 优点:免费,有统计数据,发音人种类贼多。 缺点:合成次数限制,装机量限制。免费版有时候因为网络因素会有延迟,次数没通过审核前<500次/天,装机量有限,需要 ...

    前言:目前市面上的语音合成平台有很多,讯飞,百度等等。目前使用讯飞tts语音合成。

    语音合成分为方式:

    一、使用讯飞语音开放平台在线语音合成SDK。

          优点:免费,有统计数据,发音人种类贼多。

          缺点:合成次数限制,装机量限制。免费版有时候因为网络因素会有延迟,次数没通过审核前<500次/天,装机量有限,需要                     提交引用审核方可提升至<2w次/天。审核要求是应用界面有讯飞语音技术支持。

    二、使用讯飞语音开放平台离线语音合成SDK。

         优点:快,无延迟。

         缺点:收费。。。。

    三、使用讯飞语记apk,进行语音合成。

         优点:快,免费,无延迟,无装机量限制,无合成次数限制。

         缺点:需要在安卓设备上安装讯飞语记apk,然后在开发者的应用中 调用讯飞语记的tts引擎。

    前言总结:

          使用讯飞语记实现语音语音合成的好处:免费,不受制网络传输速度,发音人选择种类多,不限装机量,不限合成次数。

          实现过程:在自己的应用程序中,调用讯飞语记.apk来进行合成。下载地址:讯飞语记.apk

    使用讯飞语记的步骤:

    一、在自己的工程里加入jar包(sunflower.jar  &  Msc.jar )和各个so库,下载demo

    二、在工程里加入代码:

         1.初始化讯飞sdk:

             ①在自己的application中加入初始化讯飞sdk代码。

    private void initItfly(){        
            // 应用程序入口处调用,避免手机内存过小,杀死后台进程后通过历史intent进入Activity造成 
            //SpeechUtility对象为null
            // 注意:此接口在非主进程调用会返回null对象,如需在非主进程使用语音功能,请增加参数: 
            //SpeechConstant.FORCE_LOGIN+"=true"
            // 参数间使用“,”分隔。
            // 设置你申请的应用appid
    
            // 注意: appid 必须和下载的SDK保持一致,否则会出现10407错误
            StringBuffer param = new StringBuffer();
            param.append("appid=" + getString(R.string.app_id));
            //        param.append("appid=" + "11111111");
            //        param.append(",");
            //         设置使用v5+
            //        param.append(SpeechConstant.ENGINE_MODE + "=" + SpeechConstant.MODE_MSC);
            SpeechUtility utility = SpeechUtility.createUtility(this, param.toString());
            try {
                mSpeechSynthesizerUtil = new SpeechSynthesizerUtil(getApplicationContext());
            } catch (Exception e) {
            }
    }

               ②创建工具类 SpeechSynthesizerUtil。

    /**
     * Created by Kai .
     * time on 2017/3/20.
     * design:语音合成工具类
     */
    public class SpeechSynthesizerUtil {
        // 语音合成对象
        public SpeechSynthesizer mTts;
    
        // 默认云端发音人
        public static String voicerCloud = Constants.VOICERCLOUD;
        //    // 云端发音人列表
    //    private String[] cloudVoicersEntries;
        // 引擎类型
        private String mEngineType = SpeechConstant.TYPE_LOCAL;
        private SharedPreferences mSharedPreferencesSpeech;
    
        //缓冲进度
        private int mPercentForBuffering = 0;
        //播放进度
        private int mPercentForPlaying = 0;
        private Context mContext;
        public SpeechSynthesizerUtil(Context context) {
            this.mContext = context;
            // 初始化合成对象
            /**
             * 初始化监听。
             */
             InitListener mTtsInitListener = new InitListener() {
                @Override
                public void onInit(int code) {
                    Util.LogUtil.d("InitListener init() code = " + code);
                    if (code != ErrorCode.SUCCESS) {
                        ToastUtil.showToast("初始化失败,错误码:" + code);
                    } else {
                        // 初始化成功,之后可以调用startSpeaking方法
                        // 注:有的开发者在onCreate方法中创建完合成对象之后马上就调用startSpeaking进行合成,
                        // 正确的做法是将onCreate中的startSpeaking调用移至这里
                    }
                }
            };
    
            mTts = SpeechSynthesizer.createSynthesizer(context, mTtsInitListener);
    //       这里使用讯飞语记合成,就把下面设置参数的代码全注释掉。如果使用讯飞别的方式合成就别注释
    //        mSharedPreferencesSpeech = context.getSharedPreferences(Constants.PREFER_NAME, Activity.MODE_PRIVATE);
            // 设置参数
            // TODO:待取消注释代码
    //        Util.setSpeechParam(mTts, mEngineType, mContext, mSharedPreferencesSpeech);
    
        }
        /**
         * 开始合成
         */
        public void startSpeech(String speakContent, OnCompletedListener onCompletedListener) {
            setOnCompletedListener(onCompletedListener);
            int code = mTts.startSpeaking(speakContent, mTtsListener);
    //			/**
    //			 * 只保存音频不进行播放接口,调用此接口请注释startSpeaking接口
    //			 * text:要合成的文本,uri:需要保存的音频全路径,listener:回调接口
    //			*/
    //			String path = Environment.getExternalStorageDirectory()+"/tts.pcm";
    //			int code = mTts.synthesizeToUri(text, path, mTtsListener);
    
            if (code != ErrorCode.SUCCESS) {
                if (code == ErrorCode.ERROR_COMPONENT_NOT_INSTALLED) {
                   ToastUtil.showToast("没有安装语音+ code = " + code);
                } else {
                    ToastUtil.showToast("语音合成失败,错误码: " + code);
                }
            }
    
        }
        /**
         * 开始合成
         */
        public void startSpeech(String speakContent, SynthesizerListener listener) {
    
            int code = mTts.startSpeaking(speakContent, listener);
            //			/**
            //			 * 只保存音频不进行播放接口,调用此接口请注释startSpeaking接口
            //			 * text:要合成的文本,uri:需要保存的音频全路径,listener:回调接口
            //			*/
            //			String path = Environment.getExternalStorageDirectory()+"/tts.pcm";
            //			int code = mTts.synthesizeToUri(text, path, mTtsListener);
    
            if (code != ErrorCode.SUCCESS) {
                if (code == ErrorCode.ERROR_COMPONENT_NOT_INSTALLED) {
                    ToastUtil.showToast("没有安装语音+ code = " + code);
                } else {
                    ToastUtil.showToast("语音合成失败,错误码: " + code);
                }
            }
    
        }
    
        //注册合成完毕后的监听事件
        private OnCompletedListener mOnCompletedListener;
        public void setOnCompletedListener(OnCompletedListener mOnCompletedListener) {
            this.mOnCompletedListener = mOnCompletedListener;
        }
        public interface OnCompletedListener {
            void OnCompleted();
        }
    
        /**
         * 合成回调监听。
         */
        public SynthesizerListener mTtsListener = new SynthesizerListener() {
    
            @Override
            public void onSpeakBegin() {
                Util.LogUtil.i("开始播放");
            }
    
            @Override
            public void onSpeakPaused() {
                Util.LogUtil.i("暂停播放");
            }
    
            @Override
            public void onSpeakResumed() {
                Util.LogUtil.i("继续播放");
            }
    
            @Override
            public void onBufferProgress(int percent, int beginPos, int endPos,
                                         String info) {
                //            ToastUtil.showToast(mContext,String.format(mContext.getString(R.string.tts_toast_format),
            }
    
            @Override
            public void onSpeakProgress(int percent, int beginPos, int endPos) {
                // 播放进度
                mPercentForPlaying = percent;
            }
    
            @Override
            public void onCompleted(SpeechError error) {
                if(mOnCompletedListener!=null)
                mOnCompletedListener.OnCompleted();
                if (error == null) {
                } else if (error != null) {
                    ToastUtil.showToast(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);
                //	}
            }
        };
    
    }
    

     

         2.判断本安卓设备是否下载讯飞语记录,没有就去下载。

                //判断本机是否安装了讯飞语记
                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 {
                    //已安装,开始合成TODO:
                    
                }

         3.语音合成代码。 

    /**
    * 第二个参数如果不想监听说话完毕的状态就传null,想监听就实现这个接口
    */
    SampleApplication.getSpeechSynthesizerUtil().startSpeech("说话",this);

    三、打开讯飞语记,设置自己喜欢的发音人,设置tts引擎。

        通用设置-->语音合成设置-->

    展开全文
  • Android 讯飞语音合成

    2016-07-18 15:17:51
    首先,需要先去科大讯飞官网申请帐号,以及创建应用,创建应用后可以进入我的应用查看APPID,并开通“讯飞语音合成”服务。然后下载对应的SDK,并进行以下步骤 http://www.xfyun.cn/Step1:导包EclipseAndroid ...

    .
    .

    首先,需要先去科大讯飞官网申请帐号,以及创建应用,创建应用后可以进入我的应用查看APPID,并开通“讯飞语音合成”服务。然后下载对应的SDK,并进行以下步骤
    http://www.xfyun.cn/

    Step1:导包

    Eclipse

    这里写图片描述

    Android Studio

    Project视图:
    这里写图片描述

    Step2:添加权限

    官方给出的权限,根据自己需要添加

    <!--连接网络权限,用于执行云端语音能力 -->  
    <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.CAMERA" />    

    Step3:初始化

    // 将“12345678”替换成您申请的APPID,申请地址:http://open.voicecloud.cn  
    SpeechUtility.createUtility(context, SpeechConstant.APPID +"=12345678");   

    Step4:具体代码

    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.EditText;
    
    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;
    
    public class MainActivity extends Activity {
    
        SpeechSynthesizer mTts;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            SpeechUtility.createUtility(this, SpeechConstant.APPID + "=123456");//APPID在科大讯飞官网申请,申请地址:http://open.voicecloud.cn
            //注意:此接口在非主进程调用会返回null对象,如需在非主进程使用语音功能,请使用参数:SpeechConstant.APPID +"=12345678," + SpeechConstant.FORCE_LOGIN +"=true"。
            mTts = SpeechSynthesizer.createSynthesizer(this, null);
            setSpeech(); //设置语音参数
    
            //点击Button阅读EditText里的内容
            findViewById(R.id.btnSpeak).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    EditText et = (EditText) findViewById(R.id.et);
                    mTts.startSpeaking(et.getText().toString(), mSynListener);
                }
            });
        }
    
        /**
         * 设置语音阅读参数
         */
        private void setSpeech() {
            //2.合成参数设置,详见《科大讯飞MSC API手册(Android)》SpeechSynthesizer 类
            mTts.setParameter(SpeechConstant.VOICE_NAME, "xiaoyan");//设置发音人
            mTts.setParameter(SpeechConstant.SPEED, "50");//设置语速
            mTts.setParameter(SpeechConstant.VOLUME, "80");//设置音量,范围0~100
            mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD); //设置云端
            //保存在SD卡需要在AndroidManifest.xml添加写SD卡权限
            // mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH, "./sdcard/iflytek.pcm");
        }
    
        /**
         * 合成监听器
         */
        private SynthesizerListener mSynListener = new SynthesizerListener() {
    
            //会话结束回调接口,没有错误时,error为null
            public void onCompleted(SpeechError error) {
            }
    
            //缓冲进度回调
            //percent为缓冲进度0~100,beginPos为缓冲音频在文本中开始位置,endPos表示缓冲音频在文本中结束位置,info为附加信息。
            public void onBufferProgress(int percent, int beginPos, int endPos, String info) {
            }
    
            //开始播放
            public void onSpeakBegin() {
            }
    
            //暂停播放
            public void onSpeakPaused() {
            }
    
            //播放进度回调
            //percent为播放进度0~100,beginPos为播放音频在文本中开始位置,endPos表示播放音频在文本中结束位置.
            public void onSpeakProgress(int percent, int beginPos, int endPos) {
            }
    
            //恢复播放回调接口
            public void onSpeakResumed() {
            }
    
            //会话事件回调接口
            public void onEvent(int arg0, int arg1, int arg2, Bundle arg3) {
            }
    
        };
    }
    
    展开全文
  • 讯飞语音合成引擎

    2020-07-13 23:31:45
    讯飞语音合成引擎 亲测很好用 解压缩安装即可对于中文语音的识别率能够达到90%以上,应用领域语义理解正确率85%以上。 语音合成软件有很多种,那些轻量级的、体积小的语音合成软件一般都是电脑合成语音或联网读取...
  • 项目中遇到讯飞语音转成WAV,我是这样做的,首先生成.pcm文件,然后再.pcm与.wav互换,最终由MediaPlayer播放,还有进度条之类的小知识点 首先上布局 <LinearLayout xmlns:android=...

    项目中遇到讯飞语音转成WAV,我是这样做的,首先生成.pcm文件,然后再.pcm与.wav互换,最终由MediaPlayer播放,还有进度条之类的小知识点
    首先上布局

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >
        <EditText
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:id="@+id/edit"/>
    <LinearLayout
        android:layout_marginBottom="15dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button android:id="@+id/play"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="播放"
            />
        <Button android:id="@+id/pause"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="暂停"
            />
    
    </LinearLayout>
    
    
        <SeekBar android:id="@+id/sb"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:max="100"
            />
    
    </LinearLayout>

    然后是.pcm与.WAV互换工具类

    public class PcmToWavUtil {
        private int mBufferSize;  //缓存的音频大小
        private int mSampleRate = 8000;// 8000|16000
        private int mChannel = AudioFormat.CHANNEL_IN_STEREO;   //立体声
        private int mEncoding = AudioFormat.ENCODING_PCM_16BIT;
    
        public PcmToWavUtil() {
            this.mBufferSize = AudioRecord.getMinBufferSize(mSampleRate, mChannel, mEncoding);
        }
    
        /**
         * @param sampleRate sample rate、采样率
         * @param channel    channel、声道
         * @param encoding   Audio data format、音频格式
         */
        public PcmToWavUtil(int sampleRate, int channel, int encoding) {
            this.mSampleRate = sampleRate;
            this.mChannel = channel;
            this.mEncoding = encoding;
            this.mBufferSize = AudioRecord.getMinBufferSize(mSampleRate, mChannel, mEncoding);
        }
    
        /**
         * pcm文件转wav文件
         *
         * @param inFilename  源文件路径
         * @param outFilename 目标文件路径
         */
        public void pcmToWav(String inFilename, String outFilename) {
            FileInputStream in;
            FileOutputStream out;
            long totalAudioLen;
            long totalDataLen;
            long longSampleRate = mSampleRate;
            int channels = 2;
            long byteRate = 16 * mSampleRate * channels / 8;
            byte[] data = new byte[mBufferSize];
            try {
                in = new FileInputStream(inFilename);
                out = new FileOutputStream(outFilename);
                totalAudioLen = in.getChannel().size();
                totalDataLen = totalAudioLen + 36;
    
                writeWaveFileHeader(out, totalAudioLen, totalDataLen,
                        longSampleRate, channels, byteRate);
                while (in.read(data) != -1) {
                    out.write(data);
                }
                in.close();
                out.close();
            }  catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 加入wav文件头
         */
        private void writeWaveFileHeader(FileOutputStream out, long totalAudioLen,
                                         long totalDataLen, long longSampleRate, int channels, long byteRate)
                throws IOException {
            byte[] header = new byte[44];
            header[0] = 'R'; // RIFF/WAVE header
            header[1] = 'I';
            header[2] = 'F';
            header[3] = 'F';
            header[4] = (byte) (totalDataLen & 0xff);
            header[5] = (byte) ((totalDataLen >> 8) & 0xff);
            header[6] = (byte) ((totalDataLen >> 16) & 0xff);
            header[7] = (byte) ((totalDataLen >> 24) & 0xff);
            header[8] = 'W';  //WAVE
            header[9] = 'A';
            header[10] = 'V';
            header[11] = 'E';
            header[12] = 'f'; // 'fmt ' chunk
            header[13] = 'm';
            header[14] = 't';
            header[15] = ' ';
            header[16] = 16;  // 4 bytes: size of 'fmt ' chunk
            header[17] = 0;
            header[18] = 0;
            header[19] = 0;
            header[20] = 1;   // format = 1
            header[21] = 0;
            header[22] = (byte) channels;
            header[23] = 0;
            header[24] = (byte) (longSampleRate & 0xff);
            header[25] = (byte) ((longSampleRate >> 8) & 0xff);
            header[26] = (byte) ((longSampleRate >> 16) & 0xff);
            header[27] = (byte) ((longSampleRate >> 24) & 0xff);
            header[28] = (byte) (byteRate & 0xff);
            header[29] = (byte) ((byteRate >> 8) & 0xff);
            header[30] = (byte) ((byteRate >> 16) & 0xff);
            header[31] = (byte) ((byteRate >> 24) & 0xff);
            header[32] = (byte) (2 * 16 / 8); // block align
            header[33] = 0;
            header[34] = 16;  // bits per sample
            header[35] = 0;
            header[36] = 'd'; //data
            header[37] = 'a';
            header[38] = 't';
            header[39] = 'a';
            header[40] = (byte) (totalAudioLen & 0xff);
            header[41] = (byte) ((totalAudioLen >> 8) & 0xff);
            header[42] = (byte) ((totalAudioLen >> 16) & 0xff);
            header[43] = (byte) ((totalAudioLen >> 24) & 0xff);
            out.write(header, 0, 44);
        }
    }
    

    最后看大布局

    public class Voice_Activity extends Activity {
        /** Called when the activity is first created. */
        private Voice_BroadcaseUtil voice_broadcaseUtil;
        private EditText edit;
        private Context context=this;
        private  ListView list;
        private  Button play,pause,resume;
        private MediaPlayer mp;
        private   SeekBar sb;
        private Handler handler=new Handler();
        private  int Duration;
        private String content;
       private PcmToWavUtil pcmToWavUtil = new PcmToWavUtil();
        public Voice_Activity voice;
        private List<Voice_Data> voiceData = new ArrayList<>();
        public static String SDPATH ="/sdcard/" ;//获取文件夹
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_voice_test);
            voice=new Voice_Activity();
            initView();
            initData();
            voice_broadcaseUtil=new Voice_BroadcaseUtil(context);
               }
    
    
        private void initView() {
            edit=(EditText)findViewById(R.id.edit);
            play=(Button)findViewById(R.id.play);
            pause=(Button)findViewById(R.id.pause);
            sb=(SeekBar)findViewById(R.id.sb);
             mp = new MediaPlayer();
            //找到相应View
    
            //后面的参数必须是URI形式的,所以要把相应路径转换成URI
            play.setOnClickListener(playlis);
            pause.setOnClickListener(pauselis);
            sb.setOnSeekBarChangeListener(sbLis);
            adapter=new GridAdapter(context,ar);
            list.setAdapter(adapter);
            testRandom1();
        }
    
    
    
    
    
    
        public static void delFile(String fileName){
            File file = new File(SDPATH + fileName);
            if(file.isFile()){
                file.delete();
            }
            file.exists();
        }
    
        private OnClickListener playlis=new OnClickListener(){
            @Override
            public void onClick(View v) {
                System.out.println(edit.getText().toString().length());
               delFile("speak_result.pcm");//这两行一定要否则,一直都会读上一个文件的内容,导致刷新不及时,点的不是读的
                delFile("speak_result.wav");
                voice_broadcaseUtil.toVoiceStartSave(edit.getText().toString());
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        final String path = "/sdcard/speak_result.pcm" ;
                        final String outpath = path.replace(".pcm", ".wav");
                        pcmToWavUtil.pcmToWav(path, outpath);//转换
                        Toast.makeText(context, "正在拉取资源。请稍后...", Toast.LENGTH_SHORT).show();
                    }
                },edit.getText().toString().length()*100);
    
    
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            mp.reset();//这句很关键,没有这句会报状态异常错误,而且很难排查
                            mp.setDataSource(context, Uri.parse("/sdcard/speak_result.wav"));
                            mp.prepare();//这句也很重要,没有这句无法正常播放
                            System.out.println("执行了啊");
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        Duration=mp.getDuration();//时间
                        sb.setMax(Duration);//进度条最大时间
                        handler.post(start);
                        Toast.makeText(context, "请稍后...", Toast.LENGTH_LONG).show();
                    }
                },edit.getText().toString().length()*100);
                //调用handler播放
                }
        };
        Runnable start=new Runnable(){
    
            @Override
            public void run() {
                mp.start();
                handler.post(updatesb);
                //用一个handler更新SeekBar
            }
        };
        Runnable updatesb =new Runnable(){
            @Override
            public void run() {
    
                        sb.setProgress(mp.getCurrentPosition());
                        // sb.setProgress();
                        handler.postDelayed(updatesb, 100);//每100毫秒修改一次进度条
    
                  }
        };
        private OnClickListener pauselis=new OnClickListener(){
    
            @Override
            public void onClick(View v) {
                if(mp.isPlaying()){
                    mp.pause();//暂停播放
                    pause.setText("继续");
                }else{
                    mp.start();//继续播放
                    pause.setText("暂停");
    
                }
    
            }
    
        };
        private OnSeekBarChangeListener sbLis=new OnSeekBarChangeListener(){
    
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress,
                                          boolean fromUser) {
                // TODO Auto-generated method stub
            }
    
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                // TODO Auto-generated method stub
    
            }
    
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                // TODO Auto-generated method stub
                mp.seekTo(sb.getProgress());
                //SeekBar确定位置后,跳到指定位置
            }
    
        };
        public void refresh() {
            onCreate(null);
        }
        private void showTip(String string){
            Toast.makeText(context, string, Toast.LENGTH_SHORT).show();
        }
    
    
    }

    快进和快退

     case R.id.next_up:
                    System.out.println("快退");
                    mp.seekTo(mp.getCurrentPosition() - 5000);
                    break;
                case R.id.next_down:
                    mp.seekTo(mp.getCurrentPosition() + 5000);

    上几张图
    这里写图片描述

    展开全文
  • 这篇将讯飞语音合成api的使用,上一篇讲的百度api 本来的思路是在线请求,然后返回音频播放,然后了解到不论是百度的还是讯飞的一次转换数量都有限,这样的话分割文章会返回多个语音,然后上面的进度条就是一条语音...
  • Android系统从1.6版本开始就支持TTS(Text-To-Speech),即语音合成。但是android系统默认的TTS引擎:Pic TTS不支持中文。所以我们得安装自己的TTS引擎和语音包。在项目中,一开始用的是手说TTS,免费版的,感觉声音很...
  • 了解与掌握语音的合成技术更是掌握了一项技能,当然本文就是从浅层入手,了解使用讯飞语音平台提供的 API 的使用;能够通过一些简单的配置来使用该项技术。不管怎样多学点儿总归是好的。  如果你还不会在讯飞语音...
  • 创建讯飞应用:在讯飞开发平台注册账号,在网站上创建应用,得到一个APPID,这个ID用来绑定讯飞SDK和自己制作的APP创建SDK:...创建android Studio项目:新建项目,修改项目名(如VoiceDemo)后其余都为默认,创建...
  • 下面就展示一个根据讯飞SDK文档做出的具有语音识别和语音合成功能的小Demo。 首先,第一步当然是去讯飞官网注册账号,创建应用并获得一个AppID,然后下载相应的SDK,我这里只下了两个,分别是语音听写和语音合成的...
  • 讯飞语音合成有多个发音人,如何选择一个合适的发音人呢?我的解决方法是,选择符合要求的,然后每个都听一遍.最后选出一个合适的. 我的要求 我是用来朗读技术文章的,文章中要英文也有中文,所以我要选择支持中英文的...
  • 语音合成: 与语音听写相反,语音合成是将一段文字转换为语音,可根据需要合成出不同音色、语速和语调的声音,让机器像人一样开口说话 效果图 2、直接上代码,配置不再重复说明了: ①、TTSActivity.java public ...
  • 最近用到了,讯飞语音,所以简单给大家介绍一下怎么加入语音朗读; Step 1: 首先你需要申请一个 appid,去讯申请吧; Step 2: 按照文档导入sdk,加入权限; Step 3: 初始化sdk; ...
  • 讯飞语音语音合成

    2017-02-24 11:08:02
    因为一个项目的需要,开始接触这个...第二部:导入jar包和so文件 论坛上大多代码是eclipse的,比较简单,这里介绍一下Android Studio的导入方法: 1、首先,将左侧的显示改成project视图 2、将下载的讯飞语音包内 lib
  • 讯飞离线语音合成接入: 文字转语音的方法 1.Google TextToSpeech + 中文语音引擎 Google提供了原生的方法TextToSpeech,但是不支持中文,sad… 不过可以用第三方的语音引擎,eg,讯飞,百度… 详情参考: Android ...
  • 在线语音合成,需要下载对应app id的SDK包。 1、解压,目录拷贝位置,与app同级别: 2、在build.gradle文件中添加: sourceSets { main { jniLibs.srcDirs = ['libs'] } } 在dependencies添加: compile ...
  • 讯飞离线语音合成(离线资源包) 讯飞语音合成有三种方式 在线语音合成(免费) 离线使用语记语音合成(免费,需要本地装一个语记App并且下载离线资源) 使用讯飞离线语音包(付费) 这里使用离线资源包...
  • //percent为播放进度0~100,beginPos为播放音频在文本中开始位置,endPos表示播放音频在文 本中结束位置. 我在这里这样获取播放...我发现这个值一直是0,语音播放前,播放结束都是0.怎样才能获取到播放进度这个值?
1 2 3 4 5 ... 20
收藏数 728
精华内容 291