Completed
Push — master ( a001d3...c4e388 )
by Jacob
01:45
created

tinymce/js/videomodule.js   A

Complexity

Total Complexity 27
Complexity/F 2.08

Size

Lines of Code 166
Function Count 13

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 39
Bugs 4 Features 1
Metric Value
cc 0
c 39
b 4
f 1
nc 3
dl 0
loc 166
rs 10
wmc 27
mnd 2
bc 18
fnc 13
bpm 1.3846
cpm 2.0769
noi 0

2 Functions

Rating   Name   Duplication   Size   Complexity  
B M.tinymce_recordrtc.capture_audio_video 0 26 1
A M.tinymce_recordrtc.stop_recording_video 0 9 1
1
// TinyMCE recordrtc library functions.
2
// @package    tinymce_recordrtc.
3
// @author     Jesus Federico  (jesus [at] blindsidenetworks [dt] com).
4
// @copyright  2016 to present, Blindside Networks Inc.
5
// @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later.
6
7
// Scrutinizer CI directives.
8
/** global: M */
9
/** global: Y */
10
/** global: tinyMCEPopup */
11
/** global: recordrtc */
12
/** global: alertWarning */
13
/** global: alertDanger */
14
/** global: blobSize */
15
/** global: chunks */
16
/** global: countdownSeconds */
17
/** global: countdownTicker */
18
/** global: maxUploadSize */
19
/** global: mediaRecorder */
20
/** global: player */
21
/** global: playerDOM */
22
/** global: recType */
23
/** global: startStopBtn */
24
/** global: uploadBtn */
25
26
// This function is initialized from PHP.
27
M.tinymce_recordrtc.view_init = function() {
28
    // Assignment of global variables.
29
    alertWarning = Y.one('div#alert-warning');
30
    alertDanger = Y.one('div#alert-danger');
31
    player = Y.one('video#player');
32
    playerDOM = document.querySelector('video#player');
33
    startStopBtn = Y.one('button#start-stop');
34
    uploadBtn = Y.one('button#upload');
35
    recType = 'video';
36
    // Extract the numbers from the string, and convert to bytes.
37
    maxUploadSize = window.parseInt(recordrtc.maxfilesize.match(/\d+/)[0], 10) * Math.pow(1024, 2);
38
39
    // Show alert and redirect user if connection is not secure.
40
    M.tinymce_recordrtc.check_secure();
41
    // Show alert if using non-ideal browser.
42
    M.tinymce_recordrtc.check_browser();
43
44
    // Run when user clicks on "record" button.
45
    startStopBtn.on('click', function() {
46
        startStopBtn.set('disabled', true);
47
48
        // If button is displaying "Start Recording" or "Record Again".
49
        if ((startStopBtn.get('textContent') === M.util.get_string('startrecording', 'tinymce_recordrtc')) ||
50
            (startStopBtn.get('textContent') === M.util.get_string('recordagain', 'tinymce_recordrtc')) ||
51
            (startStopBtn.get('textContent') === M.util.get_string('recordingfailed', 'tinymce_recordrtc'))) {
52
            // Make sure the upload button is not shown.
53
            uploadBtn.ancestor().ancestor().addClass('hide');
54
55
            // Change look of recording button.
56
            if (!recordrtc.oldermoodle) {
57
                startStopBtn.replaceClass('btn-outline-danger', 'btn-danger');
58
            }
59
60
            // Empty the array containing the previously recorded chunks.
61
            chunks = [];
62
            blobSize = 0;
63
64
            // Initialize common configurations.
65
            var commonConfig = {
66
                // When the stream is captured from the microphone/webcam.
67
                onMediaCaptured: function(stream) {
68
                    // Make video stream available at a higher level by making it a property of startStopBtn.
69
                    startStopBtn.stream = stream;
70
71
                    M.tinymce_recordrtc.start_recording(recType, startStopBtn.stream);
72
                },
73
74
                // Revert button to "Record Again" when recording is stopped.
75
                onMediaStopped: function(btnLabel) {
76
                    startStopBtn.set('textContent', btnLabel);
77
                    startStopBtn.set('disabled', false);
78
                    if (!recordrtc.oldermoodle) {
79
                        startStopBtn.replaceClass('btn-danger', 'btn-outline-danger');
80
                    }
81
                },
82
83
                // Handle recording errors.
84
                onMediaCapturingFailed: function(error) {
85
                    var btnLabel = M.util.get_string('recordingfailed', 'tinymce_recordrtc');
86
                    var treatAsStopped = function() {
87
                        commonConfig.onMediaStopped(btnLabel);
88
                    };
89
90
                    // Handle getUserMedia-thrown errors.
91
                    // After alert, proceed to treat as stopped recording, or close dialogue.
92
                    switch (error.name) {
93
                        case 'AbortError':
94
                            M.tinymce_recordrtc.show_alert('gumabort', treatAsStopped);
95
96
                            break;
97
                        case 'NotAllowedError':
98
                            M.tinymce_recordrtc.show_alert('gumnotallowed', treatAsStopped);
99
100
                            break;
101
                        case 'NotFoundError':
102
                            M.tinymce_recordrtc.show_alert('gumnotfound', treatAsStopped);
103
104
                            break;
105
                        case 'NotReadableError':
106
                            M.tinymce_recordrtc.show_alert('gumnotreadable', treatAsStopped);
107
108
                            break;
109
                        case 'OverConstrainedError':
110
                            M.tinymce_recordrtc.show_alert('gumoverconstrained', treatAsStopped);
111
112
                            break;
113
                        case 'SecurityError':
114
                            M.tinymce_recordrtc.show_alert('gumsecurity', function() {
115
                                tinyMCEPopup.close();
116
                            });
117
118
                            break;
119
                        case 'TypeError':
120
                            M.tinymce_recordrtc.show_alert('gumtype', treatAsStopped);
121
122
                            break;
123
                        default:
124
                            break;
125
                    }
126
                }
127
            };
128
129
            // Show video tag without controls to view webcam stream.
130
            player.ancestor().ancestor().removeClass('hide');
131
            player.set('controls', false);
132
133
            // Capture audio+video stream from webcam/microphone.
134
            M.tinymce_recordrtc.capture_audio_video(commonConfig);
135
        } else { // If button is displaying "Stop Recording".
136
            // First of all clears the countdownTicker.
137
            window.clearInterval(countdownTicker);
138
139
            // Disable "Record Again" button for 1s to allow background processing (closing streams).
140
            window.setTimeout(function() {
141
                startStopBtn.set('disabled', false);
142
            }, 1000);
143
144
            // Stop recording.
145
            M.tinymce_recordrtc.stop_recording_video(startStopBtn.stream);
146
147
            // Change button to offer to record again.
148
            startStopBtn.set('textContent', M.util.get_string('recordagain', 'tinymce_recordrtc'));
149
            if (!recordrtc.oldermoodle) {
150
                startStopBtn.replaceClass('btn-danger', 'btn-outline-danger');
151
            }
152
        }
153
    });
154
};
155
156
// Setup to get audio+video stream from microphone/webcam.
157
M.tinymce_recordrtc.capture_audio_video = function(config) {
158
    M.tinymce_recordrtc.capture_user_media(
159
        // Media constraints.
160
        {
161
            audio: true,
162
            video: {
163
                width: {ideal: 640},
164
                height: {ideal: 480}
165
            }
166
        },
167
168
        // Success callback.
169
        function(audioVideoStream) {
170
            // Set video player source to microphone+webcam stream, and play it back as it's recording.
171
            playerDOM.srcObject = audioVideoStream;
172
            playerDOM.play();
173
174
            config.onMediaCaptured(audioVideoStream);
175
        },
176
177
        // Error callback.
178
        function(error) {
179
            config.onMediaCapturingFailed(error);
180
        }
181
    );
182
};
183
184
M.tinymce_recordrtc.stop_recording_video = function(stream) {
185
    // Stop recording microphone stream.
186
    mediaRecorder.stop();
187
188
    // Stop each individual MediaTrack.
189
    stream.getTracks().forEach(function(track) {
190
        track.stop();
191
    });
192
};
193