• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

collab-project / videojs-record / 13776407136

10 Mar 2025 10:56PM UTC coverage: 69.859% (-1.6%) from 71.445%
13776407136

push

github

web-flow
build(deps): bump prismjs from 1.29.0 to 1.30.0 in /docs (#738)

Bumps [prismjs](https://github.com/PrismJS/prism) from 1.29.0 to 1.30.0.
- [Release notes](https://github.com/PrismJS/prism/releases)
- [Changelog](https://github.com/PrismJS/prism/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PrismJS/prism/compare/v1.29.0...v1.30.0)

---
updated-dependencies:
- dependency-name: prismjs
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

362 of 581 branches covered (62.31%)

Branch coverage included in aggregate %.

827 of 1121 relevant lines covered (73.77%)

45.32 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

74.34
/src/js/engine/record-rtc.js
1
/**
2
 * @file record-rtc.js
3
 * @since 2.0.0
4
 */
5

6
import videojs from 'video.js';
7

8
import RecordRTC from 'recordrtc';
9

10
import Event from '../event';
11
import {RecordEngine} from './record-engine';
12
import {isChrome} from '../utils/detect-browser';
13
import {IMAGE_ONLY, AUDIO_ONLY, VIDEO_ONLY, AUDIO_VIDEO, ANIMATION, SCREEN_ONLY, AUDIO_SCREEN} from './record-mode';
14

15
const Component = videojs.getComponent('Component');
1✔
16

17
/**
18
 * Engine used with the MRecordRTC class in the RecordRTC library.
19
 *
20
 * @class
21
 * @augments videojs.RecordEngine
22
 */
23
class RecordRTCEngine extends RecordEngine {
24

25
    /**
26
     * Setup recording engine.
27
     *
28
     * @param {LocalMediaStream} stream - Media stream to record.
29
     * @param {Object} mediaType - Object describing the media type of this
30
     *     engine.
31
     * @param {Boolean} debug - Indicating whether or not debug messages should
32
     *     be printed in the console.
33
     */
34
    setup(stream, mediaType, debug) {
35
        this.inputStream = stream;
14✔
36
        this.mediaType = mediaType;
14✔
37
        this.debug = debug;
14✔
38

39
        if ('screen' in this.mediaType) {
14!
40
            this.mediaType.video = true;
×
41
        }
42

43
        // recorder type
44
        if (this.recorderType !== undefined) {
14!
45
            this.mediaType.video = this.recorderType;
×
46
        }
47

48
        // setup RecordRTC
49
        this.engine = new RecordRTC.MRecordRTC();
14✔
50
        this.engine.mediaType = this.mediaType;
14✔
51
        this.engine.disableLogs = !this.debug;
14✔
52
        this.engine.mimeType = this.mimeType;
14✔
53

54
        // audio settings
55
        this.engine.bufferSize = this.bufferSize;
14✔
56
        this.engine.sampleRate = this.sampleRate;
14✔
57
        this.engine.numberOfAudioChannels = this.audioChannels;
14✔
58

59
        // video/canvas settings
60
        this.engine.video = this.video;
14✔
61
        this.engine.canvas = this.canvas;
14✔
62
        this.engine.bitrate = this.bitRate;
14✔
63

64
        // animated gif settings
65
        this.engine.quality = this.quality;
14✔
66
        this.engine.frameRate = this.frameRate;
14✔
67

68
        // timeSlice option
69
        if (this.timeSlice !== undefined) {
14✔
70
            this.engine.timeSlice = this.timeSlice;
1✔
71
            this.engine.onTimeStamp = this.onTimeStamp.bind(this);
1✔
72
        }
73

74
        // worker
75
        this.engine.workerPath = this.workerPath;
14✔
76
        this.engine.webAssemblyPath = this.videoWebAssemblyURL;
14✔
77

78
        // connect stream to recording engine
79
        this.engine.addStream(this.inputStream);
14✔
80
    }
81

82
    /**
83
     * Remove any temporary data and references to streams.
84
     */
85
    dispose() {
86
        super.dispose();
23✔
87

88
        this.destroy();
23✔
89
    }
90

91
    /**
92
     * Destroy engine.
93
     */
94
    destroy() {
95
        if (this.engine && typeof this.engine.destroy === 'function') {
37!
96
            this.engine.destroy();
37✔
97
        }
98
    }
99

100
    /**
101
     * Start recording.
102
     */
103
    start() {
104
        this.engine.startRecording();
9✔
105
    }
106

107
    /**
108
     * Stop recording. Result will be available async when onStopRecording
109
     * is called.
110
     */
111
    stop() {
112
        this.engine.stopRecording(this.onStopRecording.bind(this));
23✔
113
    }
114

115
    /**
116
     * Pause recording.
117
     */
118
    pause() {
119
        this.engine.pauseRecording();
1✔
120
    }
121

122
    /**
123
     * Resume recording.
124
     */
125
    resume() {
126
        this.engine.resumeRecording();
1✔
127
    }
128

129
    /**
130
     * Show save as dialog in browser so the user can store the recorded media
131
     * locally.
132
     *
133
     * @param {object} name - Object with names for the particular blob(s)
134
     *     you want to save. File extensions are added automatically. For
135
     *     example: {'video': 'name-of-video-file'}. Supported keys are
136
     *     'audio', 'video' and 'gif'.
137
     * @example
138
     * // save video file as 'foo.webm'
139
     * player.record().saveAs({'video': 'foo'});
140
     */
141
    saveAs(name) {
142
        if (this.engine && name !== undefined) {
1!
143
            this.engine.save(name);
1✔
144
        }
145
    }
146

147
    /**
148
     * Invoked when recording is stopped and resulting stream is available.
149
     *
150
     * @private
151
     * @param {string} audioVideoURL - URI of the recorded Blob
152
     *     object, e.g. 'blob:http://localhost:8080/10100016-4248-9949-b0d6-0bb40db56eba'
153
     * @param {string} type - Media type, eg. 'video' or 'audio'.
154
     */
155
    onStopRecording(audioVideoURL, type) {
156
        // garbage collect unused blob
157
        URL.revokeObjectURL(audioVideoURL);
9✔
158

159
        // store reference to recorded stream data
160
        let recordType = this.player().record().getRecordType();
9✔
161
        this.engine.getBlob((recording) => {
9✔
162
            switch (recordType) {
9!
163
                case AUDIO_ONLY:
164
                    if (recording.audio !== undefined) {
5!
165
                        this.recordedData = recording.audio;
5✔
166
                    }
167
                    break;
5✔
168

169
                case VIDEO_ONLY:
170
                case AUDIO_VIDEO:
171
                case AUDIO_SCREEN:
172
                case SCREEN_ONLY:
173
                    // recordrtc returns a single blob that includes both audio
174
                    // and video data
175
                    if (recording.video !== undefined) {
4!
176
                        this.recordedData = recording.video;
4✔
177
                    }
178
                    break;
4✔
179

180
                case ANIMATION:
181
                    if (recording.gif !== undefined) {
×
182
                        this.recordedData = recording.gif;
×
183
                    }
184
                    break;
×
185
            }
186
            // inject file info
187
            this.addFileInfo(this.recordedData);
9✔
188

189
            // notify listeners
190
            this.trigger(Event.RECORD_COMPLETE);
9✔
191
        });
192
    }
193

194
    /**
195
     * Received new timestamp (when timeSlice option is enabled).
196
     * @private
197
     * @param {float} current - Current timestamp.
198
     * @param {array} all - List of timestamps so far.
199
     */
200
    onTimeStamp(current, all) {
201
        this.player().currentTimestamp = current;
7✔
202
        this.player().allTimestamps = all;
7✔
203

204
        // get blob (only for MediaStreamRecorder)
205
        let internal;
206
        switch (this.player().record().getRecordType()) {
7!
207
            case AUDIO_ONLY:
208
                internal = this.engine.audioRecorder;
7✔
209
                break;
7✔
210

211
            case ANIMATION:
212
                internal = this.engine.gifRecorder;
×
213
                break;
×
214

215
            default:
216
                internal = this.engine.videoRecorder;
×
217
        }
218

219
        let maxFileSizeReached = false;
7✔
220
        if (internal) {
7!
221
            internal = internal.getInternalRecorder();
7✔
222
        }
223

224
        if ((internal instanceof RecordRTC.MediaStreamRecorder) === true) {
7!
225
            this.player().recordedData = internal.getArrayOfBlobs();
7✔
226

227
            // inject file info for newest blob
228
            this.addFileInfo(
7✔
229
                this.player().recordedData[this.player_.recordedData.length - 1]);
230

231
            // check max file size
232
            if (this.maxFileSize > 0) {
7!
233
                let currentSize = new Blob(this.player().recordedData).size;
×
234
                if (currentSize >= this.maxFileSize) {
×
235
                    maxFileSizeReached = true;
×
236
                }
237
            }
238
        }
239

240
        // notify others
241
        this.player().trigger(Event.TIMESTAMP);
7✔
242

243
        // automatically stop when max file size was reached
244
        if (maxFileSizeReached) {
7!
245
            this.player().record().stop();
×
246
        }
247
    }
248
}
249

250
// expose plugin
251
videojs.RecordRTCEngine = RecordRTCEngine;
1✔
252

253
Component.registerComponent('RecordRTCEngine', RecordRTCEngine);
1✔
254

255
export default RecordRTCEngine;
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc