溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

語音識別,語義理解一站式解決(android平臺&olami sdk)

發布時間:2020-07-31 07:50:30 來源:網絡 閱讀:1263 作者:ls0609 欄目:移動開發

  

olami sdk語音識別語義理解做在線聽書

olamisdk實現了把錄音或者文字轉化為用戶可以理解的json字符串,本文使用olami sdk做了一個在線聽書的demo,用的是喜馬拉雅的在線聽書sdk.基于eclipse開發環境,libs目錄下jarso文件如下:

olami-android-sdk.jar//olami sdk jar

afinal_0.5.1_bin.jar

litepal.jar

gson-2.2.4.jar

okhttp-2.4.0.jar

okhttp-urlconnection-2.2.0.jar

okio-1.4.0.jar

opensdk.jar          //上面這幾個都是喜馬拉雅需要的jar

libspeex.so          //olami sdk 需要用到speex壓縮功能

libxmediaplayer.so   // 喜馬拉雅so

libxmediaplayer_x.so// 喜馬拉雅so

概述 
VoiceSdkService中定義了OlamiVoiceRecognizer語音識別引擎,通過點擊MusicActivity的開始button啟動錄音,錄音結果在VoiceSdkService中的onResult()回調中拿到識別的Json字符串,在processServiceMessage()函數中處理后找到要聽書的名稱,然后進入BookUtil進行搜索,搜索到結果后通知VoiceSdkService進行播放,并通知MusicActivity更新播放進度等信息。

 

 

 

 

 

 

1.AndroidManifest.xml配置

<?xml version="1.0"encoding="utf-8"?>

    <manifestxmlns:android="http://schemas.android.com/apk/res/android"

       package="com.olami.musicdemo"

       android:versionCode="1"

       android:versionName="1.0" >

 

       <uses-sdk

           android:minSdkVersion="8"

           android:targetSdkVersion="21" />

 

       <uses-permissionandroid:name="android.permission.RECORD_AUDIO"/>

       <uses-permissionandroid:name="android.permission.INTERNET"/>

       <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

       <uses-permissionandroid:name="android.permission.ACCESS_WIFI_STATE"/>

       <uses-permissionandroid:name="android.permission.READ_PHONE_STATE"/>

       <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

       <uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE" />

 

       <application

           android:name="com.olami.musicdemo.OlamiApplication"

           android:allowBackup="true"

           android:icon="@drawable/ic_launcher"

           android:label="@string/app_name"

           android:theme="@style/AppTheme" >

 

           <!--喜馬拉雅聽書測試賬號app_key-->

           <meta-data

               android:name="app_key"

                android:value="b617866c20482d133d5de66fceb37da3"/>

           <!--喜馬拉雅聽書測試賬號包名-->

           <meta-data

               android:name="pack_id"

               android:value="com.app.test.android" />

 

           <activity

               android:name=".MusicActivity"

               android:label="@string/app_name" >

                <intent-filter>

                    <actionandroid:name="android.intent.action.MAIN" />

 

                    <categoryandroid:name="android.intent.category.LAUNCHER" />

                </intent-filter>

           </activity>

 

            <!--注冊olami sdk service-->

           <service

               android:name=".VoiceSdkService"

               android:exported="true" >

           </service>

 

           <!--注冊喜馬拉雅聽書service-->

            <service               

              android:name=

            "com.ximalaya.ting.android.opensdk.player.service.XmPlayerService"

           />

       </application>

 

</manifest>

2.layout布局文件

layout_musicview.xml

TextView 有兩個,tv_name顯示聽書的名稱, tv_totoal_time顯示聽書的總時間。 
ProgressBar
實時刷新顯示聽書的進度

<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"

 xmlns:tools="http://schemas.android.com/tools"

  android:layout_width="fill_parent"

 android:layout_height="wrap_content"

  android:background="@android:color/transparent">

 

 

    <TextView

        android:text="name"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:layout_marginTop="5dp"

        android:layout_centerHorizontal="true"

       android:id="@+id/tv_name"/>

 

    <ProgressBar

       

       android:layout_width="fill_parent"

       android:layout_height="wrap_content"

       android:layout_below="@+id/tv_name"

       android:layout_marginTop="10dp"

       android:layout_marginLeft="20dp"

       android:layout_marginRight="20dp"

       android:id="@+id/progressbar_music"/>

 

    <TextView

        android:text="total_time"

        android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:layout_below="@+id/progressbar_music"

       android:layout_marginTop="10dp"

       android:layout_centerHorizontal="true"

       android:id="@+id/tv_total_time"/>

 

</RelativeLayout>

 

activity_music.xml

<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"

   xmlns:tools="http://schemas.android.com/tools"

   android:layout_width="match_parent"

   android:layout_height="match_parent"

   android:paddingLeft="@dimen/activity_horizontal_margin"

   android:paddingRight="@dimen/activity_horizontal_margin"

   tools:context="com.olami.musicdemo.MusicActivity" >

 

   <TextView

       android:id="@+id/tv_inputText"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:layout_marginTop="5dp"

       android:text="輸入:" />

 

   <TextView

       android:id="@+id/tv_volume"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:layout_alignLeft="@+id/tv_inputText"

       android:layout_below="@+id/tv_inputText"

       android:layout_marginTop="40dp"

       android:text="音量:" />

 

   <TextView

       android:id="@+id/tv_result"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:layout_below="@+id/tv_volume"

       android:layout_marginTop="20dp"

       android:maxLines="15"

       android:ellipsize="end"

       android:text="服務器返回sentence:"

       android:visibility="visible" />

 

   <com.olami.musicdemo.MusicView

       android:id="@+id/music_view"

       android:layout_width="fill_parent"

       android:layout_height="80dp"

       android:layout_centerInParent="true"

       >

   </com.olami.musicdemo.MusicView>

 

   <EditText

       android:id="@+id/et_content"

       android:layout_width="wrap_content"

       android:layout_height="40dp"

       android:layout_above="@+id/btn_stop"

       android:layout_alignLeft="@+id/tv_inputText"

       android:layout_marginBottom="10dp"

       android:layout_toLeftOf="@+id/btn_send"

       android:background="#E7E7E7"

       android:singleLine="true"

       android:text="上海的天氣" />   

 

    <Button

       android:id="@+id/btn_send"

        android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:layout_alignBaseline="@+id/et_content"

       android:layout_alignBottom="@+id/et_content"

       android:layout_alignParentRight="true"

       android:text="提交" />

 

   <Button

       android:id="@+id/btn_start"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content" 

       android:layout_alignParentBottom="true"

       android:layout_centerHorizontal="true"

       android:text="開始" />

 

   <Button

       android:id="@+id/btn_stop"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:layout_alignLeft="@+id/et_content"

       android:layout_alignParentBottom="true"

       android:text="停止" />

 

   <Button

       android:id="@+id/btn_cancel"

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       android:layout_alignParentBottom="true"

       android:layout_toRightOf="@+id/et_content"

       android:text="取消" />

 

</RelativeLayout>

 

自定義MusicView比較簡單,代碼如下:

public class MusicView extendsRelativeLayout{

   private Context mContext;

   private Handler mHandler;

   private TextView mTextViewName;

   private TextView mTextViewTotalTime;

   private ProgressBar mProgressBar;

   public MusicView(Context context,AttributeSet attrs) {

       super(context,attrs);

       LayoutInflater inflater =(LayoutInflater) context.getSystemService(

                                            context.LAYOUT_INFLATER_SERVICE);

       RelativeLayout view = (RelativeLayout) inflater.inflate

(R.layout.layout_musicview,this,true);

       mTextViewName = (TextView) view.findViewById(R.id.tv_name);

       mTextViewTotalTime = (TextView) view.findViewById(R.id.tv_total_time);

       mProgressBar = (ProgressBar)view.findViewById(R.id.progressbar_music);

 

    }

 

   public void initMusicView(Context context,Handler handler)

    {

       mContext = context;

       mHandler = handler;

    }

 

   public void setMusicName(String name)

   {//設置播放名稱

       mTextViewName.setText(name);

    }

 

   public void setProgress(int progress)

   {//設置播放進度

       mProgressBar.setProgress(progress);

    }

 

   public void setTotalTime(String time)

   {//設置播放總時間

       mTextViewTotalTime.setText(time);

    }

}

布局效果圖如下: 

語音識別,語義理解一站式解決(android平臺&olami sdk)

 

 

3.MusicActivityVoiceSdkService通信

本文沒有用bindservice的方式實現activityservice的消息通信。 
MusicAcitity
VoiceSdkService中分別實現了一個CommunicationAssist的接口

 

public interface CommunicationAssist {

   public void callBack(int what, int arg1, int arg2,Bundle data, Objectobj);

}

然后把他們分別實現CommunicationAssist接口的變量注冊到OlamiApplication,這樣通過OlamiApplication實現了MusicAcitity VoiceSdkService橋接。

 

3.1OlamiApplication

1) 注冊MusicActivityVoiceSdkService的回調

public voidsetActivityToServiceListener(CommunicationAssist listener)

{

  ActivityToServiceListener = listener;

}

這個是在VoiceSdkService中調用setActivityToServiceListener(),VoiceSdkService中的VoiceSdkComAssist注冊到application中,MusicActivity中可以通過getActivityToServiceListener 
這個函數回調向VoiceSdkService發送消息。

 

2) 注冊 VoiceSdkServiceMusicActivity回調

public voidsetServiceToActivityListener(CommunicationAssist listener)

{

 mServiceToActivityListener = listener;

}

 

這個是在MusicAcitivity中調用setServiceToActivityListener(),這樣在VoiceSdkService中就可以通過getServiceToActivityListener()獲得回調向MusciActivity發送消息。

 

3.2MusicActivity

public class MusicActivity extends Activity{

   private Handler mHandler;

   private Handler mInComingHandler;

   private ActivityComAssist mActivityComAssist;

   private Button mBtnStart;

   private Button mBtnStop;

   private Button mBtnCancel;

   private Button mBtnSend;

   private EditText mEditText;

   private TextView mTextView;

   private TextView mInputTextView;

   private TextView mTextViewVolume;

   private BookUtil mBookUtil = null;

   private MusicView mMusicView = null;

 

   @Override

   protected void onCreate(Bundle savedInstanceState) {

       super.onCreate(savedInstanceState);

       setContentView(R.layout.activity_music);

       initHandler();//初始化handler用于內部消息處理

       initInComingHandler();//用于處理來自VoiceSdkService的消息

       initCommunicationAssist();//application注冊消息回調,VoiceSdkSerive可以

                //通過getServiceToActivityListener()獲得回調向MusicActivity發送消息

       initView();//初始化view控件

       Intent intent = new Intent();

       intent.setClass(MusicActivity.this, VoiceSdkService.class);

       startService(intent);//啟動后臺服務

 

    }

 

   private void initView()

    {

       mBtnStart = (Button) findViewById(R.id.btn_start);

       mBtnStop = (Button) findViewById(R.id.btn_stop);

       mBtnCancel = (Button) findViewById(R.id.btn_cancel);

       mBtnSend = (Button) findViewById(R.id.btn_send);

       mInputTextView = (TextView) findViewById(R.id.tv_inputText);

       mEditText = (EditText) findViewById(R.id.et_content);

       mTextView = (TextView) findViewById(R.id.tv_result);

       mTextViewVolume = (TextView) findViewById(R.id.tv_volume);

 

        mBtnStart.setOnClickListener(newOnClickListener(){

 

           @Override

           public void onClick(View v) {

               sendMessageToService(MessageConst.CLIENT_ACTION_START_RECORED,0,0,null,null);

           }          

       });

 

       mBtnStop.setOnClickListener(new OnClickListener(){

 

           @Override

           public void onClick(View v) {

               sendMessageToService(MessageConst.CLIENT_ACTION_STOP_RECORED,0,0,null,null);

                mBtnStart.setText("開始");

               Log.i("led","MusicActivity mBtnStop onclick 開始");

           }          

       });

 

       mBtnCancel.setOnClickListener(new OnClickListener(){

 

           @Override

           public void onClick(View v) {

                sendMessageToService(MessageConst.CLIENT_ACTION_CANCEL_RECORED,0,0,null,null);

           }          

       });

 

       mBtnSend.setOnClickListener(new OnClickListener(){

 

           @Override

                public void onClick(View v) {

           sendMessageToService(

           MessageConst.CLIENT_ACTION_SENT_TEXT,0,0,null,mEditText.getText());

                mInputTextView.setText("文字:"+mEditText.getText());

           }          

       });

 

       mMusicView = (MusicView) findViewById(R.id.music_view);

       //if(mMusicView != null)

           //mMusicView.initMusicView(MusicActivity.this,mHandler);

 

    }

 

   private void initHandler()

    {

       mHandler = new Handler(){

           @Override

           public voidhandleMessage(Message msg)

           {

                switch (msg.what){

                caseMessageConst.CLIENT_ACTION_START_RECORED:

                    break;

                default:

                    break; 

                }

            }

       };

    }

   //InComingHandler 收到來自VoiceSdkService的消息用于更新界面,

   //包括開始錄音,結束錄音,播放的書的名稱和進度,音量等信息。

   private void initInComingHandler()

    {

       mInComingHandler = new Handler(){

           @Override

           public void handleMessage(Message msg)

           {

                switch (msg.what){

                caseMessageConst.CLIENT_ACTION_START_RECORED:

                    mBtnStart.setText("錄音中");

                   Log.i("led","MusicActivity 錄音中");

                    break;

                caseMessageConst.CLIENT_ACTION_STOP_RECORED:

                    mBtnStart.setText("識別中");

                   Log.i("led","MusicActivity 識別中");

                    break;

                caseMessageConst.CLIENT_ACTION_CANCEL_RECORED:

                    mBtnStart.setText("開始");

                    mTextView.setText("已取消");

                    break;

                caseMessageConst.CLIENT_ACTION_ON_ERROR:

                    mTextView.setText("錯誤代碼:"+msg.arg1);

                    mBtnStart.setText("開始");

                    break;

                caseMessageConst.CLIENT_ACTION_UPDATA_VOLUME:

                   mTextViewVolume.setText("音量: "+msg.arg1);

                    break;

                caseMessageConst.SERVER_ACTION_RETURN_RESULT:

                   //mTextView.setText(msg.obj.toString());

                    mBtnStart.setText("開始");

                    break;

                caseMessageConst.CLIENT_ACTION_PLAY_BOOK_AFTER_SEARCH:

                    mBtnStart.setText("開始");

                    mBookUtil =BookUtil.getInstance();

                    mBookUtil.play(msg.arg1);

                    break;

                caseMessageConst.CLIENT_ACTION_UPDATA_PLAYING_BOOK_NAME:

                    mMusicView.setMusicName(msg.obj.toString());

                    break;

                caseMessageConst.CLIENT_ACTION_UPDATE_BOOK_PROGRESS:

                    int current = msg.arg1;

                    int duration = msg.arg2;

                   mMusicView.setProgress(current*100/duration);

                    float time =duration/1000/60;

                   mMusicView.setTotalTime("總時間:"+time);

                    break;

                caseMessageConst.CLIENT_ACTION_UPDATA_INPUT_TEXT:

                    if(msg.obj != null)

                      mInputTextView.setText("文字:"+msg.obj.toString());

                    break;

                caseMessageConst.CLIENT_ACTION_UPDATA_SERVER_MESSAGE:

                    if(msg.obj != null)

                        mTextView.setText("服務器返回sentence:"+msg.obj.toString());

                    break;

                default:

                    break;

                }

           }

       };

    }

 

   private void initCommunicationAssist()

   {//Application注冊VoiceSdkServiceMusicActivity的回調

       mActivityComAssist = new ActivityComAssist();

       OlamiApplication.getInstance().setServiceToActivityListener(mActivityComAssist);

    }

 

   private void sendMessageToService(int what, int arg1, int arg2, Bundledata, Object obj)

   {//VoiceSdkService發送消息

       if(OlamiApplication.getInstance().getActivityToServiceListener() !=null)

           OlamiApplication.getInstance().getActivityToServiceListener().callBack

           (what, arg1, arg2, data, obj);

    }

 

   private class ActivityComAssist implements CommunicationAssist{

   //實現CommunicationAssist借口,用于回調VoiceSdkService發送過來的消息

       @Override

       public void callBack(int what, int arg1, int arg2, Bundle data,Objectobj) {

           Message msg = Message.obtain(null, what);

           msg.arg1 = arg1;

           msg.arg2 = arg2;

           if (data != null)

                msg.setData(data);

           if (obj != null)

                msg.obj = obj;

           mInComingHandler.sendMessage(msg);

       }       

    }

 

   @Override

   public void onDestroy() {

       //退出應用,停止VoiceSdkService,會進行資源的釋放

       super.onDestroy();

       Intent intent = new Intent();

       intent.setClass(MusicActivity.this, VoiceSdkService.class);

       stopService(intent);

    }

}

3.3VoiceSdkService

@Override

public void onCreate() {

   initHandler();//用于內部消息處理

   initInComingHandler();//用于處理來自MusicActivity的消息

   initCommunicationAssist();//application注冊消息回調,這樣MusicActivity

   //以通過getActivityToServiceListener()回調向VoiceSdkService發送消息

   initViaVoiceRecognizerListener();//初始化錄音識別回調listener

   init();//olami錄音識別引擎初始化

   initXmly();//喜馬拉雅初始化

}

 

public void init()

{

   initHandler();

   mOlamiVoiceRecognizer = new OlamiVoiceRecognizer(VoiceSdkService.this);

   TelephonyManager telephonyManager=(TelephonyManager)this.getSystemService(

   (this.getBaseContext().TELEPHONY_SERVICE);

   String imei=telephonyManager.getDeviceId();

   mOlamiVoiceRecognizer.init(imei);//設置身份標識,可以填null

 

   mOlamiVoiceRecognizer.setListener(mOlamiVoiceRecognizerListener);//設置識別結果回調listener

   mOlamiVoiceRecognizer.setLocalization(

   OlamiVoiceRecognizer.LANGUAGE_SIMPLIFIED_CHINESE);//設置支持的語音類型,優先選擇中文簡體

   mOlamiVoiceRecognizer.setAuthorization("51a4bb56ba954655a4fc834bfdc46af1",

                           "asr","68bff251789b426896e70e888f919a6d","nli"); 

   //注冊Appkey,在olami官網注冊應用后生成的appkey

   //注冊api,請直接填寫“asr”,標識語音識別類型

   //注冊secret,在olami官網注冊應用后生成的secret

   //注冊seq ,請填寫“nli

 

   mOlamiVoiceRecognizer.setVADTailTimeout(2000);//錄音時尾音結束時間,建議填//2000ms

   //設置經緯度信息,不愿上傳位置信息,可以填0

   mOlamiVoiceRecognizer.setLatitudeAndLongitude(31.155364678184498,121.34882432933009);

}

 

定義OlamiVoiceRecognizerListener

onError(int errCode)//出錯回調,可以對比官方文檔錯誤碼看是什么錯誤 
onEndOfSpeech()//
錄音結束 
onBeginningOfSpeech()//
錄音開始 
onResult(String result, int type)//result
是識別結果JSON字符串 
onCancel()//
取消識別,不會再返回識別結果 
onUpdateVolume(int volume)//
錄音時的音量,1-12個級別大小音量

下面是VoiceSdkService完整代碼:

 

public class VoiceSdkService extends Service{

 

   private Handler mHandler;

   private Handler mInComingHandler;

   private VoiceSdkComAssist mVoiceSdkComAssist;

   private OlamiVoiceRecognizer mOlamiVoiceRecognizer;

   private OlamiVoiceRecognizerListener mOlamiVoiceRecognizerListener;

    privateBookUtil mBookUtil = null;

   private boolean mIsRecordPause = false;

 

   @Override

   public void onCreate() {

       initHandler();

       initInComingHandler();

       initCommunicationAssist();

       initViaVoiceRecognizerListener();

       init();

       initXmly();

    }

 

   @Override

   public IBinder onBind(Intent intent) {

       // TODO Auto-generated method stub

       return null;

    }

 

   public void init()

    {

       initHandler();

       mOlamiVoiceRecognizer = new OlamiVoiceRecognizer(VoiceSdkService.this);

       TelephonyManager telephonyManager=(TelephonyManager)this.getSystemService(

       this.getBaseContext().TELEPHONY_SERVICE);

       String imei=telephonyManager.getDeviceId();

       mOlamiVoiceRecognizer.init(imei);//set null if you do not want to notifyolami server.

 

       mOlamiVoiceRecognizer.setListener(mOlamiVoiceRecognizerListener);

       mOlamiVoiceRecognizer.setLocalization(

                                        OlamiVoiceRecognizer.LANGUAGE_SIMPLIFIED_CHINESE);

       mOlamiVoiceRecognizer.setAuthorization(

           "51a4bb56ba954655a4fc834bfdc46af1",

           "asr","68bff251789b426896e70e888f919a6d","nli");       

       mOlamiVoiceRecognizer.setVADTailTimeout(2000);

       mOlamiVoiceRecognizer.setLatitudeAndLongitude(31.155364678184498,121.34882432933009);

    }

 

   private void initHandler()

    {

       mHandler = new Handler(){

           @Override

           public void handleMessage(Message msg)

           {

                switch (msg.what){

                caseMessageConst.CLIENT_ACTION_START_RECORED:

                   sendMessageToActivity(MessageConst.CLIENT_ACTION_START_RECORED,0,0,null,null);

                    break;

                case MessageConst.CLIENT_ACTION_STOP_RECORED:

                   sendMessageToActivity(MessageConst.CLIENT_ACTION_STOP_RECORED,0,0,null,null);

                    break;

                caseMessageConst.CLIENT_ACTION_ON_ERROR:

                    sendMessageToActivity(MessageConst.CLIENT_ACTION_ON_ERROR,msg.arg1,0,null,null);

                    break;

                caseMessageConst.CLIENT_ACTION_PLAY_BOOK_AFTER_SEARCH:

                   sendMessageToActivity(MessageConst.

                    CLIENT_ACTION_PLAY_BOOK_AFTER_SEARCH,msg.arg1, 0, null, msg.obj);

                    break;

                caseMessageConst.CLIENT_ACTION_UPDATA_PLAYING_BOOK_NAME:

                   sendMessageToActivity(MessageConst.

                   CLIENT_ACTION_UPDATA_PLAYING_BOOK_NAME, msg.arg1, 0, null, msg.obj);

                    break;

                caseMessageConst.CLIENT_ACTION_UPDATE_BOOK_PROGRESS:

                   sendMessageToActivity(MessageConst.

                    CLIENT_ACTION_UPDATE_BOOK_PROGRESS,msg.arg1, msg.arg2, null, null);

                    break;

                caseMessageConst.CLIENT_ACTION_CANCEL_RECORED:

                   sendMessageToActivity(MessageConst.

                    CLIENT_ACTION_CANCEL_RECORED,msg.arg1, msg.arg2, null, null);

                    break;

                default:

                    break;

                }

           }

       };

    }

 

   private void initInComingHandler()

    {

       mInComingHandler = new Handler(){

           @Override

           public void handleMessage(Message msg)

           {

                switch (msg.what){

                caseMessageConst.CLIENT_ACTION_START_RECORED:

                    if(mOlamiVoiceRecognizer !=null)

                       mOlamiVoiceRecognizer.start(); 

                    break;

                caseMessageConst.CLIENT_ACTION_STOP_RECORED:

                    if(mOlamiVoiceRecognizer !=null)

                       mOlamiVoiceRecognizer.stop();  

                    break;

                caseMessageConst.CLIENT_ACTION_CANCEL_RECORED:

                    if(mOlamiVoiceRecognizer !=null)

                       mOlamiVoiceRecognizer.cancel();

                    break;

                case MessageConst.CLIENT_ACTION_SENT_TEXT:

                    if(mOlamiVoiceRecognizer !=null)

                       mOlamiVoiceRecognizer.sendText(msg.obj.toString());                

                    break;

                }

           }

       };

    }

 

   private void initViaVoiceRecognizerListener()

    {

       mOlamiVoiceRecognizerListener = new OlamiVoiceRecognizerListener();

    }

 

   private class OlamiVoiceRecognizerListener implementsIOlamiVoiceRecognizerListener{

 

       @Override

       public void onError(int errCode) {

           mHandler.sendMessage(mHandler.obtainMessage(

           MessageConst.CLIENT_ACTION_ON_ERROR,errCode,0));

 

       }

 

       @Override

       public void onEndOfSpeech() {

           mHandler.sendEmptyMessage(MessageConst.CLIENT_ACTION_STOP_RECORED);

           if(mIsRecordPause)

           {

                mIsRecordPause = false;

                mBookUtil.resumePlay();

           }

 

       }

 

       @Override

       public void onBeginningOfSpeech() {

           if(mBookUtil.isPlaying())

           {

                mBookUtil.pause();

                mIsRecordPause = true;

           }

           mHandler.sendEmptyMessage(MessageConst.CLIENT_ACTION_START_RECORED);

 

       }

 

       @Override

       public void onResult(String result, int type) {    

           sendMessageToActivity(MessageConst.SERVER_ACTION_RETURN_RESULT,type,0,null,result);

           processServiceMessage(result);

       }

 

       @Override

       public void onCancel() {

           mHandler.sendEmptyMessage(MessageConst.CLIENT_ACTION_CANCEL_RECORED);

 

       }

 

       @Override

       public void onUpdateVolume(int volume) {

 

       sendMessageToActivity(MessageConst.CLIENT_ACTION_UPDATA_VOLUME,volume,0,null,null);

 

       }

 

    }

 

   private void initCommunicationAssist()

    {

       mVoiceSdkComAssist = new VoiceSdkComAssist();

       OlamiApplication.getInstance().setActivityToServiceListener(mVoiceSdkComAssist);

    }

 

   private void initXmly()

    {

       if(mBookUtil == null)

       {

           mBookUtil = BookUtil.getInstance();

           mBookUtil.init(VoiceSdkService.this);

           mBookUtil.setHandler(mHandler);

       }

    }

 

   private void processServiceMessage(String message)

    {

       String input = null;

       String serverMessage = null;

       try{

           JSONObject jsonObject = new JSONObject(message);

           JSONArray jArrayNli = jsonObject.optJSONObject("data").optJSONArray("nli");

           JSONObject jObj = jArrayNli.optJSONObject(0);

           JSONArray jArraySemantic = null;

           if(message.contains("semantic"))

              jArraySemantic =jObj.getJSONArray("semantic");

           else{

               input =jsonObject.optJSONObject("data").optJSONObject("asr").

                optString("result");

               sendMessageToActivity(MessageConst.

                                    CLIENT_ACTION_UPDATA_INPUT_TEXT, 0, 0, null, input);

                serverMessage =jObj.optJSONObject("desc_obj").opt("result").toString();

               sendMessageToActivity(MessageConst.

                       CLIENT_ACTION_UPDATA_SERVER_MESSAGE, 0, 0, null, serverMessage);

                return;

           }

           JSONObject jObjSemantic;

           JSONArray jArraySlots;

           JSONArray jArrayModifier;

           String type = null;

           String songName = null;

           String singer = null;

 

 

           if(jObj != null) {

                type =jObj.optString("type");

               if("musiccontrol".equals(type))

                {

                    jObjSemantic =jArraySemantic.optJSONObject(0);

                    input =jObjSemantic.optString("input");

                    jArraySlots =jObjSemantic.optJSONArray("slots");

                    jArrayModifier =jObjSemantic.optJSONArray("modifier");

                    String modifier =(String)jArrayModifier.opt(0);

                    if((jArrayModifier != null)&& ("play".equals(modifier)))

                    {

                        if(jArraySlots != null)

                           for(inti=0,k=jArraySlots.length(); i<k; i++)

                           {

                               JSONObject obj =jArraySlots.getJSONObject(i);

                               String name =obj.optString("name");

                              if("singer".equals(name))

                                   singer =obj.optString("value");

                               elseif("songname".equals(name))

                                   songName =obj.optString("value");

 

                           }

                    }else if((modifier != null)&& ("stop".equals(modifier)))

                    {

                        if(mBookUtil != null)

                           if(mBookUtil.isPlaying())

                               mBookUtil.stop();

                    }else if((modifier != null)&& ("pause".equals(modifier)))

                    {

                        if(mBookUtil != null)

                           if(mBookUtil.isPlaying())

                               mBookUtil.pause();

                    }else if((modifier != null)&& ("resume_play".equals(modifier)))

                    {

                        if(mBookUtil != null)

                           mBookUtil.resumePlay();

                    }else if((modifier != null)&& ("add_volume".equals(modifier)))

                    {

                        if(mBookUtil != null)

                            mBookUtil.addVolume();

                    }else if((modifier != null)&& ("del_volume".equals(modifier)))

                    {

                        if(mBookUtil != null)

                           mBookUtil.delVolume();

                    }else if((modifier != null)&& ("next".equals(modifier)))

                    {

                        if(mBookUtil != null)

                            mBookUtil.next();

                    }else if((modifier != null)&& ("previous".equals(modifier)))

                    {

                       if(mBookUtil !=null)

                            mBookUtil.prev();

                    }else if((modifier != null)&& ("play_index".equals(modifier)))

                    {

                        int position = 0;

                        if(jArraySlots != null)

                               for(inti=0,k=jArraySlots.length(); i<k; i++)

                               {

                                   JSONObjectobj = jArraySlots.getJSONObject(i);

                                   JSONObjectjNumDetial = obj.getJSONObject("num_detail");

                                   String index= jNumDetial.optString("recommend_value");

                                   position =Integer.parseInt(index) - 1;

                               }

                        if(mBookUtil != null)

                           mBookUtil.skipTo(position);

                    }

                }

           }

           if(songName != null)

           {

                if(singer != null)

                {

 

                }else{

                   mBookUtil.searchBookAndPlay(songName,0,0);

                }

           }else if(singer != null)

           {

               mBookUtil.searchBookAndPlay(songName,0,0);

           }

           serverMessage =jObj.optJSONObject("desc_obj").opt("result").toString();

       }

       catch (Exception e)

       {

           e.printStackTrace();

       }

       //發送消息更新語音識別的文字

       sendMessageToActivity(MessageConst.CLIENT_ACTION_UPDATA_INPUT_TEXT, 0,0, null, input);

       //發送消息更新服務器返回的結果字符串

       sendMessageToActivity(MessageConst.CLIENT_ACTION_UPDATA_SERVER_MESSAGE,

                                                   0, 0, null, serverMessage);

 

    }

 

   private void sendMessageToActivity(int what, int arg1, int arg2, Bundledata, Object obj)

    {

       if(OlamiApplication.getInstance().getServiceToActivityListener() !=null)

           OlamiApplication.getInstance().getServiceToActivityListener().

                                            callBack(what, arg1, arg2, data, obj);

    }

 

   private class VoiceSdkComAssist implements CommunicationAssist{

 

       @Override

       public void callBack(int what, int arg1, int arg2, Bundle data,Objectobj) {

           Message msg = Message.obtain(null, what);

           msg.arg1 = arg1;

           msg.arg2 = arg2;

           if (data != null)

                msg.setData(data);

           if (obj != null)

                msg.obj = obj;

            mInComingHandler.sendMessage(msg);

       }      

    }

 

   @Override

   public void onDestroy(){

       super.onDestroy();

       if(mOlamiVoiceRecognizer != null)

           mOlamiVoiceRecognizer.destroy();

       if(mBookUtil != null)

       {

           mBookUtil.destroy();

       }

 

    }

 

}

 

3.4VoiceSdkServiceonResult的回調處理

在VoiceSdkService.java中processServiceMessage(String message)用于處理onResult的回調數據。例如“我要聽三國演義”返回如下數據:

 

{

    "data": {

        "asr": {

            "result": "我要聽三國演義",

            "speech_status": 0,

            "final": true,

            "status": 0

        },

        "nli": [

            {

                "desc_obj": {

                    "result": "正在努力搜索中,請稍等",

                    "status": 0

                },

                "semantic": [

                    {

                        "app": "musiccontrol",

                        "input": "我要聽三國演義",

                        "slots": [

                            {

                                "name": "songname",

                               "value": "三國演義"

                            }

                        ],

                        "modifier": [

                            "play"

                        ],

                        "customer": "58df512384ae11f0bb7b487e"

                    }

                ],

                "type": "musiccontrol"

            }

        ]

    },

    "status": "ok"

}

1)解析出nlitype類型是musiccontrol,這是語法返回app的類型,而這個在線聽書的demo只關心musiccontrolapp類型,其他的忽略。

2)用戶說的話轉成文字是在asr中的result中獲取 
3
)在nli中的semantic中,input值是用戶說的話,同asr中的result。 
modifier
代表返回的行為動作,此處可以看到是play就是要求播放,slots中的數據表示歌曲名稱是三國演義。 
那么動作是play,內容是歌曲名稱是三國演義,在這個demo中調用 
mBookUtil.searchBookAndPlay(songName,0,0);
會先查詢,查詢到結果會再發播放消息要求播放,我要聽三國演義這個流程就走完了。

 

4.BookUtil

說一下搜索聽書的實現過程

public void searchBookInfo(StringbookName,final int index,final boolean isNeedPlay)

{

   mBookName = bookName;

   Map<String, String> param = new HashMap<String, String>();

   param.put(DTransferConstants.SEARCH_KEY, bookName);

   param.put(DTransferConstants.CATEGORY_ID, "" + 3);//此處3代表搜索的是聽書

   //param.put(DTransferConstants.PAGE, "" + mPageId);

   param.put(DTransferConstants.SORT, "asc");//返回列表的排序是正序還是逆序

   param.put(DTransferConstants.PAGE_SIZE, "" + PAGE_SIZE);//每頁能返回多少個查詢結果

   mPage = (index/PAGE_SIZE)+1;//當前在第幾頁

 

   mPlayerManager = XmPlayerManager.getInstance(mContext);//喜馬拉雅初始化部分

   mPlayerManager.init(mNotificationId, null);

   mPlayerManager.addPlayerStatusListener(mPlayerStatusListener);

   mPlayerManager.addAdsStatusListener(mAdsListener);

 

   CommonRequest.getSearchedAlbums(param, newIDataCallBack<SearchAlbumList>()

    {

 

       @Override

       public void onSuccess(SearchAlbumList object)  

       {                  

           if (object != null && object.getAlbums() != null

                    &&object.getAlbums().size() != 0)

           {

                if (mSearchAlbumList == null)

                {

                    mSearchAlbumList = object;

                }

                else

               {

                   mSearchAlbumList.getAlbums().addAll(object.getAlbums());

                }

               //mTrackAdapter.notifyDataSetChanged();

 

                Map<String, String> map =new HashMap<String, String>();

 

                map.put(

                DTransferConstants.ALBUM_ID,""+object.getAlbums().get(0).getId());

               map.put(DTransferConstants.SORT, "asc");

               map.put(DTransferConstants.PAGE, "" + mPage);

               map.put(DTransferConstants.PAGE_SIZE, "" + PAGE_SIZE);

 

                CommonRequest.getTracks(map,new IDataCallBack<TrackList>()

                {

 

                        @Override

                        public voidonSuccess(TrackList object)

                        {

                            mTrackList =object;

                            mTotalCount =mTrackList.getTotalCount();

                           if(mTrackList.getTracks().size() <= 0)

                                return;

                            String str = "專輯:"+mTrackList.getAlbumTitle()+

                                           get(0).getTrackTitle().toString();

                            if(isNeedPlay)

                            {

                                mPosition =index % PAGE_SIZE;

                               mHandler.sendMessage(mHandler.obtainMessage                               MessageConst.CLIENT_ACTION_PLAY_BOOK_AFTER_SEARCH,

                             index %PAGE_SIZE,0));//此處mTrackList中已經查詢出結果

                                //VoiceSdkService發送消息進行播放

                            }

                            else

                               sendBookInfoToServer();                                

                        }

                        @Override

                        public void onError(intcode, String message)

                        {

                           Log.i("ppp","error: "+message);

                           sendBookInfoToServer();

                        }

                });

 

            }

       }

 

       @Override

       public void onError(int code, String message)

       {

             Log.i("ppp","error: "+message);

              sendBookInfoToServer();

       }

   });

}

5.demo中支持的說法

我想聽西游記 
我要聽西游記 
播放西游記 
聽西游記 
我想聽西游記這本書 
上一首 
上一回 
下一首 
下一回 
暫停/暫停播放 
繼續/繼續播放 
聲音大一點 
聲音小一點 
關閉/關閉播放

用的是喜馬拉雅測試賬號,只支持聽書的功能,查找歌曲的結果返回為空。

6.×××鏈接

https://github.com/ls0609/olami_musicdemo

7.相關博客

語音識別語義理解一站式解決(android平臺&olami sdk

http://blog.csdn.net/ls0609/article/details/71519203

 

olami開放平臺語法編寫簡介:http://blog.csdn.net/ls0609/article/details/71624340

olami開放平臺語法官方介紹:https://cn.olami.ai/wiki/?mp=nli&content=nli2.html

csdn博文:http://blog.csdn.net/ls0609/article/details/71519203 


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女