ChivoxAiEngine.js 80 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069
  1. "use strict";
  2. var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
  3. var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
  4. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  5. /**
  6. * 版本号
  7. *
  8. * 31 ~ 24 : MAJOR
  9. * 23 ~ 16 : MINOR
  10. * 15 ~ 8 : PATCH
  11. * 7 ~ 0 : 保持为00, 不要填写任何数字
  12. *
  13. */
  14. var ChivoxSdkVersion = 0x02000800;
  15. var ChivoxAiErr = {
  16. EngineStatus: 72201,
  17. NotYetNew: 72202,
  18. NotYetStart: 72203,
  19. NewRepeatedly: 72204,
  20. StartRepeatedly: 72205,
  21. StopRepeatedly: 72206,
  22. WaitConnectFinish: 72207, // TODO remove
  23. WaitStartFinish: 72208,
  24. WaitStopFinish: 72209,
  25. WaitResulted: 72210,
  26. WaitCancelFinish: 72211,
  27. StartRecorderFail: 72212,
  28. StopRecorderFail: 72213,
  29. CancelRecorderFail: 72214,
  30. WxRecorderError: 72215,
  31. OperationCanceled: 72216
  32. };
  33. var ChivoxWsErr = {
  34. WechatVersion: 72001,
  35. InvalidApp: 72002,
  36. InvalidAppAppId: 72003,
  37. InvalidAppSig: 72004,
  38. InvalidAppAlg: 72005,
  39. InvalidAppUserId: 72006,
  40. InvalidRequest: 72007,
  41. InvalidAudio: 72008,
  42. InvalidAudioType: 72009,
  43. InvalidAudioChannel: 72010,
  44. InvalidSampleBytes: 72011,
  45. InvalidSampleRate: 72012,
  46. EngineStatus: 72013,
  47. ConnectRepeatedly: 72014, // TODO remove
  48. ConnectFail: 72015,
  49. StartRepeatedly: 72016,
  50. StopRepeatedly: 72017,
  51. NotYetConnect: 72018,
  52. NotYetStarted: 72019,
  53. WaitConnected: 72020,
  54. WaitResulted: 72021,
  55. ResultJsonParse: 72022,
  56. ResultNotObject: 72023,
  57. NetException: 72024,
  58. ServerTimeout: 72025
  59. };
  60. var ChivoxUtils = {
  61. generateGuid: function generateGuid() {
  62. return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
  63. var r = Math.random() * 16 | 0;
  64. var v = c === "x" ? r : r & 0x3 | 0x8;
  65. return v.toString(16);
  66. });
  67. },
  68. getVersion: function getVersion(_version) {
  69. var tkn = (_version & 0xff000000) >> 24;
  70. var ver = "";
  71. ver += tkn.toString();
  72. tkn = (_version & 0x00ff0000) >> 16;
  73. ver += "." + tkn.toString();
  74. tkn = (_version & 0x0000ff00) >> 8;
  75. ver += "." + tkn.toString();
  76. tkn = _version & 0x000000ff;
  77. if (tkn !== 0) {
  78. ver += "." + tkn.toString();
  79. }
  80. return ver;
  81. },
  82. compareWxVersion: function compareWxVersion(v1, v2) {
  83. v1 = v1.split('.');
  84. v2 = v2.split('.');
  85. var len = Math.max(v1.length, v2.length);
  86. while (v1.length < len) {
  87. v1.push('0');
  88. }
  89. while (v2.length < len) {
  90. v2.push('0');
  91. }
  92. for (var i = 0; i < len; i++) {
  93. var num1 = parseInt(v1[i]);
  94. var num2 = parseInt(v2[i]);
  95. if (num1 > num2) {
  96. return 1;
  97. } else if (num1 < num2) {
  98. return -1;
  99. }
  100. }
  101. return 0;
  102. },
  103. isValidApp: function isValidApp(app, err, tag) {
  104. if (typeof tag !== "string") tag = "";
  105. if (typeof app === "undefined") {
  106. err.errId = ChivoxWsErr.InvalidApp;
  107. err.error = tag + " no 'app'. ";
  108. return false;
  109. }
  110. if ((typeof app === "undefined" ? "undefined" : _typeof(app)) !== "object") {
  111. err.errId = ChivoxWsErr.InvalidApp;
  112. err.error = tag + " invalid 'app'. ";
  113. return false;
  114. }
  115. if (typeof app.applicationId !== "string") {
  116. err.errId = ChivoxWsErr.InvalidAppAppId;
  117. err.error = tag + " invalid 'app.applicationId'. ";
  118. return false;
  119. }
  120. if (typeof app.sig !== "string") {
  121. err.errId = ChivoxWsErr.InvalidAppSig;
  122. err.error = tag + " invalid 'app.sig'. ";
  123. return;
  124. }
  125. if (typeof app.alg !== "string") {
  126. err.errId = ChivoxWsErr.InvalidAppAlg;
  127. err.error = tag + " invalid 'app.alg'. ";
  128. return false;
  129. }
  130. if (typeof app.userId !== "string") {
  131. err.errId = ChivoxWsErr.InvalidAppUserId;
  132. err.error = tag + " invalid 'app.userId'. ";
  133. return false;
  134. }
  135. return true;
  136. },
  137. isValidRequest: function isValidRequest(request, err, tag) {
  138. if (typeof tag !== "string") tag = "";
  139. if ((typeof request === "undefined" ? "undefined" : _typeof(request)) !== "object") {
  140. err.errId = ChivoxWsErr.InvalidRequest;
  141. err.error = tag + " invalid 'request'. ";
  142. return false;
  143. }
  144. return true;
  145. },
  146. isValidAudio: function isValidAudio(audio, err) {
  147. if ((typeof audio === "undefined" ? "undefined" : _typeof(audio)) !== "object") {
  148. err.errId = ChivoxWsErr.InvalidAudio;
  149. err.error = "[ChivoxWsEngine] invalid 'audio', or no 'audio'. ";
  150. return false;
  151. }
  152. if (typeof audio.audioType !== "string") {
  153. err.errId = ChivoxWsErr.InvalidAudioType;
  154. err.error = "[ChivoxWsEngine] invalid audio.audioType. ";
  155. return false;
  156. }
  157. if (audio.channel !== 1) {
  158. err.errId = ChivoxWsErr.InvalidAudioChannel;
  159. err.error = "[ChivoxWsEngine] invalid audio.channel. ";
  160. return false;
  161. }
  162. if (typeof audio.sampleBytes !== "number") {
  163. err.errId = ChivoxWsErr.InvalidSampleBytes;
  164. err.error = "[ChivoxWsEngine] invalid audio.sampleBytes. ";
  165. return false;
  166. }
  167. if (typeof audio.sampleRate !== "number") {
  168. err.errId = ChivoxWsErr.InvalidSampleRate;
  169. err.error = "[ChivoxWsEngine] invalid audio.sampleRate. ";
  170. return false;
  171. }
  172. return true;
  173. }
  174. };
  175. var ChivoxFire = {
  176. Fail: function Fail(options, res, res2) {
  177. if (typeof options.fail === "function") {
  178. options.fail(res);
  179. } else {
  180. console.warn("'fail' undefined");
  181. }
  182. if (typeof options.complete === "function") {
  183. options.complete(res2);
  184. }
  185. },
  186. Success: function Success(options, res, res2) {
  187. if (typeof options.success === "function") {
  188. options.success(res);
  189. } else {
  190. console.warn("'success' undefined");
  191. }
  192. if (typeof options.complete === "function") {
  193. options.complete(res2);
  194. }
  195. },
  196. OnResult: function OnResult(obj, res) {
  197. if (typeof obj._onResult === "function") {
  198. obj._onResult(res);
  199. } else {
  200. console.warn("'onResult' undefined");
  201. }
  202. },
  203. OnErrorResult: function OnErrorResult(obj, res) {
  204. if (typeof obj._onErrorResult === "function") {
  205. obj._onErrorResult(res);
  206. } else {
  207. console.warn("'onErrorResult' undefined");
  208. }
  209. },
  210. // for ChivoxAiEngine
  211. OnRecorderStart: function OnRecorderStart(obj, res) {
  212. if (typeof obj._onRecorderStart === "function") {
  213. obj._onRecorderStart(res);
  214. } else {
  215. console.warn("'onRecorderStart' undefined");
  216. }
  217. },
  218. OnRecorderPause: function OnRecorderPause(obj, res) {
  219. if (typeof obj._onRecorderPause === "function") {
  220. obj._onRecorderPause(res);
  221. } else {
  222. console.warn("'onRecorderPause' undefined");
  223. }
  224. },
  225. OnRecorderResume: function OnRecorderResume(obj, res) {
  226. if (typeof obj._onRecorderResume === "function") {
  227. obj._onRecorderResume(res);
  228. } else {
  229. console.warn("'onRecorderResume' undefined");
  230. }
  231. },
  232. OnRecorderStop: function OnRecorderStop(obj, res) {
  233. if (typeof obj._onRecorderStop === "function") {
  234. obj._onRecorderStop(res);
  235. } else {
  236. console.warn("'onRecorderStop' undefined");
  237. }
  238. },
  239. OnRecorderError: function OnRecorderError(obj, res) {
  240. if (typeof obj._onRecorderError === "function") {
  241. obj._onRecorderError(res);
  242. }
  243. },
  244. OnRecorderFrame: function OnRecorderFrame(obj, res) {
  245. if (typeof obj._onRecorderFrame === "function") {
  246. obj._onRecorderFrame(res);
  247. }
  248. }
  249. };
  250. var ChivoxWsLogBus = {
  251. WsConnectStart: 19,
  252. WsConnectSuccess: 15,
  253. WsConnectClose: 17,
  254. WsConnectFail: 16,
  255. GetResultSuccess: 1000,
  256. GetResultTimeOut: 1001
  257. };
  258. /*
  259. 状态转换图:
  260. None <-------+ <--+ <--+ <--+ <--+
  261. ↓ | | | | |
  262. Connecting --+ | | | |
  263. ↓ | | | |
  264. Ready ------------+ | | |
  265. ↓ | | |
  266. +------> Evaluating ------------+ | |
  267. | ↓ | |
  268. | Resulting ------------------+ |
  269. | ↓ |
  270. | Resulted ------------------------+
  271. | ↓
  272. +----------+
  273. */
  274. var ChivoxWsEngineStatus = {
  275. None: "None",
  276. Connecting: "Connecting",
  277. Ready: "Ready",
  278. Evaluating: "Evaluating",
  279. Resulting: "Resulting",
  280. Resulted: "Resulted"
  281. };
  282. var ChivoxWsEngineReStatus = {
  283. completed: "completed",
  284. reConnecting: "reConnecting",
  285. reConnected: "reConnected"
  286. };
  287. var ChivoxWsEngine = function () {
  288. function ChivoxWsEngine() {
  289. _classCallCheck(this, ChivoxWsEngine);
  290. var that = this;
  291. that._version = ChivoxSdkVersion;
  292. that._SERVER_DEFAULT = "wss://cloud.chivox.com/ws?e=0&t=0&version=2";
  293. that._SERVER_GRAY = "wss://gray.cloud.chivox.com/ws?e=0&t=0&version=2";
  294. that._server = that._SERVER_DEFAULT;
  295. that._wsClient = undefined;
  296. that._waitTimer = undefined;
  297. that._lastConnectOptions = undefined;
  298. that._lastStartOptions = undefined;
  299. that._status = ChivoxWsEngineStatus.None;
  300. that._reConnecting = undefined;
  301. that._onErrorResult = undefined;
  302. that._onResult = undefined;
  303. }
  304. _createClass(ChivoxWsEngine, [{
  305. key: "onResult",
  306. value: function onResult(func) {
  307. this._onResult = func;
  308. }
  309. }, {
  310. key: "onErrorResult",
  311. value: function onErrorResult(func) {
  312. this._onErrorResult = func;
  313. }
  314. }, {
  315. key: "getVersion",
  316. value: function getVersion() {
  317. return ChivoxUtils.getVersion(this._version);
  318. }
  319. /**
  320. * init 初始化
  321. * @param {boolean} gray [可选] 是否使用灰度服
  322. * @param {string} server [可选-非公开] 指定服务器,若传此参数,则忽略gray
  323. */
  324. }, {
  325. key: "init",
  326. value: function init(cfg) {
  327. var that = this;
  328. console.log("[ChivoxWsEngine] init()");
  329. that.reset();
  330. if ((typeof cfg === "undefined" ? "undefined" : _typeof(cfg)) === "object") {
  331. if (cfg.gray) {
  332. that._server = that._SERVER_GRAY;
  333. }
  334. if (typeof cfg.server === "string") {
  335. that._server = cfg.server + "/ws?e=0&t=0&version=2";
  336. }
  337. }
  338. }
  339. /**
  340. * start 向评分服务发送"开始"命令
  341. * [1] 如果引擎内部还没有连接评分服务器,本方内部会先连接,然后后再发送"开始"命令。
  342. * [2] 如果引擎内部已经连接到评分服务器了,本方法直接发送"开始"命令。
  343. * [3] 如果引擎内部的服务器连接断开了,同 [1]
  344. * @param {object} app [必选] 身份验证信息。连接服务器时用到,如果已经连接上了,则不再连接。
  345. * @param {string} tokenId [可选-非公开] 指定tokenId
  346. * @param {object} request [必选] 评分请求
  347. * @param {object} audio [必选] 音频参数
  348. * @param {function} success [必选] 接口调用成功事件
  349. * @param {function} fail [必选] 接口调用失败事件
  350. * @param {function} complete [可选] 接口调用完毕事件
  351. */
  352. }, {
  353. key: "start",
  354. value: function start(options) {
  355. var that = this;
  356. console.log("[ChivoxWsEngine] start()");
  357. if (that._status != ChivoxWsEngineStatus.None && that._status != ChivoxWsEngineStatus.Ready && that._status != ChivoxWsEngineStatus.Resulted) {
  358. if (that._status == ChivoxWsEngineStatus.Connecting) {
  359. var _err = { errId: ChivoxWsErr.WaitConnected,
  360. error: "[ChivoxWsEngine] engine is connecting to server, please wait connected. "
  361. };
  362. ChivoxFire.Fail(options, _err);
  363. return;
  364. }
  365. if (that._status == ChivoxWsEngineStatus.Evaluating) {
  366. var _err2 = { errId: ChivoxWsErr.StartRepeatedly,
  367. error: "[ChivoxWsEngine] you shouldn't call 'start' repeatedly. "
  368. };
  369. ChivoxFire.Fail(options, _err2);
  370. return;
  371. }
  372. if (that._status == ChivoxWsEngineStatus.Resulting) {
  373. var _err3 = { errId: ChivoxWsErr.WaitResulted,
  374. error: "[ChivoxWsEngine] you should wait the 'result'. "
  375. };
  376. ChivoxFire.Fail(options, _err3);
  377. return;
  378. }
  379. // 逻辑上不可能到这里
  380. var err = { errId: ChivoxWsErr.EngineStatus,
  381. error: "[ChivoxWsEngine] engine status error when you call 'start', status: " + that._status + ". "
  382. };
  383. ChivoxFire.Fail(options, err);
  384. return;
  385. }
  386. options.tcpNoDelay = typeof options.tcpNoDelay === "boolean" ? options.tcpNoDelay : true;
  387. that._lastStartOptions = options;
  388. if (that._status == ChivoxWsEngineStatus.None) {
  389. that._reConnecting = ChivoxWsEngineReStatus.completed;
  390. that._doConnect({
  391. app: options.app,
  392. tcpNoDelay: options.tcpNoDelay,
  393. success: function success() {
  394. that._doStart(options);
  395. },
  396. fail: function fail(res) {
  397. ChivoxFire.Fail(options, res);
  398. }
  399. });
  400. return;
  401. }
  402. that._doStart(options);
  403. }
  404. }, {
  405. key: "isStarted",
  406. value: function isStarted() {
  407. var that = this;
  408. return that._status == ChivoxWsEngineStatus.Evaluating;
  409. }
  410. }, {
  411. key: "_doConnect",
  412. value: function _doConnect(options) {
  413. var that = this;
  414. var sysInfo = wx.getSystemInfoSync();
  415. that._status = ChivoxWsEngineStatus.Connecting;
  416. if (ChivoxUtils.compareWxVersion(sysInfo.SDKVersion, "1.7.0") < 0) {
  417. that._status = ChivoxWsEngineStatus.None;
  418. var _err4 = { errId: ChivoxWsErr.WechatVersion,
  419. error: "[ChivoxWsEngine] the minimum version requirement of wechat-app-sdk is 1.7.0 . "
  420. };
  421. ChivoxFire.Fail(options, _err4);
  422. return;
  423. }
  424. var err = {};
  425. if (!ChivoxUtils.isValidApp(options.app, err, "[ChivoxWsEngine]")) {
  426. that._status = ChivoxWsEngineStatus.None;
  427. ChivoxFire.Fail(options, err);
  428. return;
  429. }
  430. that._wsClient = wx.connectSocket({
  431. url: that._server,
  432. tcpNoDelay: options.tcpNoDelay,
  433. success: function success(res) {
  434. that._logBus({ est: ChivoxWsLogBus.WsConnectStart, reason: res.errMsg });
  435. },
  436. fail: function fail(res) {
  437. that._status = ChivoxWsEngineStatus.None;
  438. var err = { errId: ChivoxWsErr.ConnectFail,
  439. error: "[ChivoxWsEngine] connect server(" + that._server + ") fail. " + res.errMsg + ". "
  440. };
  441. that.reset();
  442. ChivoxFire.Fail(options, err);
  443. }
  444. });
  445. if (typeof that._wsClient !== "undefined") {
  446. that._lastConnectOptions = options;
  447. that._wsClient.onOpen(that._onWsOpen(that._wsClient));
  448. that._wsClient.onMessage(that._onWsMessage(that._wsClient));
  449. that._wsClient.onError(that._onWsError(that._wsClient));
  450. that._wsClient.onClose(that._onWsClose(that._wsClient));
  451. }
  452. }
  453. }, {
  454. key: "_doStart",
  455. value: function _doStart(options) {
  456. var that = this;
  457. var oldStatus = that._status;
  458. that._status = ChivoxWsEngineStatus.Evaluating;
  459. var err = {};
  460. if (!ChivoxUtils.isValidRequest(options.request, err, "[ChivoxWsEngine]")) {
  461. that._status = oldStatus;
  462. ChivoxFire.Fail(options, err);
  463. return;
  464. }
  465. err = {};
  466. if (!ChivoxUtils.isValidAudio(options.audio, err)) {
  467. that._status = oldStatus;
  468. ChivoxFire.Fail(options, err);
  469. return;
  470. }
  471. var tokenId = options.tokenId;
  472. if (typeof tokenId !== "string") {
  473. tokenId = ChivoxUtils.generateGuid().replace(/-/g, "");
  474. }
  475. that._tokenId = tokenId;
  476. var startObj = { tokenId: tokenId, request: options.request, audio: options.audio };
  477. var startText = JSON.stringify(startObj);
  478. console.log("[ChivoxWsEngine] send start text");
  479. console.debug(startObj);
  480. that._wsClient.send({ data: startText,
  481. fail: function fail(res) {
  482. console.warn("[ChivoxWsEngine] send start text fail!!! errMsg: " + res.errMsg);
  483. }
  484. });
  485. ChivoxFire.Success(options, { tokenId: tokenId });
  486. }
  487. /**
  488. * feed 向评分服务发送音频数据
  489. * @param {ArrayBuffer} data 音频数据, 不允许传入空对象或Buffer长度为0
  490. * @param {function} success 接口调用成功事件
  491. * @param {function} fail 接口调用失败事件
  492. * @param {function} complete 接口调用完毕事件
  493. */
  494. }, {
  495. key: "feed",
  496. value: function feed(options) {
  497. var that = this;
  498. console.log("[ChivoxWsEngine] feed()");
  499. if (that._status != ChivoxWsEngineStatus.Evaluating) {
  500. if (that._status == ChivoxWsEngineStatus.None) {
  501. var _err5 = { errId: ChivoxWsErr.NotYetConnect,
  502. error: "[ChivoxWsEngine] you should call 'start' first. "
  503. };
  504. ChivoxFire.Fail(options, _err5);
  505. return;
  506. }
  507. if (that._status == ChivoxWsEngineStatus.Connecting) {
  508. var _err6 = { errId: ChivoxWsErr.WaitConnected,
  509. error: "[ChivoxWsEngine] you should wait 'start' complete. "
  510. };
  511. ChivoxFire.Fail(options, _err6);
  512. return;
  513. }
  514. if (that._status == ChivoxWsEngineStatus.Ready) {
  515. var _err7 = { errId: ChivoxWsErr.NotYetStarted,
  516. error: "[ChivoxWsEngine] you should call 'start' first. "
  517. };
  518. ChivoxFire.Fail(options, _err7);
  519. return;
  520. }
  521. // stop以后feed的数据
  522. if (that._status == ChivoxWsEngineStatus.Resulting || that._status == ChivoxWsEngineStatus.Resulted) {
  523. console.warn("[ChivoxWsEngine] you shouldn't feed data after you called 'stop'. ");
  524. ChivoxFire.Success(options);
  525. return;
  526. }
  527. // 逻辑上不可能执行到这里
  528. var err = { errId: ChivoxWsErr.EngineStatus,
  529. error: "[ChivoxWsEngine] engine status error when you call 'feed', status: " + that._status + ". "
  530. };
  531. ChivoxFire.Fail(options, err);
  532. return;
  533. }
  534. console.log("[ChivoxWsEngine] send audio-data");
  535. if (null == options.data || options.data.byteLength <= 0) {
  536. ChivoxFire.Success(options);
  537. return;
  538. }
  539. that._wsClient.send({ data: options.data,
  540. fail: function fail(res) {
  541. console.warn("[ChivoxWsEngine] send audio-data fail!!! errMsg: " + res.errMsg);
  542. }
  543. });
  544. ChivoxFire.Success(options);
  545. }
  546. /**
  547. * stop 向评分服务发送"结束"命令
  548. * @param {int} timeout [可选] 等待结果超时,单位毫秒
  549. * @param {function} success 接口调用成功事件
  550. * @param {function} fail 接口调用失败事件
  551. * @param {function} complete 接口调用完毕事件
  552. */
  553. }, {
  554. key: "stop",
  555. value: function stop(options) {
  556. var that = this;
  557. console.log("[ChivoxWsEngine] stop()");
  558. if (that._status != ChivoxWsEngineStatus.Evaluating) {
  559. if (that._status == ChivoxWsEngineStatus.None) {
  560. var _err8 = { errId: ChivoxWsErr.NotYetConnect,
  561. error: "[ChivoxWsEngine] you should call 'start' first. "
  562. };
  563. ChivoxFire.Fail(options, _err8);
  564. return;
  565. }
  566. if (that._status == ChivoxWsEngineStatus.Connecting) {
  567. var _err9 = { errId: ChivoxWsErr.WaitConnected,
  568. error: "[ChivoxWsEngine] you should wait 'start' complete. "
  569. };
  570. ChivoxFire.Fail(options, _err9);
  571. return;
  572. }
  573. if (that._status == ChivoxWsEngineStatus.Ready || that._status == ChivoxWsEngineStatus.Resulted) {
  574. var _err10 = { errId: ChivoxWsErr.NotYetStarted,
  575. error: "[ChivoxWsEngine] you should call 'start' first. "
  576. };
  577. ChivoxFire.Fail(options, _err10);
  578. return;
  579. }
  580. // stop以后又调用stop
  581. if (that._status == ChivoxWsEngineStatus.Resulting) {
  582. var _err11 = { errId: ChivoxWsErr.StopRepeatedly,
  583. error: "[ChivoxWsEngine] you shouldn't call 'stop' repeatedly. "
  584. };
  585. ChivoxFire.Fail(options, _err11);
  586. return;
  587. }
  588. // 逻辑上不可能执行到这里
  589. var err = { errId: ChivoxWsErr.EngineStatus,
  590. error: "[ChivoxWsEngine] engine status error when you call 'stop', status: " + that._status + ". "
  591. };
  592. ChivoxFire.Fail(options, err);
  593. return;
  594. }
  595. console.log("[ChivoxWsEngine] send stop");
  596. that._status = ChivoxWsEngineStatus.Resulting;
  597. that._wsClient.send({ data: '{"cmd":"stop"}',
  598. fail: function fail(res) {
  599. console.warn("[ChivoxWsEngine] send stop fail!!! errMsg: " + res.errMsg);
  600. }
  601. });
  602. var timeout = 60000; // 缺省等待时间60秒
  603. if (typeof options.timeout === "number" && options.timeout >= 0) {
  604. timeout = options.timeout;
  605. }
  606. if (typeof that._waitTimer !== "undefined") {
  607. clearTimeout(that._waitTimer);
  608. that._waitTimer = undefined;
  609. }
  610. that._waitTimer = setTimeout(that._onWaitResultTimeout(), timeout);
  611. ChivoxFire.Success(options);
  612. }
  613. /**
  614. * reset 重置引擎
  615. * 将会销毁websocket连接,销毁'结果定时器'
  616. */
  617. }, {
  618. key: "reset",
  619. value: function reset() {
  620. var that = this;
  621. console.log("[ChivoxWsEngine] reset()");
  622. if (typeof that._wsClient !== "undefined") {
  623. var wsClient = that._wsClient;
  624. that._wsClient = undefined;
  625. // 若正在连接的时候关闭,则连接可被正常关闭,之后_onWsOpen不再触发,onError、onClose事件会触发。
  626. wsClient.close();
  627. }
  628. if (typeof that._waitTimer !== "undefined") {
  629. var waitTimer = that._waitTimer;
  630. that._waitTimer = undefined;
  631. clearTimeout(waitTimer);
  632. }
  633. that._status = ChivoxWsEngineStatus.None;
  634. that._lastConnectOptions = undefined;
  635. that._tokenId = undefined;
  636. }
  637. }, {
  638. key: "_onWsOpen",
  639. value: function _onWsOpen(wsClient) {
  640. var that = this;
  641. return function (res) {
  642. console.log("[ChivoxWsEngine] _onWsOpen(), at status: " + that._status);
  643. if (that._wsClient !== wsClient) {
  644. // 若引擎已被重置,则忽略本事件。
  645. console.log("[ChivoxWsEngine] _onWsOpen: engine has been reset. not current wsClient's event.");
  646. return;
  647. }
  648. if (that._reConnecting === ChivoxWsEngineReStatus.reConnecting) {
  649. that._reConnecting = ChivoxWsEngineReStatus.reConnected;
  650. }
  651. that._logBus({ est: ChivoxWsLogBus.WsConnectSuccess, reason: res.errMsg });
  652. var lastConnectOptions = that._lastConnectOptions;
  653. that._lastConnectOptions = undefined;
  654. var app = undefined;
  655. if (typeof lastConnectOptions !== "undefined") {
  656. app = lastConnectOptions.app;
  657. }
  658. var connectObj = {
  659. sdk: { version: that._version, source: 0x09, protocol: 0x1 },
  660. app: app };
  661. var connectText = JSON.stringify(connectObj);
  662. console.log("[ChivoxWsEngine] send connect text");
  663. console.log(connectObj);
  664. that._wsClient.send({ data: connectText,
  665. fail: function fail(res) {
  666. console.warn("[ChivoxWsEngine] send connect text fail!!! errMsg: " + res.errMsg);
  667. }
  668. });
  669. that._status = ChivoxWsEngineStatus.Ready;
  670. if (typeof lastConnectOptions !== "undefined") {
  671. ChivoxFire.Success(lastConnectOptions);
  672. } else {
  673. console.error("[ChivoxWsEngine] _onWsOpen: lastConnectOptions undefined");
  674. }
  675. };
  676. }
  677. }, {
  678. key: "_onWsMessage",
  679. value: function _onWsMessage(wsClient) {
  680. var that = this;
  681. return function (res) {
  682. console.log("[ChivoxWsEngine] _onWsMessage(), at status: " + that._status);
  683. if (that._wsClient !== wsClient) {
  684. // 若引擎已被重置,则忽略本事件。
  685. console.log("[ChivoxWsEngine] _onWsMessage: engine has been reset. not current wsClient's event.");
  686. return;
  687. }
  688. var result = undefined;
  689. if ((typeof res === "undefined" ? "undefined" : _typeof(res)) === "object") {
  690. result = res.data;
  691. }
  692. if (typeof result !== "string" || result == "") {
  693. console.warn("[ChivoxWsEngine] _onWsMessage: server response empty result");
  694. return;
  695. }
  696. if (that._status == ChivoxWsEngineStatus.Ready) {
  697. console.warn("[ChivoxWsEngine] _onWsMessage: recv websocket response at Ready status, just ignore it. ");
  698. return;
  699. }
  700. if (that._status == ChivoxWsEngineStatus.Resulted) {
  701. console.warn("[ChivoxWsEngine] _onWsMessage: recv websocket response at Resulted status, just ignore it. ");
  702. return;
  703. }
  704. if (that._status != ChivoxWsEngineStatus.Evaluating && that._status != ChivoxWsEngineStatus.Resulting) {
  705. console.error("[ChivoxWsEngine] _onWsMessage: status error, status = " + that._status);
  706. return;
  707. }
  708. var needReset = false;
  709. try {
  710. result = JSON.parse(result);
  711. } catch (e) {
  712. needReset = true;
  713. result = {
  714. errId: ChivoxWsErr.ResultJsonParse,
  715. error: "[ChivoxWsEngine] the server response invalid json. ",
  716. tokenId: that._tokenId
  717. };
  718. }
  719. if ((typeof result === "undefined" ? "undefined" : _typeof(result)) !== "object") {
  720. needReset = true;
  721. result = {
  722. errId: ChivoxWsErr.ResultNotObject,
  723. error: "[ChivoxWsEngine] the server response is not json. ",
  724. tokenId: that._tokenId
  725. };
  726. }
  727. console.debug("[ChivoxWsEngine] result = " + JSON.stringify(result));
  728. // 以上的错误情况,定会把result.tokenId置为当前tokenId
  729. if (result.tokenId !== undefined && result.tokenId !== null) {
  730. if (result.tokenId !== that._tokenId) {
  731. // tokenId非当前请求的
  732. console.warn("[ChivoxWsEngine] _onWsMessage: tokenId (" + result.tokenId + ") not matched to " + that._tokenId);
  733. return;
  734. }
  735. }
  736. if (_typeof(result.error) === "object") {
  737. var errMsg = result.error.msg;
  738. result.errId = result.error.id;
  739. result.error = errMsg;
  740. if (result.tokenId === undefined || result.tokenId === null) {
  741. result.tokenId = that._tokenId;
  742. }
  743. needReset = true;
  744. }
  745. if (typeof result.errId === "number" && result.errId !== 0 || result.eof == 1) {
  746. that._status = ChivoxWsEngineStatus.Resulted;
  747. if (typeof that._waitTimer !== "undefined") {
  748. clearTimeout(that._waitTimer);
  749. that._waitTimer = undefined;
  750. }
  751. // 在收到最终结果后,强制关闭当前连接。即,每次评分都重新连接
  752. needReset = true;
  753. }
  754. if (needReset) that.reset();
  755. that._logBus({ est: ChivoxWsLogBus.GetResultSuccess, reason: result.eof });
  756. if (typeof result.errId === "number" && result.errId !== 0) {
  757. ChivoxFire.OnErrorResult(that, result);
  758. } else {
  759. ChivoxFire.OnResult(that, result);
  760. }
  761. };
  762. }
  763. }, {
  764. key: "_onWsError",
  765. value: function _onWsError(wsClient) {
  766. var that = this;
  767. return function (res) {
  768. console.log("[ChivoxWsEngine] _onWsError(), at status: " + that._status + ", res: " + JSON.stringify(res));
  769. if (that._wsClient !== wsClient) {
  770. console.log("[ChivoxWsEngine] _onWsError: engine has been reset. not current wsClient's event.");
  771. return;
  772. }
  773. var status = that._status;
  774. if (status == ChivoxWsEngineStatus.None) {
  775. // 逻辑上不可能出现这种情况
  776. console.error("[ChivoxWsEngine] _onWsError: code logic error, status: " + that._status);
  777. that.reset();
  778. return;
  779. }
  780. if (status == ChivoxWsEngineStatus.Connecting) {
  781. var lastConnectOptions = that._lastConnectOptions;
  782. if (that._reConnecting === ChivoxWsEngineReStatus.completed) {
  783. that._reConnecting = ChivoxWsEngineReStatus.reConnecting;
  784. setTimeout(function () {
  785. console.log("[ChivoxWsEngine] in _onWsError: webSocket reconnecting !!!");
  786. that._doConnect({
  787. app: lastConnectOptions.app,
  788. tcpNoDelay: lastConnectOptions.tcpNoDelay,
  789. success: function success() {
  790. that._doStart(that._lastStartOptions);
  791. },
  792. fail: function fail(res) {
  793. ChivoxFire.Fail(that._lastStartOptions, res);
  794. }
  795. });
  796. }, 100);
  797. } else {
  798. that._logBus({ est: ChivoxWsLogBus.WsConnectFail, reason: res.errMsg });
  799. var err = { errId: ChivoxWsErr.ConnectFail,
  800. error: "[ChivoxWsEngine] connect websocket server fail, " + res.errMsg + ". "
  801. };
  802. that.reset();
  803. if (typeof lastConnectOptions !== "undefined") {
  804. ChivoxFire.Fail(lastConnectOptions, err);
  805. } else {
  806. console.error("[ChivoxWsEngine] _onWsError: lastConnectOptions undefined");
  807. }
  808. }
  809. return;
  810. }
  811. if (status == ChivoxWsEngineStatus.Ready || status == ChivoxWsEngineStatus.Resulted) {
  812. that.reset();
  813. return;
  814. }
  815. if (status == ChivoxWsEngineStatus.Evaluating || status == ChivoxWsEngineStatus.Resulting) {
  816. var _err12 = { errId: ChivoxWsErr.NetException,
  817. error: "[ChivoxWsEngine] websocket error. errMsg: " + res.errMsg + ". ",
  818. tokenId: that._tokenId
  819. };
  820. that.reset();
  821. ChivoxFire.OnErrorResult(that, _err12);
  822. return;
  823. }
  824. };
  825. }
  826. }, {
  827. key: "_onWsClose",
  828. value: function _onWsClose(wsClient) {
  829. var that = this;
  830. return function (res) {
  831. if (that._reConnecting === ChivoxWsEngineReStatus.reConnecting) return;
  832. that._logBus({ est: ChivoxWsLogBus.WsConnectClose, reason: res.errMsg });
  833. console.log("[ChivoxWsEngine] _onWsClose(), at status: " + that._status);
  834. if (that._wsClient !== wsClient) {
  835. console.log("[ChivoxWsEngine] _onWsClose: engine has been reset. not current wsClient's event.");
  836. return;
  837. }
  838. var status = that._status;
  839. if (status == ChivoxWsEngineStatus.None) {
  840. // 逻辑上不可能出现这种情况
  841. console.error("[ChivoxWsEngine] _onWsClose: code logic error, status: " + that._status);
  842. that.reset();
  843. return;
  844. }
  845. if (status == ChivoxWsEngineStatus.Connecting) {
  846. var lastConnectOptions = that._lastConnectOptions;
  847. var err = { errId: ChivoxWsErr.ConnectFail,
  848. error: "[ChivoxWsEngine] connect websocket server fail, " + res.errMsg + ". "
  849. };
  850. that.reset();
  851. if (typeof lastConnectOptions !== "undefined") {
  852. ChivoxFire.Fail(lastConnectOptions, err);
  853. } else {
  854. console.error("[ChivoxWsEngine] _onWsClose: lastConnectOptions undefined");
  855. }
  856. return;
  857. }
  858. if (status == ChivoxWsEngineStatus.Ready || status == ChivoxWsEngineStatus.Resulted) {
  859. that.reset();
  860. return;
  861. }
  862. if (status == ChivoxWsEngineStatus.Evaluating || status == ChivoxWsEngineStatus.Resulting) {
  863. var _err13 = { errId: ChivoxWsErr.NetException,
  864. error: "[ChivoxWsEngine] websocket closed. errMsg: " + res.errMsg + ". ",
  865. tokenId: that._tokenId
  866. };
  867. that.reset();
  868. ChivoxFire.OnErrorResult(that, _err13);
  869. return;
  870. }
  871. };
  872. }
  873. }, {
  874. key: "_onWaitResultTimeout",
  875. value: function _onWaitResultTimeout() {
  876. var that = this;
  877. return function (res) {
  878. console.log("[ChivoxWsEngine] _onWaitResultTimeout, at status: " + that._status);
  879. that._logBus({ est: ChivoxWsLogBus.GetResultTimeOut, reason: "server timeout" });
  880. var status = that._status;
  881. if (status == ChivoxWsEngineStatus.Resulting) {
  882. var err = { errId: ChivoxWsErr.ServerTimeout,
  883. error: "[ChivoxWsEngine] server timeout",
  884. tokenId: that._tokenId
  885. };
  886. that.reset();
  887. ChivoxFire.OnErrorResult(that, err);
  888. return;
  889. }
  890. // 逻辑上不可能执行到这里
  891. that.reset();
  892. console.error("[ChivoxWsEngine] _onWaitResultTimeout: status error, status: " + that._status);
  893. };
  894. }
  895. }, {
  896. key: "_logBus",
  897. value: function _logBus(options) {
  898. var that = this;
  899. var os_res = wx.getSystemInfoSync();
  900. options.os_version = os_res.system;
  901. options.timeStamp = new Date().getTime();
  902. options.uid = typeof that._lastStartOptions.request.uid == "string" ? that._lastStartOptions.request.uid : "unknow";
  903. options.appId = that._lastStartOptions.app.applicationId;
  904. options.reason = typeof options.reason == "string" ? options.reason : "unknow";
  905. var log_bus = { uid: options.uid, applicationId: options.appId, protocol: "1", os_version: options.os_version, body: [{ est: options.est, timestamp: options.timeStamp, reason: options.reason }] };
  906. wx.request({
  907. url: "https://log.cloud.chivox.com/bus?ver=2",
  908. method: "POST",
  909. data: "log=" + JSON.stringify(log_bus),
  910. fail: function fail(res) {
  911. console.error("[ChivoxWsEngine] _logBus():send logbus fail," + res.errMsg);
  912. }
  913. });
  914. }
  915. }]);
  916. return ChivoxWsEngine;
  917. }();
  918. /*
  919. 状态转换图:
  920. None
  921. Ready <----+ <-------------------+ <--+
  922. ↓ | | |
  923. Starting --+ | |
  924. ↓ | |
  925. (Recording<-->Paused) --+ | |
  926. ↓ ↓ | |
  927. Stoping -----------> Canceling --+ |
  928. ↓ ↑ |
  929. Resulting --------------+-------------+
  930. */
  931. var ChivoxAiEngineStatus = {
  932. None: "None", // 无状态
  933. Ready: "Ready", // 就绪态 (初始化完成 或 评分已结束 或 评分已取消)
  934. Starting: "Starting", // 正在开始
  935. Recording: "Recording", // 录音中
  936. Paused: "Paused", // 录音暂停
  937. Stoping: "Stoping", // 正在结束
  938. Resulting: "Resulting", // 等待结果中 (此时录音机已关闭)
  939. Canceling: "Canceling" // 正在取消
  940. };
  941. var ChivoxAiEngine = function () {
  942. function ChivoxAiEngine() {
  943. _classCallCheck(this, ChivoxAiEngine);
  944. var that = this;
  945. that._version = ChivoxSdkVersion;
  946. that._status = ChivoxAiEngineStatus.None;
  947. that._wsEngine = undefined;
  948. that._recorder = undefined;
  949. that._onRecorderStart = undefined;
  950. that._onRecorderPause = undefined;
  951. that._onRecorderResume = undefined;
  952. that._onRecorderStop = undefined;
  953. that._onRecorderError = undefined;
  954. that._onRecorderFrame = undefined;
  955. that._onResult = undefined;
  956. that._onErrorResult = undefined;
  957. that._lastStartOptions = undefined;
  958. that._lastStopOptions = undefined;
  959. that._lastCancelOptions = undefined;
  960. that._stopOriStatus = undefined;
  961. that._cancelOriStatus = undefined;
  962. that._serverTimeout = 60000; //评分超时时间
  963. }
  964. _createClass(ChivoxAiEngine, [{
  965. key: "getVersion",
  966. value: function getVersion() {
  967. var that = this;return ChivoxUtils.getVersion(that._version);
  968. }
  969. /**
  970. * createWsEngine 创建Websocket引擎
  971. * @param {boolean} gray [可选] 是否使用灰度服
  972. * @param {string} server [可选-非公开] 指定服务器,如果传入此参数,则忽略gray
  973. */
  974. }, {
  975. key: "createWsEngine",
  976. value: function createWsEngine(cfg) {
  977. var wsEngine = new ChivoxWsEngine();
  978. wsEngine.init(cfg);
  979. return wsEngine;
  980. }
  981. /**
  982. * 录音开始事件
  983. * @param {function} func 回调函数
  984. * func 的参数 void
  985. */
  986. }, {
  987. key: "onRecorderStart",
  988. value: function onRecorderStart(func) {
  989. this._onRecorderStart = func;
  990. }
  991. /**
  992. * 录音暂停事件
  993. * @param {function} func 回调函数
  994. * func 的参数 void
  995. */
  996. }, {
  997. key: "onRecorderPause",
  998. value: function onRecorderPause(func) {
  999. this._onRecorderPause = func;
  1000. }
  1001. /**
  1002. * 录音恢复事件
  1003. * @param {function} func 回调函数
  1004. * func 的参数 void
  1005. */
  1006. }, {
  1007. key: "onRecorderResume",
  1008. value: function onRecorderResume(func) {
  1009. this._onRecorderResume = func;
  1010. }
  1011. /**
  1012. * 接收录音数据事件
  1013. * @param {function} func 回调函数
  1014. * func 的参数 {object} res - 录音分片数据
  1015. * frameBuffer {ArrayBuffer} 录音分片数据
  1016. * isLastFrame {boolean} 当前帧是否正常录音结束前的最后一帧
  1017. * */
  1018. }, {
  1019. key: "onRecorderFrame",
  1020. value: function onRecorderFrame(func) {
  1021. this._onRecorderFrame = func;
  1022. }
  1023. /**
  1024. * 录音停止事件
  1025. * @param {function} func 回调函数
  1026. * func 的参数 {object} res
  1027. * waitingResult: {boolean} 是否需等待评分结果
  1028. * tempFilePath: {string} 录音文件路径,这是个临时文件
  1029. */
  1030. }, {
  1031. key: "onRecorderStop",
  1032. value: function onRecorderStop(func) {
  1033. this._onRecorderStop = func;
  1034. }
  1035. /**
  1036. * 录音机错误事件
  1037. * @param {function} func 回调函数
  1038. * func 的参数 {object} res
  1039. * errId: {int} 错误ID
  1040. * error: {string} 错误描述
  1041. */
  1042. }, {
  1043. key: "onRecorderError",
  1044. value: function onRecorderError(func) {
  1045. this._onRecorderError = func;
  1046. }
  1047. /**
  1048. * 评分结果回调
  1049. * @param {function} func 回调函数
  1050. * func 的参数 {object} res - 评分结果
  1051. */
  1052. }, {
  1053. key: "onResult",
  1054. value: function onResult(func) {
  1055. this._onResult = func;
  1056. }
  1057. /**
  1058. * 错误结果回调
  1059. * 当收到此回调时,请调用 aiengine_cancel 取消当前评测。
  1060. * @param {function} func 回调函数
  1061. * func 的参数 {object} res - 评分结果
  1062. * errId: {int} 错误ID
  1063. * error: {string} 错误描述
  1064. * tokenId: {string} 评分任务唯一标识
  1065. */
  1066. }, {
  1067. key: "onErrorResult",
  1068. value: function onErrorResult(func) {
  1069. this._onErrorResult = func;
  1070. }
  1071. /**
  1072. * aiengine_new 初始化评分引擎 (本函数一旦调用成功以后,请永远不要再次调用了)。
  1073. * @param {boolean} gray [可选] 是否使用灰度服务器
  1074. * @param {string} server [可选,非公开] 使用特定的服务器地址,若传入此参数,则忽略gray
  1075. * @param {function} success [必须] 接口调用成功事件
  1076. * @param {function} fail [必须] 接口调用失败事件
  1077. * fail 的参数 {object} res
  1078. * errId: {int} 错误ID
  1079. * error: {string} 错误描述
  1080. * @param {function} complete [可选] 接口调用完毕事件
  1081. */
  1082. }, {
  1083. key: "aiengine_new",
  1084. value: function aiengine_new(options) {
  1085. var that = this;
  1086. console.log("[ChivoxAiEngine] aiengine_new()");
  1087. if (that._status != ChivoxAiEngineStatus.None) {
  1088. var err = { errId: ChivoxAiErr.NewRepeatedly,
  1089. error: "[ChivoxAiEngine] call 'aiengine_new' repeatedly. "
  1090. };
  1091. ChivoxFire.Fail(options, err);
  1092. return;
  1093. }
  1094. // 创建 ChivoxWsEngine
  1095. if (typeof that._wsEngine === "undefined") {
  1096. that._wsEngine = that.createWsEngine({
  1097. gray: options.gray, server: options.server
  1098. });
  1099. that._wsEngine.onResult(that._wsEngineOnResult());
  1100. that._wsEngine.onErrorResult(that._wsEngineOnErrorResult());
  1101. }
  1102. that._status = ChivoxAiEngineStatus.Ready;
  1103. ChivoxFire.Success(options);
  1104. }
  1105. /**
  1106. * aiengine_start 启动评分引擎
  1107. * @param {object} app [必须] 身份验证信息,在连接服务器时使用。
  1108. * @param {object} request [必须] 评分请求
  1109. * @param {object} audio [可选] 录音参数。
  1110. * {
  1111. * sampleRate: {int} [可选-默认值16000] 录音采样率 取值范围 (16000, 44100)
  1112. * duration: {int} [可选-默认值600000] 录音时长,单位毫秒,到达该时长后录音机自动停止。
  1113. * }
  1114. * @param {function} success [必须] 接口调用成功事件(收到此事件时录音机已开始录音)
  1115. * success 的参数 {object} res
  1116. * {
  1117. * tokenId: {string} 评分任务唯一标识
  1118. * }
  1119. * @param {function} fail [必须] 接口调用失败事件
  1120. * fail 的参数 {object} res
  1121. * {
  1122. * errId: {int} 错误ID
  1123. * error: {string} 错误描述
  1124. * }
  1125. * @param {function} complete [可选] 接口调用完毕事件
  1126. */
  1127. }, {
  1128. key: "aiengine_start",
  1129. value: function aiengine_start(options) {
  1130. var that = this;
  1131. console.log("[ChivoxAiEngine] aiengine_start()");
  1132. if (that._status != ChivoxAiEngineStatus.Ready) {
  1133. if (that._status == ChivoxAiEngineStatus.None) {
  1134. var _err15 = { errId: ChivoxAiErr.NotYetNew,
  1135. error: "[ChivoxAiEngine] you must call 'aiengine_new' first. "
  1136. };
  1137. ChivoxFire.Fail(options, _err15);
  1138. return;
  1139. }
  1140. if (that._status == ChivoxAiEngineStatus.Starting || that._status == ChivoxAiEngineStatus.Recording || that._status == ChivoxAiEngineStatus.Paused) {
  1141. var _err16 = { errId: ChivoxAiErr.StartRepeatedly,
  1142. error: "[ChivoxAiEngine] you should not call 'aiengine_start' repeatedly. "
  1143. };
  1144. ChivoxFire.Fail(options, _err16);
  1145. return;
  1146. }
  1147. if (that._status == ChivoxAiEngineStatus.Stoping) {
  1148. var _err17 = { errId: ChivoxAiErr.WaitStopFinish,
  1149. error: "[ChivoxAiEngine] you must wait 'aiengine_stop' completed. "
  1150. };
  1151. ChivoxFire.Fail(options, _err17);
  1152. return;
  1153. }
  1154. if (that._status == ChivoxAiEngineStatus.Resulting) {
  1155. var _err18 = { errId: ChivoxAiErr.WaitResulted,
  1156. error: "[ChivoxAiEngine] you must wait engine result. "
  1157. };
  1158. ChivoxFire.Fail(options, _err18);
  1159. return;
  1160. }
  1161. if (that._status == ChivoxAiEngineStatus.Canceling) {
  1162. var _err19 = { errId: ChivoxAiErr.WaitCancelFinish,
  1163. error: "[ChivoxAiEngine] you must wait 'aiengine_cancel' completed. "
  1164. };
  1165. ChivoxFire.Fail(options, _err19);
  1166. return;
  1167. }
  1168. // 逻辑上不可能执行到这里
  1169. var _err14 = { errId: ChivoxAiErr.EngineStatus,
  1170. error: "[ChivoxAiEngine] engine status error, status: " + that._status + ". "
  1171. };
  1172. ChivoxFire.Fail(options, _err14);
  1173. return;
  1174. }
  1175. that._status = ChivoxAiEngineStatus.Starting;
  1176. var err = {};
  1177. if (!ChivoxUtils.isValidRequest(options.request, err, "[ChivoxAiEngine]")) {
  1178. that._status = ChivoxAiEngineStatus.Ready;
  1179. ChivoxFire.Fail(options, err);
  1180. return;
  1181. }
  1182. err = {};
  1183. if (!ChivoxUtils.isValidApp(options.app, err, "[ChivoxAiEngine]")) {
  1184. that._status = ChivoxAiEngineStatus.Ready;
  1185. ChivoxFire.Fail(options, err);
  1186. return;
  1187. }
  1188. that._recorderBind();
  1189. // ---- audio ----
  1190. var audioOpt = {
  1191. duration: 600000, // 默认录音时长, 微信录音机最大支持 600000 毫秒
  1192. format: "mp3",
  1193. numberOfChannels: 1,
  1194. sampleRate: 16000, // 默认采样率 16000
  1195. frameSize: 5 // 每帧5KB
  1196. };
  1197. if (_typeof(options.audio) === "object") {
  1198. if (typeof options.audio.sampleRate === "number") {
  1199. audioOpt.sampleRate = options.audio.sampleRate;
  1200. }
  1201. if (typeof options.audio.duration === "number" && options.audio.duration >= 500 && options.audio.duration < 600000) {
  1202. audioOpt.duration = options.audio.duration;
  1203. }
  1204. }
  1205. if (audioOpt.sampleRate >= 44100) {
  1206. audioOpt.encodeBitRate = 128000;
  1207. }
  1208. // ---- audio ----
  1209. that._lastStartOptions = options;
  1210. that._recorder.start(audioOpt);
  1211. }
  1212. /**
  1213. * aiengine_stop 结束评测 (如果小程序进入后台,请不要调用这个方法)
  1214. * @param {function} success [必须] 接口调用成功事件(收到此事件时录音机已开始录音)
  1215. * @param {function} fail [必须] 接口调用失败事件
  1216. * fail 的参数 {object} res
  1217. * {
  1218. * errId: {int} 错误ID
  1219. * error: {string} 错误描述
  1220. * }
  1221. * @param {function} complete [可选] 接口调用完毕事件
  1222. */
  1223. }, {
  1224. key: "aiengine_stop",
  1225. value: function aiengine_stop(options) {
  1226. var that = this;
  1227. console.log("[ChivoxAiEngine] aiengine_stop()");
  1228. if (that._status != ChivoxAiEngineStatus.Recording && that._status != ChivoxAiEngineStatus.Paused) {
  1229. if (that._status == ChivoxAiEngineStatus.None) {
  1230. var _err20 = { errId: ChivoxAiErr.NotYetNew,
  1231. error: "[ChivoxAiEngine] you must call 'aiengine_new' first. "
  1232. };
  1233. ChivoxFire.Fail(options, _err20);
  1234. return;
  1235. }
  1236. if (that._status == ChivoxAiEngineStatus.Ready) {
  1237. var _err21 = { errId: ChivoxAiErr.NotYetStart,
  1238. error: "[ChivoxAiEngine] you must call 'aiengine_start' first. "
  1239. };
  1240. ChivoxFire.Fail(options, _err21);
  1241. return;
  1242. }
  1243. if (that._status == ChivoxAiEngineStatus.Starting) {
  1244. var _err22 = { errId: ChivoxAiErr.WaitStartFinish,
  1245. error: "[ChivoxAiEngine] you must wait 'aiengine_start' completed. "
  1246. };
  1247. ChivoxFire.Fail(options, _err22);
  1248. return;
  1249. }
  1250. if (that._status == ChivoxAiEngineStatus.Stoping || that._status == ChivoxAiEngineStatus.Resulting) {
  1251. var _err23 = { errId: ChivoxAiErr.StopRepeatedly,
  1252. error: "[ChivoxAiEngine] you should not call 'aiengine_stop' repeatedly. "
  1253. };
  1254. ChivoxFire.Fail(options, _err23);
  1255. return;
  1256. }
  1257. if (that._status == ChivoxAiEngineStatus.Canceling) {
  1258. var _err24 = { errId: ChivoxAiErr.WaitCancelFinish,
  1259. error: "[ChivoxAiEngine] you must wait 'aiengine_cancel' completed. "
  1260. };
  1261. ChivoxFire.Fail(options, _err24);
  1262. return;
  1263. }
  1264. // 逻辑上不可能执行到这里
  1265. var err = { errId: ChivoxAiErr.EngineStatus,
  1266. error: "[ChivoxAiEngine] engine status error, status: " + that._status + ". "
  1267. };
  1268. ChivoxFire.Fail(options, err);
  1269. return;
  1270. }
  1271. var oldStatus = that._status;
  1272. that._status = ChivoxAiEngineStatus.Stoping;
  1273. that._lastStopOptions = options;
  1274. that._stopOriStatus = oldStatus;
  1275. that._recorder.stop();
  1276. }
  1277. /**
  1278. * 暂停录音
  1279. */
  1280. }, {
  1281. key: "aiengine_pause",
  1282. value: function aiengine_pause() {
  1283. var that = this;
  1284. console.log("[ChivoxAiEngine] aiengine_pause(), at status: " + that._status);
  1285. if (that._status != ChivoxAiEngineStatus.Recording) {
  1286. if (that._status == ChivoxAiEngineStatus.Paused) {
  1287. return;
  1288. }
  1289. //console.warn("[ChivoxAiEngine] aiengine_pause: status is not recording, status: " + that._status);
  1290. return;
  1291. }
  1292. that._recorder.pause();
  1293. }
  1294. /**
  1295. * 恢复录音
  1296. */
  1297. }, {
  1298. key: "aiengine_resume",
  1299. value: function aiengine_resume() {
  1300. var that = this;
  1301. console.log("[ChivoxAiEngine] aiengine_resume(), at status: " + that._status);
  1302. if (that._status != ChivoxAiEngineStatus.Paused) {
  1303. if (that._status == ChivoxAiEngineStatus.Recording) {
  1304. return;
  1305. }
  1306. //console.warn("[ChivoxAiEngine] aiengine_resume: status error, status: " + that._status);
  1307. return;
  1308. }
  1309. that._recorder.resume();
  1310. }
  1311. /**
  1312. * aiengine_opt 设置引擎参数(评分超时时间)
  1313. * key {string} [必须] 当key为serverTimeout,将value赋值到 this._serverTimeout
  1314. * value {number} [必须] value值为 ms,
  1315. * */
  1316. }, {
  1317. key: "aiengine_opt",
  1318. value: function aiengine_opt(key, value) {
  1319. var that = this;
  1320. var allow_opt = ["serverTimeout"];
  1321. if (allow_opt.includes(key) > -1) {
  1322. that["_" + key] = value;
  1323. }
  1324. }
  1325. /**
  1326. * aiengine_cancel 取消评测 (如果小程序进入后台,请不要调用这个方法)
  1327. * @param {function} success [必须] 接口调用成功事件(收到此事件时录音机已开始录音)
  1328. * @param {function} fail [必须] 接口调用失败事件
  1329. * fail 的参数 {object} res
  1330. * {
  1331. * errId: {int} 错误ID
  1332. * error: {string} 错误描述
  1333. * }
  1334. * @param {function} complete [可选] 接口调用完毕事件
  1335. */
  1336. }, {
  1337. key: "aiengine_cancel",
  1338. value: function aiengine_cancel(options) {
  1339. var that = this;
  1340. console.log("[ChivoxAiEngine] aiengine_cancel(), at status: " + that._status);
  1341. if (that._status != ChivoxAiEngineStatus.Ready && that._status != ChivoxAiEngineStatus.Recording && that._status != ChivoxAiEngineStatus.Paused && that._status != ChivoxAiEngineStatus.Stoping && that._status != ChivoxAiEngineStatus.Resulting) {
  1342. if (that._status == ChivoxAiEngineStatus.None) {
  1343. var _err25 = { errId: ChivoxAiErr.NotYetNew,
  1344. error: "[ChivoxAiEngine] you must call 'aiengine_new' first. "
  1345. };
  1346. ChivoxFire.Fail(options, _err25);
  1347. return;
  1348. }
  1349. if (that._status == ChivoxAiEngineStatus.Starting) {
  1350. var _err26 = { errId: ChivoxAiErr.WaitStartFinish,
  1351. error: "[ChivoxAiEngine] you must wait 'aiengine_start' completed. "
  1352. };
  1353. ChivoxFire.Fail(options, _err26);
  1354. return;
  1355. }
  1356. if (that._status == ChivoxAiEngineStatus.Canceling) {
  1357. var _err27 = { errId: ChivoxAiErr.WaitCancelFinish,
  1358. error: "[ChivoxAiEngine] you must wait 'aiengine_cancel' completed. "
  1359. };
  1360. ChivoxFire.Fail(options, _err27);
  1361. return;
  1362. }
  1363. // 逻辑上不可能执行到这里
  1364. var err = { errId: ChivoxAiErr.EngineStatus,
  1365. error: "[ChivoxAiEngine] engine status error, status: " + that._status + ". "
  1366. };
  1367. ChivoxFire.Fail(options, err);
  1368. return;
  1369. }
  1370. if (that._status == ChivoxAiEngineStatus.Ready) {
  1371. ChivoxFire.Success(options);
  1372. return;
  1373. }
  1374. if (that._status == ChivoxAiEngineStatus.Recording || that._status == ChivoxAiEngineStatus.Paused) {
  1375. var oldStatus = that._status;
  1376. that._status = ChivoxAiEngineStatus.Canceling;
  1377. that._lastCancelOptions = options;
  1378. that._cancelOriStatus = oldStatus;
  1379. that._recorder.stop();
  1380. return;
  1381. }
  1382. if (that._status == ChivoxAiEngineStatus.Stoping) {
  1383. that._lastCancelOptions = options;
  1384. that._cancelOriStatus = that._stopOriStatus;
  1385. that._status = ChivoxAiEngineStatus.Canceling;
  1386. var _err28 = { errId: ChivoxAiErr.OperationCanceled,
  1387. error: "[ChivoxAiEngine] the call of 'aiengine_stop' has be canceled. "
  1388. };
  1389. var lastStopOptions = that._lastStopOptions;
  1390. that._lastStopOptions = undefined;
  1391. that._stopOriStatus = undefined;
  1392. if (typeof lastStopOptions !== "undefined") {
  1393. ChivoxFire.Fail(lastStopOptions, _err28);
  1394. } else {
  1395. console.error("[ChivoxAiEngine] aiengine_cancel: _lastStopOptions undefined");
  1396. }
  1397. return;
  1398. }
  1399. if (that._status == ChivoxAiEngineStatus.Resulting) {
  1400. that._wsEngine.reset();
  1401. that._status = ChivoxAiEngineStatus.Ready;
  1402. ChivoxFire.Success(options);
  1403. return;
  1404. }
  1405. return;
  1406. }
  1407. }, {
  1408. key: "_wsEngineOnResult",
  1409. value: function _wsEngineOnResult() {
  1410. var that = this;
  1411. return function (res) {
  1412. console.log("[ChivoxAiEngine] _wsEngineOnResult(), at status: " + that._status);
  1413. if (that._status != ChivoxAiEngineStatus.Recording && that._status != ChivoxAiEngineStatus.Paused && that._status != ChivoxAiEngineStatus.Stoping && that._status != ChivoxAiEngineStatus.Resulting) {
  1414. console.warn("[ChivoxAiEngine] _wsEngineOnResult: status error, status: " + that._status);
  1415. return;
  1416. }
  1417. if (that._status == ChivoxAiEngineStatus.Recording || that._status == ChivoxAiEngineStatus.Paused || that._status == ChivoxAiEngineStatus.Stoping) {
  1418. if (res.eof == 1) {
  1419. console.warn("[ChivoxAiEngine] _wsEngineOnResult: server response result eof=1, but we never send stop!!!");
  1420. }
  1421. ChivoxFire.OnResult(that, res);
  1422. return;
  1423. }
  1424. if (that._status == ChivoxAiEngineStatus.Resulting) {
  1425. if (res.eof == 1) {
  1426. that._status = ChivoxAiEngineStatus.Ready;
  1427. }
  1428. ChivoxFire.OnResult(that, res);
  1429. return;
  1430. }
  1431. };
  1432. }
  1433. }, {
  1434. key: "_wsEngineOnErrorResult",
  1435. value: function _wsEngineOnErrorResult() {
  1436. var that = this;
  1437. return function (res) {
  1438. console.log("[ChivoxAiEngine] _wsEngineOnErrorResult(), at status: " + that._status);
  1439. if (that._status != ChivoxAiEngineStatus.Recording && that._status != ChivoxAiEngineStatus.Paused && that._status != ChivoxAiEngineStatus.Stoping && that._status != ChivoxAiEngineStatus.Resulting) {
  1440. console.warn("[ChivoxAiEngine] _wsEngineOnErrorResult: status error, status: " + that._status);
  1441. return;
  1442. }
  1443. if (that._status == ChivoxAiEngineStatus.Recording || that._status == ChivoxAiEngineStatus.Paused || that._status == ChivoxAiEngineStatus.Stoping) {
  1444. ChivoxFire.OnErrorResult(that, res);
  1445. return;
  1446. }
  1447. if (that._status == ChivoxAiEngineStatus.Resulting) {
  1448. that._status = ChivoxAiEngineStatus.Ready;
  1449. ChivoxFire.OnErrorResult(that, res);
  1450. return;
  1451. }
  1452. };
  1453. }
  1454. }, {
  1455. key: "_recorderBind",
  1456. value: function _recorderBind() {
  1457. var that = this;
  1458. if (this._recorder) {
  1459. this._recorderUnbind();
  1460. }
  1461. this._recorder = wx.getRecorderManager();
  1462. this._recorder.onStart(that._recorderOnStart());
  1463. this._recorder.onPause(that._recorderOnPause());
  1464. this._recorder.onStop(that._recorderOnStop());
  1465. this._recorder.onError(that._recorderOnError());
  1466. this._recorder.onFrameRecorded(that._recorderOnFrame());
  1467. }
  1468. }, {
  1469. key: "_recorderUnbind",
  1470. value: function _recorderUnbind() {
  1471. if (this._recorder) {
  1472. this._recorder.onStart(null);
  1473. this._recorder.onPause(null);
  1474. this._recorder.onStop(null);
  1475. this._recorder.onError(null);
  1476. this._recorder.onFrameRecorded(null);
  1477. this._recorder = null;
  1478. }
  1479. }
  1480. }, {
  1481. key: "_recorderOnStart",
  1482. value: function _recorderOnStart() {
  1483. var that = this;
  1484. return function (res) {
  1485. console.log("[ChivoxAiEngine] _recorderOnStart(), at status: " + that._status);
  1486. if (that._status != ChivoxAiEngineStatus.Paused && that._status != ChivoxAiEngineStatus.Starting) {
  1487. that._status = ChivoxAiEngineStatus.Recording;
  1488. console.error("[ChivoxAiEngine] _recorderOnStart: status error, status: " + that._status);
  1489. return;
  1490. }
  1491. if (that._status == ChivoxAiEngineStatus.Paused) {
  1492. // 恢复录音机
  1493. that._status = ChivoxAiEngineStatus.Recording;
  1494. ChivoxFire.OnRecorderResume(that, res);
  1495. return;
  1496. }
  1497. if (that._status == ChivoxAiEngineStatus.Starting) {
  1498. // 启动录音机
  1499. that._status = ChivoxAiEngineStatus.Recording;
  1500. that._msgQueue = [];
  1501. that._allAudioFrames = [];
  1502. var lastStartOptions = that._lastStartOptions;
  1503. that._lastStartOptions = undefined;
  1504. if (typeof lastStartOptions === "undefined") {
  1505. console.error("[ChivoxAiEngine] _recorderOnStart: _lastStartOptions undefined");
  1506. return;
  1507. }
  1508. var tokenId = ChivoxUtils.generateGuid().replace(/-/g, "");
  1509. // ---- audio ----
  1510. var sysInfo = wx.getSystemInfoSync();
  1511. var audio = {
  1512. audioType: "mp3",
  1513. channel: 1,
  1514. sampleBytes: 2,
  1515. sampleRate: 16000
  1516. };
  1517. if (sysInfo.platform === "devtools") {
  1518. audio.audioType = "opus";
  1519. }
  1520. if (_typeof(lastStartOptions.audio) === "object" && typeof lastStartOptions.audio.sampleRate === "number") {
  1521. audio.sampleRate = lastStartOptions.audio.sampleRate;
  1522. }
  1523. // ---- audio ----
  1524. that._wsEngine.start({
  1525. tokenId: tokenId,
  1526. request: lastStartOptions.request,
  1527. audio: audio,
  1528. app: lastStartOptions.app,
  1529. tcpNoDelay: lastStartOptions.tcpNoDelay,
  1530. fail: function fail(res) {
  1531. console.log("[ChivoxAiEngine] wsEngine start fail! " + JSON.stringify(res));
  1532. that._wsEngine.reset();
  1533. ChivoxFire.OnErrorResult(that, res);
  1534. }, success: function success(res) {
  1535. console.log("[ChivoxAiEngine] wsEngine start success!");
  1536. that.__msgIterate();
  1537. }
  1538. });
  1539. ChivoxFire.Success(lastStartOptions, { tokenId: tokenId });
  1540. ChivoxFire.OnRecorderStart(that);
  1541. }
  1542. };
  1543. }
  1544. }, {
  1545. key: "_recorderOnPause",
  1546. value: function _recorderOnPause() {
  1547. var that = this;
  1548. return function (res) {
  1549. console.log("[ChivoxAiEngine] _recorderOnPause(), at status: " + that._status);
  1550. if (that._status != ChivoxAiEngineStatus.Recording) {
  1551. that._status = ChivoxAiEngineStatus.Paused;
  1552. console.error("[ChivoxAiEngine] _recorderOnPause: status error, status: " + that._status);
  1553. return;
  1554. }
  1555. that._status = ChivoxAiEngineStatus.Paused;
  1556. ChivoxFire.OnRecorderPause(that, res);
  1557. };
  1558. }
  1559. }, {
  1560. key: "_recorderOnStop",
  1561. value: function _recorderOnStop() {
  1562. var that = this;
  1563. return function (res) {
  1564. console.log("[ChivoxAiEngine] _recorderOnStop(), at status: " + that._status);
  1565. that._recorderUnbind();
  1566. if (that._status != ChivoxAiEngineStatus.Recording && that._status != ChivoxAiEngineStatus.Paused && that._status != ChivoxAiEngineStatus.Stoping && that._status != ChivoxAiEngineStatus.Canceling) {
  1567. console.error("[ChivoxAiEngine] _recorderOnStop: status error, status: " + that._status);
  1568. that._wsEngine.reset();
  1569. that._status = ChivoxAiEngineStatus.Ready;
  1570. ChivoxFire.OnRecorderStop(that, {
  1571. waitingResult: false,
  1572. tempFilePath: res.tempFilePath
  1573. });
  1574. return;
  1575. }
  1576. if (that._status == ChivoxAiEngineStatus.Recording || that._status == ChivoxAiEngineStatus.Paused) {
  1577. // 录音超时自动停止
  1578. that._status = ChivoxAiEngineStatus.Resulting;
  1579. if (typeof that._msgQueue !== "undefined") {
  1580. that._msgQueue.push({ cmd: "stop" });
  1581. setTimeout(function () {
  1582. that.__msgIterate();
  1583. }, 1);
  1584. }
  1585. ChivoxFire.OnRecorderStop(that, {
  1586. waitingResult: true,
  1587. tempFilePath: res.tempFilePath
  1588. });
  1589. return;
  1590. }
  1591. if (that._status == ChivoxAiEngineStatus.Stoping) {
  1592. // 停止录音机成功
  1593. that._status = ChivoxAiEngineStatus.Resulting;
  1594. if (typeof that._msgQueue !== "undefined") {
  1595. that._msgQueue.push({ cmd: "stop" });
  1596. setTimeout(function () {
  1597. that.__msgIterate();
  1598. }, 1);
  1599. }
  1600. var lastStopOptions = that._lastStopOptions;
  1601. that._lastStopOptions = undefined;
  1602. that._stopOriStatus = undefined;
  1603. if (typeof lastStopOptions !== "undefined") {
  1604. ChivoxFire.Success(lastStopOptions);
  1605. } else {
  1606. console.error("[ChivoxAiEngine] _recorderOnStop: _lastStopOptions undefined");
  1607. }
  1608. ChivoxFire.OnRecorderStop(that, {
  1609. waitingResult: true,
  1610. tempFilePath: res.tempFilePath
  1611. });
  1612. return;
  1613. }
  1614. if (that._status == ChivoxAiEngineStatus.Canceling) {
  1615. // 取消录音成功
  1616. that._wsEngine.reset();
  1617. that._status = ChivoxAiEngineStatus.Ready;
  1618. var lastCancelOptions = that._lastCancelOptions;
  1619. that._lastCancelOptions = undefined;
  1620. that._cancelOriStatus = undefined;
  1621. if (typeof lastCancelOptions !== "undefined") {
  1622. ChivoxFire.Success(lastCancelOptions);
  1623. } else {
  1624. console.error("[ChivoxAiEngine] _recorderOnStop: _lastCancelOptions undefined");
  1625. }
  1626. ChivoxFire.OnRecorderStop(that, {
  1627. waitingResult: false,
  1628. tempFilePath: res.tempFilePath
  1629. });
  1630. return;
  1631. }
  1632. };
  1633. }
  1634. }, {
  1635. key: "_recorderOnError",
  1636. value: function _recorderOnError() {
  1637. var that = this;
  1638. return function (res) {
  1639. console.log("[ChivoxAiEngine] _recorderOnError(), errMsg: " + res.errMsg);
  1640. that._recorderUnbind();
  1641. if (that._status != ChivoxAiEngineStatus.Starting && that._status != ChivoxAiEngineStatus.Recording && that._status != ChivoxAiEngineStatus.Paused && that._status != ChivoxAiEngineStatus.Stoping && that._status != ChivoxAiEngineStatus.Canceling) {
  1642. var err = { errId: ChivoxAiErr.WxRecorderError,
  1643. error: "[ChivoxAiEngine] recorder error at status(" + that._status + "), errMsg(" + res.errMsg + "). "
  1644. };
  1645. ChivoxFire.OnRecorderError(that, err);
  1646. return;
  1647. }
  1648. if (that._status == ChivoxAiEngineStatus.Starting) {
  1649. // 在开启录音机的时候发生错误
  1650. that._status = ChivoxAiEngineStatus.Ready;
  1651. var _err29 = { errId: ChivoxAiErr.StartRecorderFail,
  1652. error: "[ChivoxAiEngine] start recorder fail, errMsg(" + res.errMsg + "). "
  1653. };
  1654. var lastStartOptions = that._lastStartOptions;
  1655. that._lastStartOptions = undefined;
  1656. if (typeof lastStartOptions !== "undefined") {
  1657. ChivoxFire.Fail(lastStartOptions, _err29);
  1658. } else {
  1659. console.error("[ChivoxAiEngine] _recorderOnError: _lastStartOptions undefined");
  1660. }
  1661. return;
  1662. }
  1663. if (that._status == ChivoxAiEngineStatus.Recording || that._status == ChivoxAiEngineStatus.Paused) {
  1664. // 录音机在录音过程中发生错误
  1665. var _err30 = { errId: ChivoxAiErr.WxRecorderError,
  1666. error: "[ChivoxAiEngine] recorder error at status(" + that._status + "), errMsg(" + res.errMsg + "). "
  1667. };
  1668. ChivoxFire.OnRecorderError(that, _err30);
  1669. return;
  1670. }
  1671. if (that._status == ChivoxAiEngineStatus.Stoping) {
  1672. // 在停止录音机的时候发生错误
  1673. that._status = that._stopOriStatus;
  1674. var _err31 = { errId: ChivoxAiErr.StopRecorderFail,
  1675. error: "[ChivoxAiEngine] recorder stop fail, errMsg(" + res.errMsg + "). "
  1676. };
  1677. var lastStopOptions = that._lastStopOptions;
  1678. that._lastStopOptions = undefined;
  1679. that._stopOriStatus = undefined;
  1680. if (typeof lastStopOptions !== "undefined") {
  1681. ChivoxFire.Fail(lastStopOptions, _err31);
  1682. } else {
  1683. console.error("[ChivoxAiEngine] _recorderOnError: _lastStopOptions undefined");
  1684. }
  1685. return;
  1686. }
  1687. if (that._status == ChivoxAiEngineStatus.Canceling) {
  1688. // 在停止录音机的时候发生错误
  1689. that._status = that._cancelOriStatus;
  1690. var _err32 = { errId: ChivoxAiErr.CancelRecorderFail,
  1691. error: "[ChivoxAiEngine] recorder cancel fail, errMsg(" + res.errMsg + "). "
  1692. };
  1693. var lastCancelOptions = that._lastCancelOptions;
  1694. that._lastCancelOptions = undefined;
  1695. that._cancelOriStatus = undefined;
  1696. if (typeof lastCancelOptions !== "undefined") {
  1697. ChivoxFire.Fail(lastCancelOptions, _err32);
  1698. } else {
  1699. console.error("[ChivoxAiEngine] _recorderOnError: _lastCancelOptions undefined");
  1700. }
  1701. return;
  1702. }
  1703. };
  1704. }
  1705. }, {
  1706. key: "_recorderOnFrame",
  1707. value: function _recorderOnFrame() {
  1708. var that = this;
  1709. return function (res) {
  1710. console.log("[ChivoxAiEngine] _recorderOnFrame(), at status: " + that._status);
  1711. ChivoxFire.OnRecorderFrame(that, res);
  1712. if ((typeof res === "undefined" ? "undefined" : _typeof(res)) !== "object") {
  1713. console.warn("[ChivoxAiEngine] _recorderOnFrame: res not object");
  1714. return;
  1715. }
  1716. if (null == res.frameBuffer) {
  1717. console.warn("[ChivoxAiEngine] _recorderOnFrame: res.frameBuffer is null");
  1718. return;
  1719. }
  1720. if (res.frameBuffer.byteLength <= 0) {
  1721. console.warn("[ChivoxAiEngine] _recorderOnFrame: res.frameBuffer is empty");
  1722. return;
  1723. }
  1724. console.debug("[ChivoxAiEngine] isLastFrame: " + res.isLastFrame + ", frameSize: ====== " + res.frameBuffer.byteLength);
  1725. if (typeof that._allAudioFrames !== "undefined") {
  1726. that._allAudioFrames.push(res.frameBuffer);
  1727. }
  1728. if (that._status != ChivoxAiEngineStatus.Recording && that._status != ChivoxAiEngineStatus.Paused && that._status != ChivoxAiEngineStatus.Stoping && that._status != ChivoxAiEngineStatus.Canceling) {
  1729. console.error("[ChivoxAiEngine] _recorderOnFrame: status error, status = " + that._status);
  1730. return;
  1731. }
  1732. if (typeof that._msgQueue !== "undefined") {
  1733. that._msgQueue.push({
  1734. cmd: 'feed', data: res.frameBuffer
  1735. });
  1736. that.__msgIterate();
  1737. }
  1738. };
  1739. }
  1740. /**
  1741. * 消息队列迭代
  1742. */
  1743. }, {
  1744. key: "__msgIterate",
  1745. value: function __msgIterate() {
  1746. var that = this;
  1747. console.debug("[ChivoxAiEngine] __msgIterate()");
  1748. if (that._status == ChivoxAiEngineStatus.Canceling) {
  1749. console.debug("[ChivoxAiEngine] __msgIterate: end for Canceling");
  1750. return;
  1751. }
  1752. // 若消息队列已清空,停止迭代
  1753. if (typeof that._msgQueue === "undefined") {
  1754. console.debug("[ChivoxAiEngine] __msgIterate: end for _msgQueue undefined");
  1755. return;
  1756. }
  1757. if (that._msgQueue.length === 0) {
  1758. console.debug("[ChivoxAiEngine] __msgIterate: end for _msgQueue empty");
  1759. return;
  1760. }
  1761. // 若wsEngine未开始,停止迭代
  1762. if (!that._wsEngine.isStarted()) {
  1763. return;
  1764. }
  1765. // TODO: 增加判断 是否已经回调过errorresult 或 eof=1 的 result
  1766. // 取出一个消息
  1767. var msg = that._msgQueue[0];
  1768. that._msgQueue.splice(0, 1);
  1769. if (msg.cmd == "feed") {
  1770. that._wsEngine.feed({
  1771. data: msg.data,
  1772. fail: function fail(res) {
  1773. console.warn("[ChivoxAiEngine] feed fail! " + JSON.stringify(res));
  1774. that._wsEngine.reset();
  1775. ChivoxFire.OnErrorResult(that, res);
  1776. }, success: function success() {}, complete: function complete() {
  1777. setTimeout(function () {
  1778. that.__msgIterate();
  1779. }, 10); // 进行下一次迭代
  1780. }
  1781. });
  1782. return;
  1783. } else if (msg.cmd == "stop") {
  1784. that._wsEngine.stop({
  1785. //timeout: 60000,
  1786. timeout: that._serverTimeout,
  1787. fail: function fail(res) {
  1788. console.warn("[ChivoxAiEngine] stop fail! " + JSON.stringify(res));
  1789. that._wsEngine.reset();
  1790. ChivoxFire.OnErrorResult(that, res);
  1791. }, success: function success() {}, complete: function complete() {
  1792. setTimeout(function () {
  1793. that.__msgIterate();
  1794. }, 10); // 进行下一次迭代
  1795. }
  1796. });
  1797. return;
  1798. } else {
  1799. console.error("[ChivoxAiEngine] __msgIterate: invalid msg.cmd = " + msg.cmd);
  1800. }
  1801. }
  1802. }]);
  1803. return ChivoxAiEngine;
  1804. }();
  1805. var aiengine = new ChivoxAiEngine();
  1806. module.exports = aiengine;