reading.js 20 KB

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