Skip to content

Instantly share code, notes, and snippets.

@baptx
Last active April 26, 2024 08:21
Show Gist options
  • Save baptx/8a1549d91996a37378faca159b3adc17 to your computer and use it in GitHub Desktop.
Save baptx/8a1549d91996a37378faca159b3adc17 to your computer and use it in GitHub Desktop.
WebRTC and video blob record (compatible with DRM and any videos like Facebook / Instagram stories)
/* Customized code to allow WebRTC record on existing page or HTML5 video blob download (based on https://github.com/webrtc/samples/blob/409d5631f38f2bdc4dafb5275d1bc77738fbb1ba/src/content/getusermedia/record/js/main.js)
* Recording will start when executing this script and you will have to execute manually startDownload() function when needed in web console with or without stopRecording()
* Recording should ideally start before playing video manually and in case controls are hidden, you can record from the start with a command like document.getElementsByTagName("video")[0].currentTime = 0
* By default, the script targets the first video element document.getElementsByTagName("video")[0] but you can change the code if needed.
*/
// If there is an error due to DRM, capture the stream by executing the following 2 lines before playing / loading the video:
var video = document.getElementsByTagName("video")[0];
var stream = video.captureStream ? video.captureStream() : video.mozCaptureStream();
var mediaSource = new MediaSource();
mediaSource.addEventListener('sourceopen', handleSourceOpen, false);
var mediaRecorder;
var recordedBlobs;
var sourceBuffer;
function startDownload() {
var blob = new Blob(recordedBlobs, {type: 'video/webm'});
var url = window.URL.createObjectURL(blob);
var a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = 'test.webm';
document.body.appendChild(a);
a.click();
setTimeout(() => {
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}, 100);
}
function handleSourceOpen(event) {
console.log('MediaSource opened');
sourceBuffer = mediaSource.addSourceBuffer('video/webm; codecs="vp8"');
console.log('Source buffer: ', sourceBuffer);
}
function handleDataAvailable(event) {
console.log('handleDataAvailable', event);
if (event.data && event.data.size > 0) {
recordedBlobs.push(event.data);
}
}
function startRecording() {
recordedBlobs = [];
try {
mediaRecorder = new MediaRecorder(stream);
} catch (e) {
console.error('Exception while creating MediaRecorder:', e);
return;
}
mediaRecorder.onstop = (event) => {
console.log('Recorder stopped: ', event);
console.log('Recorded Blobs: ', recordedBlobs);
};
mediaRecorder.ondataavailable = handleDataAvailable;
mediaRecorder.start(1000); // collect 1000ms of data (to be able to download every second even if recording is not stopped)
console.log('MediaRecorder started', mediaRecorder);
}
function stopRecording() {
mediaRecorder.stop();
}
startRecording();
@dreamflasher
Copy link

dreamflasher commented Mar 7, 2024

@baptx yes, I tried your script unmodified and that doesn't work. No bytes are coming in.

@baptx
Copy link
Author

baptx commented Apr 14, 2024

@dreamflasher To get the best video resolution with Firefox, a solution for me on Facebook stories was to detach the Developer Tools window in a separate window. If necessary, replay the video to get the best resolution.
When I tested playing a video (without recording it) with Chromium on https://integration.widevine.com/player, it behaved like Firefox, by default it may not get the best resolution and this may change based on your Internet connection speed. Some players like the one from the Widevine website allow to select the resolution instead of the automatic selection.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment