package com.xunao.effectdemo.yzs; import android.Manifest; import android.app.Activity; import android.app.ProgressDialog; import android.content.Intent; import android.content.pm.PackageManager; import android.graphics.Color; import android.media.MediaPlayer; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.text.TextUtils; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.core.app.ActivityCompat; import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonParseException; import com.google.gson.JsonParser; import com.google.gson.stream.JsonWriter; import com.unisound.edu.oraleval.sdk.sep15.IOralEvalSDK; import com.unisound.edu.oraleval.sdk.sep15.OralEvalSDKFactory; import com.unisound.edu.oraleval.sdk.sep15.SDKError; import com.unisound.edu.oraleval.sdk.sep15.utils.OralEvalEnum; import com.xunao.effectdemo.R; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.StringWriter; public class YZSDemoActivity extends Activity implements View.OnClickListener, IOralEvalSDK.ICallback { private static final String TAG = "oraleval-demo"; public static final String CONFIG = "config"; static final boolean USE_OFFLINE_SDK_IF_FAIL_TO_SERVER = false; private ConfigBean configBean = new ConfigBean(); private FileOutputStream audioFileOut; private FileOutputStream opusFileOut; private File files; private final String audioName = "testAudio.mp3"; //音频文件名 private final String opusName = "testOpus"; //opus文件名 private EditText etOralEvalText; private EditText et_url; private EditText etAppKey; private TextView tvResult; private Button btStart; private Button play_b; private CheckBox cbDefaultConfig; private ProgressBar progressBar; IOralEvalSDK _oe; ProgressDialog _pd; //读写权限 private static String[] PERMISSIONS_STORAGE = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO }; //请求状态码 private static int REQUEST_PERMISSION_CODE = 1; private void getCfg(OralEvalSDKFactory.StartConfig cfg) { if (!cbDefaultConfig.isChecked()) { //常用配置 if (!TextUtils.isEmpty(configBean.getOralText())) { cfg.setOralText(configBean.getOralText()); } if (configBean.isCN()) { cfg.setOralEvalMode(OralEvalEnum.OnlineCH); } else { cfg.setOralEvalMode(OralEvalEnum.OnlineUS); } cfg.setVadEnable(configBean.isVadEnable()); cfg.setVadAfterMs(configBean.getVadAfterMs()); cfg.setVadBeforeMs(configBean.getVadBeforeMs()); //不常用配置 cfg.setScoreAdjuest(configBean.get_scoreAdjuest()); cfg.setServiceType(configBean.getServiceType()); cfg.setMp3Audio(configBean.isMp3Audio()); cfg.setUid(configBean.getUid()); //不建议修改或者很少使用配置 cfg.setOnline_ip(configBean.getOnline_ip()); cfg.setSecret(configBean.getSecret()); cfg.setSocket_timeout(configBean.getSocket_timeout()); cfg.setAsyncRecognize(configBean.isSetAsyncRecognize()); cfg.setBufferLog(configBean.isBufferLog()); } if (USE_OFFLINE_SDK_IF_FAIL_TO_SERVER) { cfg.set_useOfflineWhenFailedToConnectToServer(true); } cfg.setReTry(false); cfg.setAppKey(etAppKey.getText().toString()); } public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.demo_activity); if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_PERMISSION_CODE); } } files = new File(Environment.getExternalStorageDirectory() + "/yunzhisheng/"); if (!files.exists()) { files.mkdirs(); } initOfflineSDK(); etOralEvalText = (EditText) findViewById(R.id.etOralEvalText); et_url = (EditText) findViewById(R.id.et_url); etAppKey = (EditText) findViewById(R.id.etAppKey); tvResult = (TextView) findViewById(R.id.tvResult); btStart = (Button) findViewById(R.id.btStart); btStart.setOnClickListener(this); play_b = (Button) findViewById(R.id.play_b); play_b.setOnClickListener(this); progressBar = (ProgressBar) findViewById(R.id.progressBar); cbDefaultConfig = (CheckBox) findViewById(R.id.cbDefaultConfig); cbDefaultConfig.setChecked(true); findViewById(R.id.cancel_b).setOnClickListener(this); findViewById(R.id.retry_b).setOnClickListener(this); findViewById(R.id.btConfig).setOnClickListener(this); findViewById(R.id.btSelect).setOnClickListener(this); progressBar.setMax(100); } private void initOfflineSDK() { if (USE_OFFLINE_SDK_IF_FAIL_TO_SERVER) { File filesdir = this.getFilesDir(); if (!filesdir.exists()) { filesdir.mkdirs(); } Log.i(TAG, "start init offline sdk"); IOralEvalSDK.OfflineSDKError err = OralEvalSDKFactory.initOfflineSDK(YZSDemoActivity.this, filesdir.getAbsolutePath()); Log.i(TAG, "end init offline sdk"); if (err != IOralEvalSDK.OfflineSDKError.NOERROR) { showToast("init sdk failed:" + err); } } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_PERMISSION_CODE) { for (int i = 0; i < permissions.length; i++) { Log.i(TAG, "申请的权限为:" + permissions[i] + ",申请结果:" + grantResults[i]); } } files = new File(Environment.getExternalStorageDirectory() + "/yunzhisheng/"); if (!files.exists()) { files.mkdirs(); } initOfflineSDK(); } private void showToast(String txt) { if (!TextUtils.isEmpty(txt)) { Toast.makeText(YZSDemoActivity.this, txt, Toast.LENGTH_LONG).show(); } } @Override public void onDestroy() { super.onDestroy(); if (USE_OFFLINE_SDK_IF_FAIL_TO_SERVER) { OralEvalSDKFactory.cleanupOfflineSDK(this); } if (_oe != null) { _oe.cancel(); } } @Override public void onClick(View view) { switch (view.getId()) { case R.id.btSelect: fileOralEval(); break; case R.id.btStart: start(); break; case R.id.retry_b: retry(opusName); break; case R.id.cancel_b: btStart.setText(R.string.start); showToast("取消评测"); if (_oe != null) { _oe.cancel(); } break; case R.id.play_b: showToast("开始播放"); play(); break; case R.id.btConfig: cbDefaultConfig.setChecked(false); Intent intent = new Intent(this, YZSConfigActivity.class); intent.putExtra(CONFIG, configBean); startActivityForResult(intent, 1000); break; default: break; } } private void chooseAudio() { Intent intent = new Intent(); intent.setType("audio/wav"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(intent, 1); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (data != null) { if (data.getSerializableExtra(CONFIG) != null) { configBean = (ConfigBean) data.getSerializableExtra(CONFIG); } } } private void start() { if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_PERMISSION_CODE); showToast("请打开录音和存储权限"); return; } } if (_oe == null) { String txt = etOralEvalText.getText().toString(); if (TextUtils.isEmpty(txt)) { showToast("Empty Text!"); return; } OralEvalSDKFactory.StartConfig cfg = new OralEvalSDKFactory.StartConfig(txt); if (cfg == null) { return; } getCfg(cfg); _oe = OralEvalSDKFactory.start(this, cfg, this); btStart.setText(R.string.bt_stop); if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { File audioFile = new File(files, audioName); if (!audioFile.exists()) { try { audioFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } File opusFile = new File(files, opusName); if (!opusFile.exists()) { try { opusFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } ; updateFile("title.txt", txt); } else { showToast("没有SD卡"); } } else { _oe.stop(); Log.e("============", "stop"); btStart.setText(R.string.start); } } private void play() { try { final MediaPlayer mp = MediaPlayer.create(this, Uri.fromFile(new File(files, audioName))); mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mediaPlayer) { Log.d(TAG, "mp3 duration:" + mp.getDuration() + "ms"); } }); mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mediaPlayer) { Log.d(TAG, "final pos:" + mp.getCurrentPosition()); mp.release(); play_b.setEnabled(true); play_b.setBackgroundColor(Color.parseColor("#d6d7d7")); } }); mp.setOnErrorListener(new MediaPlayer.OnErrorListener() { @Override public boolean onError(MediaPlayer mp, int what, int extra) { mp.release(); play_b.setEnabled(true); play_b.setBackgroundColor(Color.parseColor("#d6d7d7")); return false; } }); mp.start(); play_b.setEnabled(false); play_b.setBackgroundColor(Color.parseColor("#33d6d7d7")); } catch (Exception ee) { Log.e(TAG, "playing failed.", ee); } } private void fileOralEval() { File file = new File(files, "test.wav"); if (_oe != null) { _oe.cancel(); btStart.setText(R.string.start); showToast("上次评测正在进行中,现在已经取消"); return; } String txt = etOralEvalText.getText().toString(); if (TextUtils.isEmpty(txt)) { showToast("Empty Text!"); return; } OralEvalSDKFactory.StartConfig cfg = null; try { cfg = new OralEvalSDKFactory.StartConfig(txt, file.getAbsolutePath()); } catch (IOException e) { e.printStackTrace(); showToast("Opening " + file.getAbsolutePath() + " failed"); return; } showToast("正在进行文件评测"); if (cfg == null) { return; } getCfg(cfg); _oe = OralEvalSDKFactory.start(this, cfg, this); } private void retry(String file_name) { if (_oe != null) { _oe.cancel(); btStart.setText(R.string.start); showToast("上次评测正在进行中,现在已经取消"); return; } String txt = etOralEvalText.getText().toString(); if (TextUtils.isEmpty(txt)) { showToast("Empty Text!"); return; } File file = new File(files, file_name); Log.e("file size =", file.length() + ""); OralEvalSDKFactory.StartConfig cfg = null; if (file.exists()) { try { cfg = new OralEvalSDKFactory.StartConfig(txt, file.getAbsolutePath()); } catch (IOException e) { e.printStackTrace(); showToast("Opening " + file.getAbsolutePath() + " failed"); return; } showToast("正在重试"); } else { showToast("没有可使用音频"); } if (cfg == null) { return; } getCfg(cfg); cfg.setReTry(true); _oe = OralEvalSDKFactory.start(this, cfg, this); } /* 文件缓存 */ public void updateFile(String fileName, String data) { File titleFile = new File(files, fileName); if (!titleFile.exists()) { try { titleFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } OutputStream os = null; try { os = new FileOutputStream(titleFile); os.write(data.getBytes()); } catch (Exception e) { e.printStackTrace(); } finally { if (os != null) { try { os.close(); } catch (IOException e) { e.printStackTrace(); } } } } long audioLength = 0; @Override public void onStart(IOralEvalSDK iOralEvalSDK, int audioId) { Log.i(TAG, "onStart(), audioId=" + audioId); this.runOnUiThread(new Runnable() { @Override public void run() { btStart.setEnabled(true); btStart.setBackgroundColor(Color.parseColor("#d6d7d7")); } }); audioLength = 0; } @Override public void onCancel() { Log.i(TAG, "onCancel()"); this.runOnUiThread(new Runnable() { @Override public void run() { _oe = null; if (audioFileOut != null) { try { audioFileOut.close(); } catch (IOException e) { e.printStackTrace(); } audioFileOut = null; } if (opusFileOut != null) { try { opusFileOut.close(); } catch (IOException e) { e.printStackTrace(); } opusFileOut = null; } btStart.setText(R.string.start); } }); } @Override public void onError(IOralEvalSDK iOralEvalSDK, SDKError error, IOralEvalSDK.OfflineSDKError ofError) { Log.i(TAG, "onError"); final SDKError err = error; final IOralEvalSDK.OfflineSDKError ofe = ofError; final String sdkLog = iOralEvalSDK.getLog(); this.runOnUiThread(new Runnable() { @Override public void run() { _oe = null; updateFile("log.txt", sdkLog); btStart.setText(R.string.start); tvResult.setText("Error:" + err + "\n. offline error:" + ofe); btStart.setEnabled(true); btStart.setBackgroundColor(Color.parseColor("#d6d7d7")); if (_pd != null) { _pd.dismiss(); _pd = null; } if (audioFileOut != null) { try { audioFileOut.close(); } catch (IOException e) { e.printStackTrace(); } audioFileOut = null; } if (opusFileOut != null) { try { opusFileOut.close(); } catch (IOException e) { e.printStackTrace(); } opusFileOut = null; } } }); } @Override public void onStop(IOralEvalSDK iOralEvalSDK, String s, boolean offline, String str, IOralEvalSDK.EndReason stoptype) { Log.i(TAG, "onStop(), offline=" + offline + ", stoptype:" + stoptype); Log.i(TAG, "result:" + s); Log.i(TAG, "url:" + str); final String sdkLog = iOralEvalSDK.getLog(); final String rst = s; final String url = str; if (audioFileOut != null) { try { audioFileOut.close(); } catch (IOException e) { e.printStackTrace(); } audioFileOut = null; } if (opusFileOut != null) { try { opusFileOut.close(); } catch (IOException e) { e.printStackTrace(); } opusFileOut = null; } this.runOnUiThread(new Runnable() { @Override public void run() { _oe = null; btStart.setText(R.string.start); tvResult.setText(formatResult(rst)); updateFile("result.txt", rst); updateFile("log.txt", sdkLog); btStart.setEnabled(true); btStart.setBackgroundColor(Color.parseColor("#d6d7d7")); et_url.setText(url); File audioFile = new File(files, audioName); if (audioFile.exists()) { long size = audioFile.length(); if (size < 20000) { showToast("说话时间过短"); } } showToast("length:" + audioLength + "-----fileLength:" + audioFile.length()); if (_pd != null) { _pd.dismiss(); _pd = null; } } }); } private String formatResult(String str) { JsonParser parser = new JsonParser(); Gson gson = new Gson(); JsonElement jo = null; try { jo = parser.parse(str); } catch (JsonParseException jpe) { return str; } StringWriter swr = new StringWriter(); JsonWriter jwr = new JsonWriter(swr); jwr.setIndent(" "); gson.toJson(jo, jwr); try { jwr.flush(); swr.flush(); } catch (Exception e) { } return swr.getBuffer().toString(); } @Override public void onVolume(IOralEvalSDK who, final int value) { this.runOnUiThread(new Runnable() { @Override public void run() { progressBar.setProgress(value); } }); } @Override public void onStartOralEval() { Log.e("StartOralEval", "StartOralEval"); } @Override public void onAudioData(IOralEvalSDK iOralEvalSDK, byte[] bytes, int offset, int len) { audioLength += bytes.length; try { if (audioFileOut == null) { audioFileOut = new FileOutputStream(new File(files, audioName)); } audioFileOut.write(bytes, offset, len); } catch (IOException e) { e.printStackTrace(); } } @Override public void onOpusData(IOralEvalSDK iOralEvalSDK, byte[] bytes, int offset, int len) { try { if (opusFileOut == null) { opusFileOut = new FileOutputStream(new File(files, opusName)); } opusFileOut.write(bytes, offset, len); } catch (IOException e) { e.printStackTrace(); } } @Override public void onAsyncResult(IOralEvalSDK who, String url) { Log.i(TAG, "onAsyncResult url:" + url); } }