reading.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  1. import httpRequestApi from '../../utils/APIClient';
  2. import {
  3. formatDate
  4. } from '../../utils/util';
  5. Page({
  6. data: {
  7. title: '',
  8. id: '',
  9. img: '',
  10. fullScreenBtn: false,
  11. playBtn: true,
  12. gesture: true,
  13. muted: false,
  14. gesture: false,
  15. centerBtn: true,
  16. recordFlag: 0,
  17. recordSource: '',
  18. videoCtr: 'recordingVideoEnd',
  19. btnFlag: false,
  20. btnImgFlag: false,
  21. microphonePng: '../../static/index/microphone.png',
  22. recordingGif: '../../static/index/readingNow.gif',
  23. videoUrl: '',
  24. readingText: '',
  25. videoList: [],
  26. pageNo: 1,
  27. totalSize: 0,
  28. nextMargin: getApp().globalData.nextMargin,
  29. lowerThresHold: 100,
  30. isVideoListShow: true,
  31. overall: '', // 评测总分
  32. integrity: '', //完成度
  33. tone: '', //语调声调
  34. fluency: '', //流利度
  35. accuracy: '', // 正确分,发音分
  36. star: [0, 0, 0, 0, 0],
  37. ifTextShow: true,
  38. ifScoreDialogShow: false,
  39. ifScoreShow: false,
  40. statusbarobj: {
  41. isshowbtn: false, //是否显示按钮
  42. title: "小学语文朗读配音", //标题
  43. },
  44. },
  45. onLoad: function (option) {
  46. console.log(option);
  47. this.videoCtx = null;
  48. const uid = wx.getStorageSync('uid')
  49. this.getClassInfo(option.id);
  50. // this.getMicAuth()
  51. },
  52. getClassInfo: function (id) {
  53. httpRequestApi.getClassDetail(id).success(res => {
  54. console.log('课程信息', res)
  55. let reg = /\\n/g
  56. this.setData({
  57. title: res.data.data.userRead.title,
  58. videoUrl: res.data.data.userRead.videoPath,
  59. originVideo: res.data.data.userRead.originVideo,
  60. img: res.data.data.userRead.iconImg,
  61. id: res.data.data.userRead.id,
  62. readingText: res.data.data.userRead.lessonText,
  63. grade: res.data.data.userRead.grade,
  64. exampleId: res.data.data.userRead.exampleId,
  65. summary: res.data.data.userRead.summary,
  66. coverImg: res.data.data.userRead.coverImg,
  67. })
  68. this.getReadInfo(id)
  69. httpRequestApi.userIntoPage('pages/reading/reading', '朗读页面').success((res) => {
  70. })
  71. })
  72. },
  73. onHide: function () {
  74. console.log('onhide')
  75. if (this.data.audioPlaying) {
  76. console.log('返回时状态', this.data.audioPlaying)
  77. this.ss.stopPlay();
  78. }
  79. if (this.data.btnImgFlag) {
  80. this.ss.stopRecord();
  81. }
  82. this.ss.destroyEngine();
  83. this.setData({
  84. recordFlag: 0
  85. })
  86. },
  87. onUnload: function () {
  88. console.log('onUnload')
  89. if (this.data.audioPlaying) {
  90. console.log('销毁时状态', this.data.audioPlaying)
  91. this.ss.stopPlay();
  92. }
  93. if (this.data.btnImgFlag) {
  94. this.ss.stopRecord();
  95. }
  96. this.ss.destroyEngine();
  97. },
  98. onShow: function () {
  99. this.videoCtx = wx.createVideoContext('myVideo', this);
  100. let data = requirePlugin("myPlugin");
  101. const obj = {
  102. appid: 'a415',
  103. userid: wx.getStorageSync('uid'),
  104. getEvalMessage: (res) => {
  105. this.getRecordScore(res)
  106. // console.log('评测结果',res)
  107. },
  108. recorderCallback: (type, data) => {
  109. // 录音测评监控回调
  110. this.ssRecorderCallback(type, data)
  111. }
  112. }
  113. this.ss = new data.ssEngine(obj);
  114. },
  115. ssRecorderCallback: function (type, data) {
  116. console.log('录音测评监控回调', type)
  117. console.log('录音测评监控回调', data)
  118. /* 录音开始 */
  119. if (type === 'onStart') {
  120. this.setData({
  121. btnImgFlag: true,
  122. btnFlag: false
  123. })
  124. console.log('recorder start')
  125. }
  126. if (type === 'onStop') {
  127. this.videoCtx.stop();
  128. this.setData({
  129. recordFlag: 0,
  130. recordSource: data.tempFilePath,
  131. btnFlag: true,
  132. btnImgFlag: false
  133. })
  134. console.log('recorder start')
  135. }
  136. },
  137. // 录音中视频播放结束 (控制录音同时结束)
  138. recordingVideoEnd: function () {
  139. console.log(this.data.videoCtr)
  140. console.log('recordingVideoEnd');
  141. //
  142. if (this.data.recordFlag === 0) {
  143. // this.recordStop();
  144. this.playingVideoEnd();
  145. return;
  146. }
  147. // 录音结束
  148. if (this.data.recordFlag === 1) {
  149. this.recordStop();
  150. }
  151. },
  152. // 播放中视频播放结束 (控制录音同时结束)
  153. playingVideoEnd: function () {
  154. console.log('playingVideoEnd')
  155. this.ss.stopPlay();;
  156. },
  157. /***
  158. * recordFlag:
  159. * 0 初始状态
  160. * 1 录音中
  161. * 2 录音结束
  162. ***/
  163. audioRecord: function () {
  164. console.log('recordFlag', this.data.recordFlag)
  165. if (this.data.recordFlag === 0) {
  166. // this.recordStart();
  167. // this.saveVideo();
  168. console.log('是否有视频', this.videoCtx)
  169. if (this.videoCtx) {
  170. this.videoCtx.stop();
  171. // this.videoCtx.seek(0);
  172. }
  173. // if (this.recorderManager) {
  174. // this.recorderManager.stop();
  175. // }
  176. // if (this.innerAudioContext) {
  177. // this.innerAudioContext.stop();
  178. // }
  179. this.getMicAuth()
  180. // this.videoComplete();
  181. return;
  182. }
  183. // 录音结束后
  184. if (this.data.recordFlag === 1) {
  185. wx.showLoading({
  186. title: '作品转码中',
  187. mask: true
  188. })
  189. this.recordStop();
  190. }
  191. },
  192. // 录音开始
  193. /**
  194. * duration: 时长 最长10分钟
  195. sampleRate: 44100, 采样率
  196. numberOfChannels: 1, 录音通道
  197. encodeBitRate: 192000, 码率
  198. format: 'mp3', 格式
  199. frameSize: 50 制定帧大小
  200. */
  201. recordStart: function () {
  202. console.log('录音开始');
  203. const options = {
  204. duration: 600000,
  205. sampleRate: 44100,
  206. numberOfChannels: 1,
  207. encodeBitRate: 192000,
  208. format: 'mp3',
  209. frameSize: 50
  210. }
  211. this.ss.startRecord({
  212. coreType: 'cn.sent.score', //测评题型
  213. evalTime: 300000, //测评的录音时间,时间到自动停止测评
  214. refText: this.data.readingText, //测评文本
  215. warrantId: 'c11163aa6c834a028da4a4b30955be96', //鉴权id
  216. })
  217. },
  218. getMicAuth() {
  219. let _this = this;
  220. wx.getSetting({
  221. success(res) {
  222. if (res.authSetting['scope.record']) {
  223. // that.videoComplete();
  224. _this.videoComplete();
  225. } else {
  226. _this.getMicSetAuth();
  227. return;
  228. }
  229. }
  230. })
  231. },
  232. getMicSetAuth() {
  233. let _this = this;
  234. wx.authorize({
  235. scope: 'scope.record',
  236. success() {
  237. // 用户已经同意小程序使用录音功能,后续调用 wx.startRecord 接口不会弹窗询问
  238. _this.audioRecord();
  239. },
  240. fail() {
  241. wx.showModal({
  242. title: '录音前请打开麦克风权限',
  243. content: '',
  244. confirmText: '我知道了',
  245. showCancel: false,
  246. success(res) {
  247. // console.log('用户点击确定')
  248. wx.openSetting({
  249. success(res) {
  250. console.log('跳转到设置页', res.authSetting)
  251. // res.authSetting = {
  252. // "scope.userInfo": true,
  253. // "scope.userLocation": true
  254. // }
  255. }
  256. })
  257. }
  258. })
  259. }
  260. })
  261. },
  262. // 录音结束
  263. recordStop: function () {
  264. this.setData({
  265. muted: false
  266. })
  267. this.ss.stopRecord();
  268. console.log('录音结束')
  269. wx.hideLoading()
  270. },
  271. // 获取测评结果
  272. getRecordScore(res) {
  273. console.log('测评结果', res)
  274. const result = res.result;
  275. const overall = result.overall; // 总分
  276. const integrity = result.integrity; //完成度
  277. const tone = result.tone; // 语调声调
  278. const accuracy = result.accuracy; // 发音分
  279. const fluency = result.fluency.overall; //流利度
  280. let starArray = [];
  281. let score = overall / 20;
  282. if (score <= 0) {
  283. starArray = [0, 0, 0, 0, 0]
  284. } else {
  285. for (let i = 1; i < 5; i += 0.9) {
  286. if (i < score) {
  287. starArray.push(1);
  288. } else {
  289. starArray.push(0)
  290. }
  291. }
  292. }
  293. this.setData({
  294. overall,
  295. integrity,
  296. tone,
  297. accuracy,
  298. fluency,
  299. ifScoreDialogShow: true,
  300. star: starArray
  301. })
  302. },
  303. closeScoreDialog() {
  304. this.setData({
  305. ifScoreDialogShow: false,
  306. ifScoreShow: true,
  307. ifTextShow: false
  308. })
  309. },
  310. // 播放录音
  311. audioPlay: function () {
  312. /* 用了先声智能以后录音播放由先声只能接管 */
  313. this.setData({
  314. videoUrl: this.data.videoUrl
  315. })
  316. if (this.data.audioPath) {
  317. if (this.data.audioPlaying) {
  318. this.ss.stopPlay();
  319. }
  320. this.ss.startPlay(this.data.audioPath);
  321. this.videoCtx.stop();
  322. this.videoCtx.play();
  323. } else {
  324. const recordSource = this.data.recordSource
  325. wx.uploadFile({
  326. url: 'https://reader-api.ai160.com/file/upload',
  327. filePath: recordSource,
  328. name: '朗读录音',
  329. header: {
  330. uid: wx.getStorageSync('uid')
  331. },
  332. success: (res) => {
  333. const formateRes = JSON.parse(res.data);
  334. let audioPath = formateRes.data;
  335. this.setData({
  336. audioPath,
  337. audioPlaying: true
  338. })
  339. this.ss.startPlay(audioPath);
  340. // this.videoCtx.seek(0);
  341. this.videoCtx.stop();
  342. console.log('播放器归0')
  343. this.videoCtx.play();
  344. console.log('播放器播放')
  345. }
  346. })
  347. }
  348. },
  349. videoComplete: function () {
  350. // let videoUrl = 'http://efunimgs.ai160.com/ott/test/002tPr2Xlx07oP7B4ro40104120022hP0k010.mp4';
  351. this.setData({
  352. recordFlag: 1,
  353. videoUrl: this.data.originVideo,
  354. centerBtn: false,
  355. playBtn: false,
  356. isVideoListShow: false,
  357. muted: true,
  358. ifTextShow: true,
  359. ifScoreShow: false
  360. }, () => {
  361. this.videoCtx.play();
  362. this.recordStart();
  363. })
  364. },
  365. // 上传
  366. upload: function () {
  367. if (this.videoCtx) {
  368. this.videoCtx.stop();
  369. }
  370. if (this.data.audioPlaying) {
  371. this.ss.stopPlay();
  372. this.setData({
  373. audioPlaying: false
  374. })
  375. }
  376. wx.showLoading({
  377. title: '作品上传中',
  378. mask: true
  379. })
  380. if (this.data.audioPath) {
  381. this.shareWorks(this.data.audioPath)
  382. } else {
  383. const recordSource = this.data.recordSource;
  384. wx.uploadFile({
  385. url: 'https://reader-api.ai160.com/file/upload',
  386. filePath: recordSource,
  387. name: '朗读录音',
  388. header: {
  389. uid: wx.getStorageSync('uid')
  390. },
  391. success: (res) => {
  392. const formateRes = JSON.parse(res.data);
  393. let audioPath = formateRes.data;
  394. this.shareWorks(audioPath);
  395. }
  396. })
  397. }
  398. },
  399. shareWorks: function (audio) {
  400. const data = {
  401. "lessonId": this.data.id,
  402. "originVideo": this.data.videoUrl,
  403. "audioPath": audio,
  404. "title": this.data.title,
  405. "iconImg": this.data.img,
  406. "summary": this.data.summary,
  407. "productId": this.data.productId,
  408. "grade": this.data.grade,
  409. "exampleId": this.data.exampleId,
  410. "coverImg": this.data.coverImg
  411. };
  412. httpRequestApi.postWork(data).success(res => {
  413. wx.hideLoading({
  414. success: () => {
  415. wx.showToast({
  416. title: '作品已上传正在审核中',
  417. icon: 'none',
  418. duration: 1000,
  419. success: () => {
  420. console.log('上传成功', res);
  421. const _data = this.data;
  422. const scoreData = {
  423. "userReadId": res.data.data.id,
  424. "complete": _data.integrity,
  425. "accuracy": _data.accuracy,
  426. "speed": _data.fluency,
  427. "intonation": _data.tone,
  428. "score": _data.overall
  429. }
  430. // 上传评分
  431. httpRequestApi.postWorksScore(scoreData).success(res => {
  432. console.log(res)
  433. });
  434. const pages = getCurrentPages();
  435. const prevPage = pages[pages.length - 2];
  436. prevPage.setData({
  437. // workId: res.data.data.id, // 有id就塞到第一位
  438. fromReading: true
  439. }, () => {
  440. wx.navigateBack({
  441. delta: 1
  442. })
  443. })
  444. }
  445. })
  446. }
  447. });
  448. }).fail(res => {
  449. wx.hideLoading({
  450. success: () => {
  451. wx.showToast({
  452. title: '上传超时',
  453. icon: 'fail',
  454. duration: 1000
  455. })
  456. }
  457. });
  458. })
  459. },
  460. // 获取本课朗读内容
  461. getReadInfo: function (id, pageNo, pageSize) {
  462. // const uid = wx.getStorageSync('uid');
  463. const data = {
  464. exampleId: this.data.id || id,
  465. pageNo: this.data.pageNo,
  466. pageSize: 3,
  467. type: 'READ'
  468. };
  469. httpRequestApi.getClassRead(data).success(res => {
  470. const readInfo = res.data.data.list;
  471. console.log(res)
  472. readInfo.forEach(item => {
  473. const temp = {};
  474. temp.title = item.userRead ? item.userRead.title : '';
  475. temp.img = item.userRead.iconImg;
  476. temp.plays = item.userRead.playAmount ? item.userRead.playAmount : 0;
  477. temp.likes = item.userRead.likeAmount ? item.userRead.likeAmount : 0;
  478. temp.classId = item.userRead.exampleId;
  479. temp.time = formatDate(item.userRead.gmtCreated, 3);
  480. temp.avatar = item.user ? item.user.avatar : '';
  481. temp.uid = item.user ? item.user.uid : '';
  482. temp.url = item.userRead.videoPath;
  483. // temp.avatar = item.user.avatar;
  484. temp.nickName = item.user ? item.user.wechatName : '';
  485. temp.id = item.userRead.id;
  486. temp.noReading = true;
  487. temp.isFans = item.isFans ? true : item.user.uid === this.uid ? true : false;
  488. temp.coverImg = item.userRead.coverImg;
  489. temp.videoShow = false;
  490. temp.grade = item.userRead.grade;
  491. temp.type = item.userRead.type;
  492. // recommendWorks.push(temp);
  493. // that.data.hotData.hotWorks.push(temp);
  494. this.data.videoList.push(temp);
  495. });
  496. this.setData({
  497. videoList: this.data.videoList,
  498. totalSize: res.data.data.totalSize
  499. })
  500. });
  501. },
  502. // 评论区点击
  503. commentTap: function (e) {
  504. console.log('点击评论区', e)
  505. if (e.target.dataset.type === 'blank') {
  506. this.setData({
  507. commentShow: false
  508. })
  509. }
  510. },
  511. scrollToLower: function (e) {
  512. console.log('滑动到底部', e)
  513. this.setData({
  514. pageNo: this.data.pageNo + 1
  515. }, () => {
  516. this.getReadInfo()
  517. })
  518. },
  519. scrollToUpper: function (e) {
  520. console.log('滑动到顶部', e)
  521. },
  522. // 打开评论
  523. openComment: function (e) {
  524. console.log('id', e.detail.activeId)
  525. this.setData({
  526. commentShow: !this.data.commentShow,
  527. commentId: e.detail.activeId,
  528. });
  529. },
  530. goToReading: function (e) {
  531. this.setData({
  532. pageNo: 1,
  533. videoList: []
  534. })
  535. const id = e.detail.activeId ? e.detail.activeId : e.currentTarget.dataset.id;
  536. this.getClassInfo(id)
  537. },
  538. onShareAppMessage: function (res) {
  539. console.log('点击分享按钮', res)
  540. console.log('点击分享按钮', this.data.shareTitle)
  541. console.log('点击分享按钮', this.data.shareId)
  542. console.log('点击分享按钮', this.data.shareImg)
  543. if (res.from === 'button') {
  544. return {
  545. title: '请欣赏我的课文朗读作品,点赞+评论。',
  546. path: `/pages/index/index?readId=${this.data.shareId}`,
  547. imageUrl: '../../static/index/share_icon.png'
  548. }
  549. } else {
  550. return {
  551. title: '课文朗读,从未如此有趣。',
  552. path: '/pages/index/index',
  553. }
  554. }
  555. },
  556. touchMove: function () {
  557. return
  558. },
  559. openShare: function (e) {
  560. console.log('用户点击分享按钮', e)
  561. this.setData({
  562. shareTitle: e.detail.currentTarget.dataset.title,
  563. shareId: e.detail.currentTarget.dataset.id,
  564. shareImg: e.detail.currentTarget.dataset.img
  565. })
  566. },
  567. onPlay: function (e) {
  568. // 下边视频列表onplay
  569. console.log('视频播放视频播放')
  570. if (this.videoCtx) {
  571. this.videoCtx.stop();
  572. } else {
  573. this.videoCtx = wx.createVideoContext('myVideo', this);
  574. this.videoCtx.stop();
  575. }
  576. },
  577. collectTap: function (e) {
  578. console.log('点击收藏', e)
  579. const index = e.detail.index;
  580. let str = `videoList[${index}].isFavorite`
  581. this.setData({
  582. [str]: e.detail.isCollect
  583. })
  584. },
  585. likeTap: function (e) {
  586. console.log('点赞', e)
  587. const index = e.detail.index;
  588. let likeStr = `videoList[${index}].isLike`;
  589. let likeNumStr = `videoList[${index}].likes`;
  590. this.setData({
  591. [likeStr]: true,
  592. [likeNumStr]: this.data.videoList[index].likes + 1
  593. })
  594. },
  595. })