index.js 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. // pages/index/component/AudioPanel/index.js
  2. const RECORD_CONFIG = {
  3. duration: 120000,
  4. sampleRate: 44100,
  5. numberOfChannels: 1,
  6. encodeBitRate: 128000,
  7. format: 'mp3',
  8. }
  9. const app = getApp()
  10. const API = app.globalData.api
  11. Component({
  12. /**
  13. * 组件的属性列表
  14. */
  15. properties: {
  16. paper: {
  17. type: Object
  18. }
  19. },
  20. /**
  21. * 组件的初始数据
  22. */
  23. data: {
  24. audio: '',
  25. isRecord: false,
  26. recordTime: 0,
  27. duration: '00:00'
  28. },
  29. lockRecord: false,
  30. recordHandler: 0,
  31. recordManager: null,
  32. /**
  33. * 组件的方法列表
  34. */
  35. methods: {
  36. audioAction: function (e) {
  37. if (this.lockRecord) {
  38. return false
  39. }
  40. if (!this.data.paper || !this.data.paper.courseId > 0) {
  41. wx.showToast({
  42. title: '请重新扫描题目二维码',
  43. icon: 'none'
  44. })
  45. return false
  46. }
  47. this.lockRecord = true
  48. this.triggerEvent('enableScan', { enabled: false })
  49. this.startRecord()
  50. },
  51. uploadSuccess(accessUrl) {
  52. const that = this
  53. //文件上传成功后通知服务端
  54. API.notifyServer(that.data.paper.examRecordDataId, that.data.paper.examStudentId, that.data.paper.questionOrder, accessUrl, 'AUDIO').then(res => {
  55. // 轮询答案处理结果
  56. const _startTime = new Date().getTime()
  57. var times = 10
  58. const handler = setInterval(function () {
  59. API.getNotifyResult(res)
  60. .then(res => {
  61. console.log(res)
  62. if (res == 'CONFIRMED') {
  63. clearInterval(handler)
  64. wx.hideLoading()
  65. wx.showToast({
  66. title: '上传成功,继续扫描下一题',
  67. icon: 'none',
  68. duration: 2500
  69. })
  70. wx.reLaunch({
  71. url: '/pages/index/index'
  72. })
  73. } else {
  74. throw '答案未同步'
  75. }
  76. }).catch(exceptions => {
  77. times--
  78. if (new Date().getTime() - _startTime >= 1000 * 10 || times < 0) {
  79. clearInterval(handler)
  80. wx.hideLoading()
  81. wx.showToast({
  82. title: '上传失败,请重新上传',
  83. icon: 'none'
  84. })
  85. }
  86. })
  87. }, 1000)
  88. }).catch(exceptions => {
  89. console.log('catch', exceptions)
  90. that.uploadFail(exceptions)
  91. })
  92. },
  93. uploadFail(exceptions) {
  94. var error = '上传失败,请重新上传'
  95. try {
  96. if (exceptions.statusCode == 500) {
  97. error = exceptions.data.desc
  98. }
  99. } catch (e) {
  100. }
  101. wx.hideLoading()
  102. wx.showToast({
  103. title: error,
  104. icon: 'none'
  105. })
  106. },
  107. uploadAudio(e) {
  108. // 正在录音 禁止操作
  109. if (this.data.isRecord) {
  110. return
  111. }
  112. const filepath = this.data.audio
  113. const that = this
  114. wx.showLoading({
  115. title: '正在上传录音',
  116. mask: true
  117. })
  118. const duration = filepath
  119. wx.getFileInfo({
  120. filePath: filepath,
  121. success: function (fileRes) {
  122. console.log(fileRes)
  123. var accessUrl = ''
  124. // 获取上传签名
  125. API.getSign(that.data.paper.examRecordDataId, that.data.paper.examStudentId,
  126. that.data.paper.questionOrder, fileRes.digest, 'mp3')
  127. .then(signRes => {
  128. console.log(signRes)
  129. // 上传文件
  130. const c_md5 = wx.arrayBufferToBase64(new Uint8Array(fileRes.digest.match(/[\da-f]{2}/gi).map(function (h) {
  131. return parseInt(h, 16)
  132. })))
  133. console.log('uploadFile::start upload')
  134. const task = wx.uploadFile({
  135. url: signRes.formUrl,
  136. filePath: filepath,
  137. name: 'file',
  138. formData: signRes.formParams,
  139. success: taskRes => {
  140. console.log('uploadFile::upload success', taskRes)
  141. that.uploadSuccess(signRes.accessUrl)
  142. },
  143. fail: error => {
  144. console.log('uploadFile:uploadFile:catch', exceptions)
  145. that.uploadFail(exceptions)
  146. }
  147. })
  148. task.onHeadersReceived(res => {
  149. console.log('task header::', res, res.header['Content-MD5'], c_md5)
  150. if (c_md5 != res.header['Content-MD5']) {
  151. that.uploadFail('文件破损,请重新上传')
  152. }
  153. })
  154. }).catch(exceptions => {
  155. console.log('catch', exceptions)
  156. that.uploadFail(exceptions)
  157. })
  158. }
  159. })
  160. },
  161. startRecord: function () {
  162. const that = this
  163. if (!this.data.isRecord) {
  164. if (this.data.audio) {
  165. wx.showModal({
  166. title: '提示',
  167. content: '已存在未上传的录音,是否开始重新录音',
  168. confirmText: '开始录音',
  169. success(res) {
  170. if (res.confirm) {
  171. that.recordManager.start(RECORD_CONFIG)
  172. } else {
  173. that.lockRecord = false
  174. }
  175. }
  176. })
  177. } else {
  178. wx.showLoading({
  179. title: '',
  180. mask: true
  181. })
  182. that.recordManager.start(RECORD_CONFIG)
  183. }
  184. } else {
  185. that.recordManager.stop()
  186. }
  187. },
  188. onRecordStart() {
  189. this.lockRecord = false
  190. console.log("record start")
  191. const that = this
  192. this.setData({
  193. audio: '',
  194. isRecord: true
  195. })
  196. this.recordHandler = setInterval(function () {
  197. var recordTime = that.data.recordTime + 0.1
  198. var second = parseInt(recordTime)
  199. var msc = parseInt((recordTime - second) * 10) * 10
  200. var duration = (second > 9 ? second : ('0' + second)) + ":" + (msc > 0 ? msc : "00")
  201. that.setData({
  202. isRecord: true,
  203. recordTime: recordTime,
  204. duration: duration
  205. })
  206. }, 100)
  207. },
  208. onRecordStop(audioPath) {
  209. this.triggerEvent('enableScan', {enabled: true})
  210. this.lockRecord = false
  211. console.log("record stop", audioPath)
  212. clearInterval(this.recordHandler)
  213. this.recordHandler = 0
  214. this.setData({
  215. audio: audioPath,
  216. recordTime: 0,
  217. duration: "00:00",
  218. isRecord: false,
  219. })
  220. },
  221. },
  222. attached() {
  223. const that = this
  224. this.recordManager = wx.getRecorderManager()
  225. this.recordManager.onError(function (res) {
  226. console.log(res)
  227. that.lockRecord = false
  228. wx.showToast({
  229. title: '录音出错',
  230. icon: 'none'
  231. })
  232. })
  233. this.recordManager.onStart(function () {
  234. //保持屏幕常亮
  235. wx.setKeepScreenOn({ keepScreenOn: true })
  236. wx.hideLoading()
  237. that.onRecordStart()
  238. })
  239. this.recordManager.onStop(function (res) {
  240. wx.setKeepScreenOn({ keepScreenOn: false })
  241. wx.hideLoading()
  242. that.onRecordStop(res.tempFilePath)
  243. })
  244. this.recordManager.onInterruptionBegin(function () {
  245. wx.hideLoading()
  246. console.log("onInterruptionBegin")
  247. that.lockRecord = false
  248. that.recordManager.stop()
  249. })
  250. this.recordManager.onInterruptionEnd(function () {
  251. wx.hideLoading()
  252. that.lockRecord = false
  253. console.log("onInterruptionEnd")
  254. })
  255. wx.onAppHide(() => {
  256. if (that.data.isRecord) {
  257. wx.hideLoading()
  258. that.recordManager.stop()
  259. that.lockRecord = false
  260. }
  261. })
  262. },
  263. detached() {
  264. const that = this
  265. wx.offAppHide(() => {
  266. if (that.data.isRecord) {
  267. that.recordManager.stop()
  268. }
  269. })
  270. }
  271. })