Advertisement
Guest User

Untitled

a guest
Oct 14th, 2017
436
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.61 KB | None | 0 0
  1. DOM exception: failed to execute start on Media recorder: The
  2. MediaRecorder failed to start because there are no audio or video
  3. tracks available
  4.  
  5. const recorder = yield select(getRecorder)
  6. yield call(recorder.startRecording)
  7.  
  8. startRecording = () => {
  9.  
  10. try {
  11. this.captureUserMedia((stream, error) => {
  12. try {
  13.  
  14. if (error) {
  15. console.log(error)
  16. return
  17. }
  18.  
  19. this.rtcRecorder.startRecording()
  20. this.recording = true
  21. } catch (err) {
  22. sendEmail(err, "inner startRecording failed", "support@gmail.com")
  23. console.log("inner startRecording ERROR: ", err)
  24. }
  25. });
  26. } catch (err) {
  27. sendEmail(err, "startRecording failed", "support@gmail.com")
  28. console.log("startRecording ERROR: ", err)
  29. }
  30.  
  31. }
  32.  
  33. captureUserMedia(callback) {
  34. var params = { audio: true, video: false };
  35.  
  36. navigator.getUserMedia(params, callback, (error) => {
  37. // alert(JSON.stringify(error));
  38. console.log('USER MEDIA ERROR:: ' + JSON.stringify(error))
  39. callback(null, error)
  40. });
  41. };
  42.  
  43. this.rtcRecorder.startRecording()
  44.  
  45. var hiddenAudio = document.createElement('audio');
  46. hiddenAudio.srcObject = stream // this line is required to make sure stream tracks aren't stopped/released
  47. hiddenAudio.muted = true
  48. hiddenAudio.play()
  49.  
  50. initialize = (callback) => {
  51.  
  52. if (!!this.rtcRecorder) {
  53. console.log('Attempted to initialize an already initialized recorder but that's expected')
  54. return
  55. }
  56.  
  57. console.log('initialize Recorder -- requestUserMedia')
  58. this.captureUserMedia((stream, error) => {
  59.  
  60. if (error) {
  61. console.log('!!errror capturing user media!!')
  62. return callback && callback(error)
  63. }
  64.  
  65. // TODO: detect if system can play webms
  66.  
  67. // <-- smaller filesize
  68. // this.rtcRecorder = RecordRTC(stream, { recorderType: RecordRTC.StereoAudioRecorder, bitsPerSecond: 30000, numberOfAudioChannels: 1, mimeType: 'audio/wav' });
  69.  
  70. try {
  71.  
  72. // the MUAZ KHAN edits
  73. var hiddenAudio = document.createElement('audio');
  74. hiddenAudio.srcObject = stream // this line is required to make sure stream tracks aren't stopped/released
  75. hiddenAudio.muted = true
  76. hiddenAudio.play()
  77.  
  78.  
  79. this.rtcRecorder = RecordRTC(stream, { audio: 'true', mimeType: 'audio/webm', checkForInactiveTracks: 'true' });
  80. callback && callback(null)
  81. return true
  82. } catch (err) {
  83. sendEmail(err, "captureMedia (inner-most) startRecording failed", "support@gmail.com")
  84. console.log("captureMedia (inner-most) startRecording ERROR: ", err)
  85. callback && callback(null)
  86. return true
  87. }
  88.  
  89.  
  90. });
  91. };
  92.  
  93. function* rootSaga() {
  94. const { payload: { isDemo } } = yield take(IS_DEMO_SET)
  95. const { payload: { bookKey } } = yield take(BOOK_KEY_SET)
  96.  
  97. yield clog("isDemo: ", isDemo)
  98.  
  99. yield clog("bookKey: ", bookKey)
  100.  
  101. yield clog('Root Saga Started')
  102.  
  103.  
  104. const newBookKey = isDemo ? 'demo' : 'unclear'
  105. yield clog('Generating assessment... newBookKey:', newBookKey)
  106. const assessmentId = yield requestNewAssessment(newBookKey)
  107. .catch(e => e.request) // TODO
  108.  
  109. yield clog('Assessment ID:', assessmentId)
  110.  
  111.  
  112.  
  113. // if isMobileDevice, halt
  114. const isMobile = yield call(isMobileDevice)
  115. if (isMobile) {
  116. window.location.href = '/mobile_halt'
  117. take('ickkk')
  118. }
  119.  
  120.  
  121. // CREATE THE USER
  122.  
  123. $.ajax({
  124. url: ('/auth/phil_setup_demo?book_key=' + bookKey),
  125. type: 'post',
  126. }).fail(function(xhr, status, err) {
  127. console.log(err)
  128. })
  129.  
  130. /*
  131. ****************
  132. * watchers
  133. *****************
  134. */
  135. // yield* audioEffectsSaga()
  136.  
  137. yield takeLatest(HEAR_RECORDING_CLICKED, function* () {
  138. yield put(setCurrentModal('modal-playback'))
  139. yield call(stopAudio)
  140. })
  141.  
  142.  
  143. // yield takeLatest(PERMISSIONS_ARROW_CLICKED, function* () {
  144. // yield call(playSound, '/audio/click_allow_button.mp3')
  145. // })
  146.  
  147.  
  148.  
  149. /*
  150. ****************
  151. * main race
  152. *****************
  153. */
  154. yield clog('Race About To Start')
  155. while (true) {
  156. const {
  157. restartAssessment,
  158. recordingBlobArray,
  159. quit,
  160. } = yield race({
  161. restartAssessment: take(RESTART_RECORDING_CLICKED),
  162. recordingBlobArray: call(assessThenSubmitSaga, assessmentId),
  163. quit: take('QUIT_ASSESSMENT_AND_DESTROY'),
  164. })
  165.  
  166. function* assessThenSubmitSaga(assessmentId) {
  167.  
  168. const effects = []
  169.  
  170.  
  171. // TODO: convert this into a batched action
  172. yield put.resolve(setPageNumber(0))
  173. yield put.resolve(setQuestionNumber(1))
  174. yield put.resolve(setPrompt(
  175. PromptOptions.awaitingPrompt,
  176. ))
  177.  
  178. yield put.resolve(setInComp(false))
  179. yield put.resolve(setHasRecordedSomething(false))
  180. yield put.resolve(setCurrentModal('no-modal'))
  181.  
  182. yield put(setCurrentOverlay('no-overlay'))
  183.  
  184. const permissionsGranted = yield* getMicPermissionsSaga() // blocks
  185.  
  186. // TODO asap as possible
  187. // TODO: some loop here :)
  188. while (!permissionsGranted) {
  189. yield put(setCurrentOverlay('overlay-blocked-mic'))
  190. yield take('ickkkkk')
  191. return
  192. }
  193.  
  194. yield put(setCurrentOverlay('no-overlay'))
  195.  
  196.  
  197. // permission was granted!!!!
  198.  
  199.  
  200.  
  201. let recorder = yield select(getRecorder)
  202. yield call(recorder.initialize)
  203.  
  204. yield put.resolve(setReaderState(
  205. ReaderStateOptions.awaitingStart,
  206. ))
  207.  
  208. effects.push(
  209. yield fork(hideVolumeSaga),
  210. )
  211.  
  212. // before assessment has started, clicking exit immediately quits app
  213. // I guess. We will probably change this
  214. const { exit } = yield race({
  215. exit: take(EXIT_CLICKED),
  216. startAssessment: take(START_RECORDING_CLICKED),
  217. })
  218.  
  219.  
  220. // const { exit, fake } = yield all([
  221. // race({
  222. // exit: take(EXIT_CLICKED),
  223. // startAssessment: take(START_RECORDING_CLICKED),
  224. // })
  225. // ])
  226.  
  227.  
  228. yield call(stopAudio)
  229.  
  230. // the app will end :O
  231. if (exit) {
  232. yield* redirectToHomepage()
  233. }
  234.  
  235.  
  236. // now we start the assessment for real
  237. effects.push(
  238. yield takeLatest(EXIT_CLICKED, exitClick),
  239. )
  240.  
  241. yield call(sendEmail, "Demo started", "Demo was started", "philesterman@gmail.com") // move here so don't break
  242.  
  243. // TODO: convert the countdown to saga!!!!
  244. yield put.resolve(setPageNumber(1))
  245. yield put.resolve(setReaderState(
  246. ReaderStateOptions.countdownToStart,
  247. ))
  248.  
  249. yield playSoundAsync('/audio/recording_countdown.mp3')
  250.  
  251.  
  252. if (!DEV_DISABLE_VOICE_INSTRUCTIONS) {
  253.  
  254. let countdown = 3
  255. while (countdown > 0) {
  256. yield put(setCountdownValue(countdown))
  257. yield call(delay, 1000)
  258. countdown--
  259. }
  260. }
  261.  
  262.  
  263. // yield put(setCurrentSound('/audio/book_intro.mp3'))
  264.  
  265. yield put.resolve(setCurrentModal('no-modal'))
  266.  
  267.  
  268.  
  269.  
  270. yield put.resolve(setReaderState(
  271. ReaderStateOptions.inProgress,
  272. ))
  273.  
  274.  
  275. // this ensures that effects are canceleld
  276. // while (true) {
  277. // const {exit} = yield race({
  278. // exit: take(EXIT_CLICKED),
  279. // assessmentResult: call(assessmentSaga),
  280. // })
  281.  
  282. // if (exit) {
  283. // yield call(exitClick)
  284. // } else {
  285.  
  286. // }
  287. // }
  288. // starts the recording assessment flow
  289. effects.push(
  290. yield fork(assessmentSaga),
  291. )
  292.  
  293. export default function* assessmentSaga() {
  294.  
  295. yield call(console.log, "here in assessmentSaga")
  296. // watchers!
  297. // TODO: refactor this into saga for referential integrity of recorder
  298. yield takeLatest(PAUSE_CLICKED, pauseAssessmentSaga)
  299.  
  300. yield takeLatest(COMP_PAUSE_CLICKED, compPauseAssessmentSaga)
  301.  
  302. yield takeLatest(RESUME_CLICKED, resumeAssessmentSaga)
  303.  
  304. yield takeLatest(NEXT_PAGE_CLICKED, pageIncrementSaga)
  305.  
  306. yield takeLatest(PREVIOUS_PAGE_CLICKED, pageDecrementSaga)
  307. // start recording the assessment audio
  308. const recorder = yield select(getRecorder)
  309.  
  310. try {
  311. yield call(recorder.startRecording)
  312. yield put.resolve(setHasRecordedSomething(true))
  313. } catch (err) {
  314. yield clog("ERROR: ", err)
  315. yield call(sendEmail, err, "Recorder failed to start", "support@gmail.com") // move here so don't break
  316. }
  317.  
  318. return { some: 'sick results' }
  319. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement