@@ 37-173 (lines=137) @@ | ||
34 | /** global: M */ |
|
35 | /** global: Y */ |
|
36 | ||
37 | M.atto_recordrtc = M.atto_recordrtc || {}; |
|
38 | ||
39 | // Shorten access to M.atto_recordrtc.commonmodule namespace. |
|
40 | var cm = M.atto_recordrtc.commonmodule; |
|
41 | ||
42 | M.atto_recordrtc.videomodule = { |
|
43 | init: function(scope) { |
|
44 | // Assignment of global variables. |
|
45 | cm.editorScope = scope; // Allows access to the editor's "this" context. |
|
46 | cm.alertWarning = Y.one('div#alert-warning'); |
|
47 | cm.alertDanger = Y.one('div#alert-danger'); |
|
48 | cm.player = Y.one('video#player'); |
|
49 | cm.playerDOM = document.querySelector('video#player'); |
|
50 | cm.startStopBtn = Y.one('button#start-stop'); |
|
51 | cm.uploadBtn = Y.one('button#upload'); |
|
52 | cm.recType = 'video'; |
|
53 | cm.olderMoodle = scope.get('oldermoodle'); |
|
54 | // Extract the numbers from the string, and convert to bytes. |
|
55 | cm.maxUploadSize = window.parseInt(scope.get('maxrecsize').match(/\d+/)[0], 10) * Math.pow(1024, 2); |
|
56 | ||
57 | // Show alert and close plugin if WebRTC is not supported. |
|
58 | cm.check_has_gum(); |
|
59 | // Show alert and redirect user if connection is not secure. |
|
60 | cm.check_secure(); |
|
61 | // Show alert if using non-ideal browser. |
|
62 | cm.check_browser(); |
|
63 | ||
64 | // Run when user clicks on "record" button. |
|
65 | cm.startStopBtn.on('click', function() { |
|
66 | cm.startStopBtn.set('disabled', true); |
|
67 | ||
68 | // If button is displaying "Start Recording" or "Record Again". |
|
69 | if ((cm.startStopBtn.get('textContent') === M.util.get_string('startrecording', 'atto_recordrtc')) || |
|
70 | (cm.startStopBtn.get('textContent') === M.util.get_string('recordagain', 'atto_recordrtc')) || |
|
71 | (cm.startStopBtn.get('textContent') === M.util.get_string('recordingfailed', 'atto_recordrtc'))) { |
|
72 | // Make sure the upload button is not shown. |
|
73 | cm.uploadBtn.ancestor().ancestor().addClass('hide'); |
|
74 | ||
75 | // Change look of recording button. |
|
76 | if (!cm.olderMoodle) { |
|
77 | cm.startStopBtn.replaceClass('btn-outline-danger', 'btn-danger'); |
|
78 | } |
|
79 | ||
80 | // Empty the array containing the previously recorded chunks. |
|
81 | cm.chunks = []; |
|
82 | cm.blobSize = 0; |
|
83 | ||
84 | // Initialize common configurations. |
|
85 | var commonConfig = { |
|
86 | // When the stream is captured from the microphone/webcam. |
|
87 | onMediaCaptured: function(stream) { |
|
88 | // Make video stream available at a higher level by making it a property of the common module. |
|
89 | cm.stream = stream; |
|
90 | ||
91 | cm.start_recording(cm.recType, cm.stream); |
|
92 | }, |
|
93 | ||
94 | // Revert button to "Record Again" when recording is stopped. |
|
95 | onMediaStopped: function(btnLabel) { |
|
96 | cm.startStopBtn.set('textContent', btnLabel); |
|
97 | cm.startStopBtn.set('disabled', false); |
|
98 | if (!cm.olderMoodle) { |
|
99 | cm.startStopBtn.replaceClass('btn-danger', 'btn-outline-danger'); |
|
100 | } |
|
101 | }, |
|
102 | ||
103 | // Handle recording errors. |
|
104 | onMediaCapturingFailed: function(error) { |
|
105 | cm.handle_gum_errors(error, commonConfig); |
|
106 | } |
|
107 | }; |
|
108 | ||
109 | // Show video tag without controls to view webcam stream. |
|
110 | cm.player.ancestor().ancestor().removeClass('hide'); |
|
111 | cm.player.set('controls', false); |
|
112 | ||
113 | // Capture audio+video stream from webcam/microphone. |
|
114 | M.atto_recordrtc.videomodule.captureAudioVideo(commonConfig); |
|
115 | } else { // If button is displaying "Stop Recording". |
|
116 | // First of all clears the countdownTicker. |
|
117 | window.clearInterval(cm.countdownTicker); |
|
118 | ||
119 | // Disable "Record Again" button for 1s to allow background processing (closing streams). |
|
120 | window.setTimeout(function() { |
|
121 | cm.startStopBtn.set('disabled', false); |
|
122 | }, 1000); |
|
123 | ||
124 | // Stop recording. |
|
125 | M.atto_recordrtc.videomodule.stopRecording(cm.stream); |
|
126 | ||
127 | // Change button to offer to record again. |
|
128 | cm.startStopBtn.set('textContent', M.util.get_string('recordagain', 'atto_recordrtc')); |
|
129 | if (!cm.olderMoodle) { |
|
130 | cm.startStopBtn.replaceClass('btn-danger', 'btn-outline-danger'); |
|
131 | } |
|
132 | } |
|
133 | }); |
|
134 | }, |
|
135 | ||
136 | // Setup to get audio+video stream from microphone/webcam. |
|
137 | captureAudioVideo: function(config) { |
|
138 | cm.capture_user_media( |
|
139 | // Media constraints. |
|
140 | { |
|
141 | audio: true, |
|
142 | video: { |
|
143 | width: {ideal: 640}, |
|
144 | height: {ideal: 480} |
|
145 | } |
|
146 | }, |
|
147 | ||
148 | // Success callback. |
|
149 | function(audioVideoStream) { |
|
150 | // Set video player source to microphone+webcam stream, and play it back as it's recording. |
|
151 | cm.playerDOM.srcObject = audioVideoStream; |
|
152 | cm.playerDOM.play(); |
|
153 | ||
154 | config.onMediaCaptured(audioVideoStream); |
|
155 | }, |
|
156 | ||
157 | // Error callback. |
|
158 | function(error) { |
|
159 | config.onMediaCapturingFailed(error); |
|
160 | } |
|
161 | ); |
|
162 | }, |
|
163 | ||
164 | stopRecording: function(stream) { |
|
165 | // Stop recording microphone stream. |
|
166 | cm.mediaRecorder.stop(); |
|
167 | ||
168 | // Stop each individual MediaTrack. |
|
169 | stream.getTracks().forEach(function(track) { |
|
170 | track.stop(); |
|
171 | }); |
|
172 | } |
|
173 | }; |
|
174 |
@@ 37-165 (lines=129) @@ | ||
34 | /** global: M */ |
|
35 | /** global: Y */ |
|
36 | ||
37 | M.atto_recordrtc = M.atto_recordrtc || {}; |
|
38 | ||
39 | // Shorten access to M.atto_recordrtc.commonmodule namespace. |
|
40 | var cm = M.atto_recordrtc.commonmodule; |
|
41 | ||
42 | M.atto_recordrtc.audiomodule = { |
|
43 | init: function(scope) { |
|
44 | // Assignment of global variables. |
|
45 | cm.editorScope = scope; // Allows access to the editor's "this" context. |
|
46 | cm.alertWarning = Y.one('div#alert-warning'); |
|
47 | cm.alertDanger = Y.one('div#alert-danger'); |
|
48 | cm.player = Y.one('audio#player'); |
|
49 | cm.playerDOM = document.querySelector('audio#player'); |
|
50 | cm.startStopBtn = Y.one('button#start-stop'); |
|
51 | cm.uploadBtn = Y.one('button#upload'); |
|
52 | cm.recType = 'audio'; |
|
53 | cm.olderMoodle = scope.get('oldermoodle'); |
|
54 | // Extract the numbers from the string, and convert to bytes. |
|
55 | cm.maxUploadSize = window.parseInt(scope.get('maxrecsize').match(/\d+/)[0], 10) * Math.pow(1024, 2); |
|
56 | ||
57 | // Show alert and close plugin if WebRTC is not supported. |
|
58 | cm.check_has_gum(); |
|
59 | // Show alert and redirect user if connection is not secure. |
|
60 | cm.check_secure(); |
|
61 | // Show alert if using non-ideal browser. |
|
62 | cm.check_browser(); |
|
63 | ||
64 | // Run when user clicks on "record" button. |
|
65 | cm.startStopBtn.on('click', function() { |
|
66 | cm.startStopBtn.set('disabled', true); |
|
67 | ||
68 | // If button is displaying "Start Recording" or "Record Again". |
|
69 | if ((cm.startStopBtn.get('textContent') === M.util.get_string('startrecording', 'atto_recordrtc')) || |
|
70 | (cm.startStopBtn.get('textContent') === M.util.get_string('recordagain', 'atto_recordrtc')) || |
|
71 | (cm.startStopBtn.get('textContent') === M.util.get_string('recordingfailed', 'atto_recordrtc'))) { |
|
72 | // Make sure the audio player and upload button are not shown. |
|
73 | cm.player.ancestor().ancestor().addClass('hide'); |
|
74 | cm.uploadBtn.ancestor().ancestor().addClass('hide'); |
|
75 | ||
76 | // Change look of recording button. |
|
77 | if (!cm.olderMoodle) { |
|
78 | cm.startStopBtn.replaceClass('btn-outline-danger', 'btn-danger'); |
|
79 | } |
|
80 | ||
81 | // Empty the array containing the previously recorded chunks. |
|
82 | cm.chunks = []; |
|
83 | cm.blobSize = 0; |
|
84 | ||
85 | // Initialize common configurations. |
|
86 | var commonConfig = { |
|
87 | // When the stream is captured from the microphone/webcam. |
|
88 | onMediaCaptured: function(stream) { |
|
89 | // Make audio stream available at a higher level by making it a property of the common module. |
|
90 | cm.stream = stream; |
|
91 | ||
92 | cm.start_recording(cm.recType, cm.stream); |
|
93 | }, |
|
94 | ||
95 | // Revert button to "Record Again" when recording is stopped. |
|
96 | onMediaStopped: function(btnLabel) { |
|
97 | cm.startStopBtn.set('textContent', btnLabel); |
|
98 | cm.startStopBtn.set('disabled', false); |
|
99 | if (!cm.olderMoodle) { |
|
100 | cm.startStopBtn.replaceClass('btn-danger', 'btn-outline-danger'); |
|
101 | } |
|
102 | }, |
|
103 | ||
104 | // Handle recording errors. |
|
105 | onMediaCapturingFailed: function(error) { |
|
106 | cm.handle_gum_errors(error, commonConfig); |
|
107 | } |
|
108 | }; |
|
109 | ||
110 | // Capture audio stream from microphone. |
|
111 | M.atto_recordrtc.audiomodule.capture_audio(commonConfig); |
|
112 | } else { // If button is displaying "Stop Recording". |
|
113 | // First of all clears the countdownTicker. |
|
114 | window.clearInterval(cm.countdownTicker); |
|
115 | ||
116 | // Disable "Record Again" button for 1s to allow background processing (closing streams). |
|
117 | window.setTimeout(function() { |
|
118 | cm.startStopBtn.set('disabled', false); |
|
119 | }, 1000); |
|
120 | ||
121 | // Stop recording. |
|
122 | M.atto_recordrtc.audiomodule.stopRecording(cm.stream); |
|
123 | ||
124 | // Change button to offer to record again. |
|
125 | cm.startStopBtn.set('textContent', M.util.get_string('recordagain', 'atto_recordrtc')); |
|
126 | if (!cm.olderMoodle) { |
|
127 | cm.startStopBtn.replaceClass('btn-danger', 'btn-outline-danger'); |
|
128 | } |
|
129 | } |
|
130 | }); |
|
131 | }, |
|
132 | ||
133 | // Setup to get audio stream from microphone. |
|
134 | capture_audio: function(config) { |
|
135 | cm.capture_user_media( |
|
136 | // Media constraints. |
|
137 | { |
|
138 | audio: true |
|
139 | }, |
|
140 | ||
141 | // Success callback. |
|
142 | function(audioStream) { |
|
143 | // Set audio player source to microphone stream. |
|
144 | cm.playerDOM.srcObject = audioStream; |
|
145 | ||
146 | config.onMediaCaptured(audioStream); |
|
147 | }, |
|
148 | ||
149 | // Error callback. |
|
150 | function(error) { |
|
151 | config.onMediaCapturingFailed(error); |
|
152 | } |
|
153 | ); |
|
154 | }, |
|
155 | ||
156 | stopRecording: function(stream) { |
|
157 | // Stop recording microphone stream. |
|
158 | cm.mediaRecorder.stop(); |
|
159 | ||
160 | // Stop each individual MediaTrack. |
|
161 | stream.getTracks().forEach(function(track) { |
|
162 | track.stop(); |
|
163 | }); |
|
164 | } |
|
165 | }; |
|
166 |