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