YZSDemoActivity.java 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. package com.xunao.effectdemo.yzs;
  2. import android.Manifest;
  3. import android.app.Activity;
  4. import android.app.ProgressDialog;
  5. import android.content.Intent;
  6. import android.content.pm.PackageManager;
  7. import android.graphics.Color;
  8. import android.media.MediaPlayer;
  9. import android.net.Uri;
  10. import android.os.Build;
  11. import android.os.Bundle;
  12. import android.os.Environment;
  13. import android.text.TextUtils;
  14. import android.util.Log;
  15. import android.view.View;
  16. import android.widget.Button;
  17. import android.widget.CheckBox;
  18. import android.widget.EditText;
  19. import android.widget.ProgressBar;
  20. import android.widget.TextView;
  21. import android.widget.Toast;
  22. import androidx.annotation.NonNull;
  23. import androidx.core.app.ActivityCompat;
  24. import com.google.gson.Gson;
  25. import com.google.gson.JsonElement;
  26. import com.google.gson.JsonParseException;
  27. import com.google.gson.JsonParser;
  28. import com.google.gson.stream.JsonWriter;
  29. import com.unisound.edu.oraleval.sdk.sep15.IOralEvalSDK;
  30. import com.unisound.edu.oraleval.sdk.sep15.OralEvalSDKFactory;
  31. import com.unisound.edu.oraleval.sdk.sep15.SDKError;
  32. import com.unisound.edu.oraleval.sdk.sep15.utils.OralEvalEnum;
  33. import com.xunao.effectdemo.R;
  34. import java.io.File;
  35. import java.io.FileOutputStream;
  36. import java.io.IOException;
  37. import java.io.OutputStream;
  38. import java.io.StringWriter;
  39. public class YZSDemoActivity extends Activity
  40. implements View.OnClickListener, IOralEvalSDK.ICallback {
  41. private static final String TAG = "oraleval-demo";
  42. public static final String CONFIG = "config";
  43. static final boolean USE_OFFLINE_SDK_IF_FAIL_TO_SERVER = false;
  44. private ConfigBean configBean = new ConfigBean();
  45. private FileOutputStream audioFileOut;
  46. private FileOutputStream opusFileOut;
  47. private File files;
  48. private final String audioName = "testAudio.mp3"; //音频文件名
  49. private final String opusName = "testOpus"; //opus文件名
  50. private EditText etOralEvalText;
  51. private EditText et_url;
  52. private EditText etAppKey;
  53. private TextView tvResult;
  54. private Button btStart;
  55. private Button play_b;
  56. private CheckBox cbDefaultConfig;
  57. private ProgressBar progressBar;
  58. IOralEvalSDK _oe;
  59. ProgressDialog _pd;
  60. //读写权限
  61. private static String[] PERMISSIONS_STORAGE = {
  62. Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE,
  63. Manifest.permission.RECORD_AUDIO
  64. };
  65. //请求状态码
  66. private static int REQUEST_PERMISSION_CODE = 1;
  67. private void getCfg(OralEvalSDKFactory.StartConfig cfg) {
  68. if (!cbDefaultConfig.isChecked()) {
  69. //常用配置
  70. if (!TextUtils.isEmpty(configBean.getOralText())) {
  71. cfg.setOralText(configBean.getOralText());
  72. }
  73. if (configBean.isCN()) {
  74. cfg.setOralEvalMode(OralEvalEnum.OnlineCH);
  75. } else {
  76. cfg.setOralEvalMode(OralEvalEnum.OnlineUS);
  77. }
  78. cfg.setVadEnable(configBean.isVadEnable());
  79. cfg.setVadAfterMs(configBean.getVadAfterMs());
  80. cfg.setVadBeforeMs(configBean.getVadBeforeMs());
  81. //不常用配置
  82. cfg.setScoreAdjuest(configBean.get_scoreAdjuest());
  83. cfg.setServiceType(configBean.getServiceType());
  84. cfg.setMp3Audio(configBean.isMp3Audio());
  85. cfg.setUid(configBean.getUid());
  86. //不建议修改或者很少使用配置
  87. cfg.setOnline_ip(configBean.getOnline_ip());
  88. cfg.setSecret(configBean.getSecret());
  89. cfg.setSocket_timeout(configBean.getSocket_timeout());
  90. cfg.setAsyncRecognize(configBean.isSetAsyncRecognize());
  91. cfg.setBufferLog(configBean.isBufferLog());
  92. }
  93. if (USE_OFFLINE_SDK_IF_FAIL_TO_SERVER) {
  94. cfg.set_useOfflineWhenFailedToConnectToServer(true);
  95. }
  96. cfg.setReTry(false);
  97. cfg.setAppKey(etAppKey.getText().toString());
  98. }
  99. public void onCreate(Bundle savedInstanceState) {
  100. super.onCreate(savedInstanceState);
  101. setContentView(R.layout.demo_activity);
  102. if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
  103. if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
  104. != PackageManager.PERMISSION_GRANTED) {
  105. ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_PERMISSION_CODE);
  106. }
  107. }
  108. files = new File(Environment.getExternalStorageDirectory() + "/yunzhisheng/");
  109. if (!files.exists()) {
  110. files.mkdirs();
  111. }
  112. initOfflineSDK();
  113. etOralEvalText = (EditText) findViewById(R.id.etOralEvalText);
  114. et_url = (EditText) findViewById(R.id.et_url);
  115. etAppKey = (EditText) findViewById(R.id.etAppKey);
  116. tvResult = (TextView) findViewById(R.id.tvResult);
  117. btStart = (Button) findViewById(R.id.btStart);
  118. btStart.setOnClickListener(this);
  119. play_b = (Button) findViewById(R.id.play_b);
  120. play_b.setOnClickListener(this);
  121. progressBar = (ProgressBar) findViewById(R.id.progressBar);
  122. cbDefaultConfig = (CheckBox) findViewById(R.id.cbDefaultConfig);
  123. cbDefaultConfig.setChecked(true);
  124. findViewById(R.id.cancel_b).setOnClickListener(this);
  125. findViewById(R.id.retry_b).setOnClickListener(this);
  126. findViewById(R.id.btConfig).setOnClickListener(this);
  127. findViewById(R.id.btSelect).setOnClickListener(this);
  128. progressBar.setMax(100);
  129. }
  130. private void initOfflineSDK() {
  131. if (USE_OFFLINE_SDK_IF_FAIL_TO_SERVER) {
  132. File filesdir = this.getFilesDir();
  133. if (!filesdir.exists()) {
  134. filesdir.mkdirs();
  135. }
  136. Log.i(TAG, "start init offline sdk");
  137. IOralEvalSDK.OfflineSDKError err =
  138. OralEvalSDKFactory.initOfflineSDK(YZSDemoActivity.this, filesdir.getAbsolutePath());
  139. Log.i(TAG, "end init offline sdk");
  140. if (err != IOralEvalSDK.OfflineSDKError.NOERROR) {
  141. showToast("init sdk failed:" + err);
  142. }
  143. }
  144. }
  145. @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
  146. @NonNull int[] grantResults) {
  147. super.onRequestPermissionsResult(requestCode, permissions, grantResults);
  148. if (requestCode == REQUEST_PERMISSION_CODE) {
  149. for (int i = 0; i < permissions.length; i++) {
  150. Log.i(TAG, "申请的权限为:" + permissions[i] + ",申请结果:" + grantResults[i]);
  151. }
  152. }
  153. files = new File(Environment.getExternalStorageDirectory() + "/yunzhisheng/");
  154. if (!files.exists()) {
  155. files.mkdirs();
  156. }
  157. initOfflineSDK();
  158. }
  159. private void showToast(String txt) {
  160. if (!TextUtils.isEmpty(txt)) {
  161. Toast.makeText(YZSDemoActivity.this, txt, Toast.LENGTH_LONG).show();
  162. }
  163. }
  164. @Override public void onDestroy() {
  165. super.onDestroy();
  166. if (USE_OFFLINE_SDK_IF_FAIL_TO_SERVER) {
  167. OralEvalSDKFactory.cleanupOfflineSDK(this);
  168. }
  169. if (_oe != null) {
  170. _oe.cancel();
  171. }
  172. }
  173. @Override public void onClick(View view) {
  174. switch (view.getId()) {
  175. case R.id.btSelect:
  176. fileOralEval();
  177. break;
  178. case R.id.btStart:
  179. start();
  180. break;
  181. case R.id.retry_b:
  182. retry(opusName);
  183. break;
  184. case R.id.cancel_b:
  185. btStart.setText(R.string.start);
  186. showToast("取消评测");
  187. if (_oe != null) {
  188. _oe.cancel();
  189. }
  190. break;
  191. case R.id.play_b:
  192. showToast("开始播放");
  193. play();
  194. break;
  195. case R.id.btConfig:
  196. cbDefaultConfig.setChecked(false);
  197. Intent intent = new Intent(this, YZSConfigActivity.class);
  198. intent.putExtra(CONFIG, configBean);
  199. startActivityForResult(intent, 1000);
  200. break;
  201. default:
  202. break;
  203. }
  204. }
  205. private void chooseAudio() {
  206. Intent intent = new Intent();
  207. intent.setType("audio/wav");
  208. intent.setAction(Intent.ACTION_GET_CONTENT);
  209. startActivityForResult(intent, 1);
  210. }
  211. @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  212. super.onActivityResult(requestCode, resultCode, data);
  213. if (data != null) {
  214. if (data.getSerializableExtra(CONFIG) != null) {
  215. configBean = (ConfigBean) data.getSerializableExtra(CONFIG);
  216. }
  217. }
  218. }
  219. private void start() {
  220. if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
  221. if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
  222. != PackageManager.PERMISSION_GRANTED) {
  223. ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_PERMISSION_CODE);
  224. showToast("请打开录音和存储权限");
  225. return;
  226. }
  227. }
  228. if (_oe == null) {
  229. String txt = etOralEvalText.getText().toString();
  230. if (TextUtils.isEmpty(txt)) {
  231. showToast("Empty Text!");
  232. return;
  233. }
  234. OralEvalSDKFactory.StartConfig cfg = new OralEvalSDKFactory.StartConfig(txt);
  235. if (cfg == null) {
  236. return;
  237. }
  238. getCfg(cfg);
  239. _oe = OralEvalSDKFactory.start(this, cfg, this);
  240. btStart.setText(R.string.bt_stop);
  241. if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
  242. File audioFile = new File(files, audioName);
  243. if (!audioFile.exists()) {
  244. try {
  245. audioFile.createNewFile();
  246. } catch (IOException e) {
  247. e.printStackTrace();
  248. }
  249. }
  250. File opusFile = new File(files, opusName);
  251. if (!opusFile.exists()) {
  252. try {
  253. opusFile.createNewFile();
  254. } catch (IOException e) {
  255. e.printStackTrace();
  256. }
  257. }
  258. ;
  259. updateFile("title.txt", txt);
  260. } else {
  261. showToast("没有SD卡");
  262. }
  263. } else {
  264. _oe.stop();
  265. Log.e("============", "stop");
  266. btStart.setText(R.string.start);
  267. }
  268. }
  269. private void play() {
  270. try {
  271. final MediaPlayer mp = MediaPlayer.create(this, Uri.fromFile(new File(files, audioName)));
  272. mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
  273. @Override public void onPrepared(MediaPlayer mediaPlayer) {
  274. Log.d(TAG, "mp3 duration:" + mp.getDuration() + "ms");
  275. }
  276. });
  277. mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
  278. @Override public void onCompletion(MediaPlayer mediaPlayer) {
  279. Log.d(TAG, "final pos:" + mp.getCurrentPosition());
  280. mp.release();
  281. play_b.setEnabled(true);
  282. play_b.setBackgroundColor(Color.parseColor("#d6d7d7"));
  283. }
  284. });
  285. mp.setOnErrorListener(new MediaPlayer.OnErrorListener() {
  286. @Override public boolean onError(MediaPlayer mp, int what, int extra) {
  287. mp.release();
  288. play_b.setEnabled(true);
  289. play_b.setBackgroundColor(Color.parseColor("#d6d7d7"));
  290. return false;
  291. }
  292. });
  293. mp.start();
  294. play_b.setEnabled(false);
  295. play_b.setBackgroundColor(Color.parseColor("#33d6d7d7"));
  296. } catch (Exception ee) {
  297. Log.e(TAG, "playing failed.", ee);
  298. }
  299. }
  300. private void fileOralEval() {
  301. File file = new File(files, "test.wav");
  302. if (_oe != null) {
  303. _oe.cancel();
  304. btStart.setText(R.string.start);
  305. showToast("上次评测正在进行中,现在已经取消");
  306. return;
  307. }
  308. String txt = etOralEvalText.getText().toString();
  309. if (TextUtils.isEmpty(txt)) {
  310. showToast("Empty Text!");
  311. return;
  312. }
  313. OralEvalSDKFactory.StartConfig cfg = null;
  314. try {
  315. cfg = new OralEvalSDKFactory.StartConfig(txt, file.getAbsolutePath());
  316. } catch (IOException e) {
  317. e.printStackTrace();
  318. showToast("Opening " + file.getAbsolutePath() + " failed");
  319. return;
  320. }
  321. showToast("正在进行文件评测");
  322. if (cfg == null) {
  323. return;
  324. }
  325. getCfg(cfg);
  326. _oe = OralEvalSDKFactory.start(this, cfg, this);
  327. }
  328. private void retry(String file_name) {
  329. if (_oe != null) {
  330. _oe.cancel();
  331. btStart.setText(R.string.start);
  332. showToast("上次评测正在进行中,现在已经取消");
  333. return;
  334. }
  335. String txt = etOralEvalText.getText().toString();
  336. if (TextUtils.isEmpty(txt)) {
  337. showToast("Empty Text!");
  338. return;
  339. }
  340. File file = new File(files, file_name);
  341. Log.e("file size =", file.length() + "");
  342. OralEvalSDKFactory.StartConfig cfg = null;
  343. if (file.exists()) {
  344. try {
  345. cfg = new OralEvalSDKFactory.StartConfig(txt, file.getAbsolutePath());
  346. } catch (IOException e) {
  347. e.printStackTrace();
  348. showToast("Opening " + file.getAbsolutePath() + " failed");
  349. return;
  350. }
  351. showToast("正在重试");
  352. } else {
  353. showToast("没有可使用音频");
  354. }
  355. if (cfg == null) {
  356. return;
  357. }
  358. getCfg(cfg);
  359. cfg.setReTry(true);
  360. _oe = OralEvalSDKFactory.start(this, cfg, this);
  361. }
  362. /*
  363. 文件缓存
  364. */
  365. public void updateFile(String fileName, String data) {
  366. File titleFile = new File(files, fileName);
  367. if (!titleFile.exists()) {
  368. try {
  369. titleFile.createNewFile();
  370. } catch (IOException e) {
  371. e.printStackTrace();
  372. }
  373. }
  374. OutputStream os = null;
  375. try {
  376. os = new FileOutputStream(titleFile);
  377. os.write(data.getBytes());
  378. } catch (Exception e) {
  379. e.printStackTrace();
  380. } finally {
  381. if (os != null) {
  382. try {
  383. os.close();
  384. } catch (IOException e) {
  385. e.printStackTrace();
  386. }
  387. }
  388. }
  389. }
  390. long audioLength = 0;
  391. @Override public void onStart(IOralEvalSDK iOralEvalSDK, int audioId) {
  392. Log.i(TAG, "onStart(), audioId=" + audioId);
  393. this.runOnUiThread(new Runnable() {
  394. @Override public void run() {
  395. btStart.setEnabled(true);
  396. btStart.setBackgroundColor(Color.parseColor("#d6d7d7"));
  397. }
  398. });
  399. audioLength = 0;
  400. }
  401. @Override public void onCancel() {
  402. Log.i(TAG, "onCancel()");
  403. this.runOnUiThread(new Runnable() {
  404. @Override public void run() {
  405. _oe = null;
  406. if (audioFileOut != null) {
  407. try {
  408. audioFileOut.close();
  409. } catch (IOException e) {
  410. e.printStackTrace();
  411. }
  412. audioFileOut = null;
  413. }
  414. if (opusFileOut != null) {
  415. try {
  416. opusFileOut.close();
  417. } catch (IOException e) {
  418. e.printStackTrace();
  419. }
  420. opusFileOut = null;
  421. }
  422. btStart.setText(R.string.start);
  423. }
  424. });
  425. }
  426. @Override public void onError(IOralEvalSDK iOralEvalSDK, SDKError error,
  427. IOralEvalSDK.OfflineSDKError ofError) {
  428. Log.i(TAG, "onError");
  429. final SDKError err = error;
  430. final IOralEvalSDK.OfflineSDKError ofe = ofError;
  431. final String sdkLog = iOralEvalSDK.getLog();
  432. this.runOnUiThread(new Runnable() {
  433. @Override public void run() {
  434. _oe = null;
  435. updateFile("log.txt", sdkLog);
  436. btStart.setText(R.string.start);
  437. tvResult.setText("Error:" + err + "\n. offline error:" + ofe);
  438. btStart.setEnabled(true);
  439. btStart.setBackgroundColor(Color.parseColor("#d6d7d7"));
  440. if (_pd != null) {
  441. _pd.dismiss();
  442. _pd = null;
  443. }
  444. if (audioFileOut != null) {
  445. try {
  446. audioFileOut.close();
  447. } catch (IOException e) {
  448. e.printStackTrace();
  449. }
  450. audioFileOut = null;
  451. }
  452. if (opusFileOut != null) {
  453. try {
  454. opusFileOut.close();
  455. } catch (IOException e) {
  456. e.printStackTrace();
  457. }
  458. opusFileOut = null;
  459. }
  460. }
  461. });
  462. }
  463. @Override public void onStop(IOralEvalSDK iOralEvalSDK, String s, boolean offline, String str,
  464. IOralEvalSDK.EndReason stoptype) {
  465. Log.i(TAG, "onStop(), offline=" + offline + ", stoptype:" + stoptype);
  466. Log.i(TAG, "result:" + s);
  467. Log.i(TAG, "url:" + str);
  468. final String sdkLog = iOralEvalSDK.getLog();
  469. final String rst = s;
  470. final String url = str;
  471. if (audioFileOut != null) {
  472. try {
  473. audioFileOut.close();
  474. } catch (IOException e) {
  475. e.printStackTrace();
  476. }
  477. audioFileOut = null;
  478. }
  479. if (opusFileOut != null) {
  480. try {
  481. opusFileOut.close();
  482. } catch (IOException e) {
  483. e.printStackTrace();
  484. }
  485. opusFileOut = null;
  486. }
  487. this.runOnUiThread(new Runnable() {
  488. @Override public void run() {
  489. _oe = null;
  490. btStart.setText(R.string.start);
  491. tvResult.setText(formatResult(rst));
  492. updateFile("result.txt", rst);
  493. updateFile("log.txt", sdkLog);
  494. btStart.setEnabled(true);
  495. btStart.setBackgroundColor(Color.parseColor("#d6d7d7"));
  496. et_url.setText(url);
  497. File audioFile = new File(files, audioName);
  498. if (audioFile.exists()) {
  499. long size = audioFile.length();
  500. if (size < 20000) {
  501. showToast("说话时间过短");
  502. }
  503. }
  504. showToast("length:" + audioLength + "-----fileLength:" + audioFile.length());
  505. if (_pd != null) {
  506. _pd.dismiss();
  507. _pd = null;
  508. }
  509. }
  510. });
  511. }
  512. private String formatResult(String str) {
  513. JsonParser parser = new JsonParser();
  514. Gson gson = new Gson();
  515. JsonElement jo = null;
  516. try {
  517. jo = parser.parse(str);
  518. } catch (JsonParseException jpe) {
  519. return str;
  520. }
  521. StringWriter swr = new StringWriter();
  522. JsonWriter jwr = new JsonWriter(swr);
  523. jwr.setIndent(" ");
  524. gson.toJson(jo, jwr);
  525. try {
  526. jwr.flush();
  527. swr.flush();
  528. } catch (Exception e) {
  529. }
  530. return swr.getBuffer().toString();
  531. }
  532. @Override public void onVolume(IOralEvalSDK who, final int value) {
  533. this.runOnUiThread(new Runnable() {
  534. @Override public void run() {
  535. progressBar.setProgress(value);
  536. }
  537. });
  538. }
  539. @Override public void onStartOralEval() {
  540. Log.e("StartOralEval", "StartOralEval");
  541. }
  542. @Override public void onAudioData(IOralEvalSDK iOralEvalSDK, byte[] bytes, int offset, int len) {
  543. audioLength += bytes.length;
  544. try {
  545. if (audioFileOut == null) {
  546. audioFileOut = new FileOutputStream(new File(files, audioName));
  547. }
  548. audioFileOut.write(bytes, offset, len);
  549. } catch (IOException e) {
  550. e.printStackTrace();
  551. }
  552. }
  553. @Override public void onOpusData(IOralEvalSDK iOralEvalSDK, byte[] bytes, int offset, int len) {
  554. try {
  555. if (opusFileOut == null) {
  556. opusFileOut = new FileOutputStream(new File(files, opusName));
  557. }
  558. opusFileOut.write(bytes, offset, len);
  559. } catch (IOException e) {
  560. e.printStackTrace();
  561. }
  562. }
  563. @Override public void onAsyncResult(IOralEvalSDK who, String url) {
  564. Log.i(TAG, "onAsyncResult url:" + url);
  565. }
  566. }