Skip to content

Commit

Permalink
Added "video-plus-screen-recording" demo. Fixed echo on "MultiStreamR…
Browse files Browse the repository at this point in the history
…ecorder".

You can record both audio and screen in a single WebM:
simple-demos/video-plus-screen-recording
  • Loading branch information
muaz-khan committed Feb 21, 2017
1 parent 6ef4f35 commit d0a3a30
Show file tree
Hide file tree
Showing 6 changed files with 201 additions and 104 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,11 @@ recordRTC.stopRecording(function(audioURL) {

## Record Multiple Videos

Demos:

1. [Record all your cameras](https://github.com/muaz-khan/RecordRTC/blob/master/simple-demos/multi-cameras-recording.html)
2. [Record screen as well as your video!](https://github.com/muaz-khan/RecordRTC/blob/master/simple-demos/video-plus-screen-recording)

You can record 4 parallel videos/streams (**WebRTC Conference**):

```javascript
Expand Down
105 changes: 55 additions & 50 deletions RecordRTC.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Last time updated: 2017-02-21 7:34:45 AM UTC
// Last time updated: 2017-02-21 12:23:12 PM UTC

// ________________
// RecordRTC v5.4.1
Expand Down Expand Up @@ -4163,6 +4163,10 @@ function MultiStreamRecorder(arrayOfMediaStreams, options) {
self.audioContext = new AudioContext();
var audioSources = [];

self.gainNode = self.audioContext.createGain();
self.gainNode.connect(self.audioContext.destination);
self.gainNode.gain.value = 0; // don't hear self

var audioTracksLength = 0;
arrayOfMediaStreams.forEach(function(stream) {
if (!stream.getAudioTracks().length) {
Expand All @@ -4171,7 +4175,9 @@ function MultiStreamRecorder(arrayOfMediaStreams, options) {

audioTracksLength++;

audioSources.push(self.audioContext.createMediaStreamSource(stream));
var audioSource = self.audioContext.createMediaStreamSource(stream);
audioSource.connect(self.gainNode);
audioSources.push(audioSource);
});

if (!audioTracksLength) {
Expand All @@ -4198,6 +4204,7 @@ function MultiStreamRecorder(arrayOfMediaStreams, options) {
var video = getVideo(stream);
video.width = options.video.width;
video.height = options.video.height;
video.stream = stream;
videos.push(video);
});

Expand All @@ -4217,6 +4224,8 @@ function MultiStreamRecorder(arrayOfMediaStreams, options) {
function getVideo(stream) {
var video = document.createElement('video');
video.src = URL.createObjectURL(stream);
video.muted = true;
video.volume = 0;
video.play();
return video;
}
Expand All @@ -4230,74 +4239,70 @@ function MultiStreamRecorder(arrayOfMediaStreams, options) {

var videosLength = videos.length;

canvas.width = videosLength > 1 ? videos[0].width * 2 : videos[0].width;
canvas.height = videosLength > 2 ? videos[0].height * 2 : videos[0].height;

videos.forEach(function(video, idx) {
if (videosLength === 1) {
context.drawImage(video, 0, 0, video.width, video.height);
return;
var fullcanvas = false;
videos.forEach(function(video) {
if (video.stream.fullcanvas) {
fullcanvas = video.stream;
}
});

if (videosLength === 2) {
var x = 0;
var y = 0;

if (idx === 1) {
x = video.width;
}
if (fullcanvas) {
canvas.width = fullcanvas.width;
canvas.height = fullcanvas.height;
} else {
canvas.width = videosLength > 1 ? videos[0].width * 2 : videos[0].width;
canvas.height = videosLength > 2 ? videos[0].height * 2 : videos[0].height;
}

context.drawImage(video, x, y, video.width, video.height);
return;
}
videos.forEach(drawImage);

if (videosLength === 3) {
var x = 0;
var y = 0;
setTimeout(drawVideosToCanvas, options.frameInterval);
}

if (idx === 1) {
x = video.width;
}
function drawImage(video, idx) {
var x = 0;
var y = 0;
var width = video.width;
var height = video.height;

if (idx === 2) {
y = video.height;
}
if (idx === 1) {
x = video.width;
}

context.drawImage(video, x, y, video.width, video.height);
return;
}
if (idx === 2) {
y = video.height;
}

if (videosLength === 4) {
var x = 0;
var y = 0;
if (idx === 3) {
x = video.width;
y = video.height;
}

if (idx === 1) {
x = video.width;
}
if (typeof video.stream.left !== 'undefined') {
x = video.stream.left;
}

if (idx === 2) {
y = video.height;
}
if (typeof video.stream.top !== 'undefined') {
y = video.stream.top;
}

if (idx === 3) {
x = video.width;
y = video.height;
}
if (typeof video.stream.width !== 'undefined') {
width = video.stream.width;
}

context.drawImage(video, x, y, video.width, video.height);
return;
}
});
if (typeof video.stream.height !== 'undefined') {
height = video.stream.height;
}

setTimeout(drawVideosToCanvas, options.frameInterval);
context.drawImage(video, x, y, width, height);
}

var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');

canvas.style = 'opacity:0;position:absolute;z-index:-1;top: -100000000;left:-1000000000;';

document.body.appendChild(canvas);
(document.body || document.documentElement).appendChild(canvas);

/**
* This method pauses the recording process.
Expand Down
4 changes: 2 additions & 2 deletions RecordRTC.min.js

Large diffs are not rendered by default.

103 changes: 54 additions & 49 deletions dev/MultiStreamRecorder.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ function MultiStreamRecorder(arrayOfMediaStreams, options) {
self.audioContext = new AudioContext();
var audioSources = [];

self.gainNode = self.audioContext.createGain();
self.gainNode.connect(self.audioContext.destination);
self.gainNode.gain.value = 0; // don't hear self

var audioTracksLength = 0;
arrayOfMediaStreams.forEach(function(stream) {
if (!stream.getAudioTracks().length) {
Expand All @@ -124,7 +128,9 @@ function MultiStreamRecorder(arrayOfMediaStreams, options) {

audioTracksLength++;

audioSources.push(self.audioContext.createMediaStreamSource(stream));
var audioSource = self.audioContext.createMediaStreamSource(stream);
audioSource.connect(self.gainNode);
audioSources.push(audioSource);
});

if (!audioTracksLength) {
Expand All @@ -151,6 +157,7 @@ function MultiStreamRecorder(arrayOfMediaStreams, options) {
var video = getVideo(stream);
video.width = options.video.width;
video.height = options.video.height;
video.stream = stream;
videos.push(video);
});

Expand All @@ -170,6 +177,8 @@ function MultiStreamRecorder(arrayOfMediaStreams, options) {
function getVideo(stream) {
var video = document.createElement('video');
video.src = URL.createObjectURL(stream);
video.muted = true;
video.volume = 0;
video.play();
return video;
}
Expand All @@ -183,74 +192,70 @@ function MultiStreamRecorder(arrayOfMediaStreams, options) {

var videosLength = videos.length;

canvas.width = videosLength > 1 ? videos[0].width * 2 : videos[0].width;
canvas.height = videosLength > 2 ? videos[0].height * 2 : videos[0].height;

videos.forEach(function(video, idx) {
if (videosLength === 1) {
context.drawImage(video, 0, 0, video.width, video.height);
return;
var fullcanvas = false;
videos.forEach(function(video) {
if (video.stream.fullcanvas) {
fullcanvas = video.stream;
}
});

if (videosLength === 2) {
var x = 0;
var y = 0;

if (idx === 1) {
x = video.width;
}
if (fullcanvas) {
canvas.width = fullcanvas.width;
canvas.height = fullcanvas.height;
} else {
canvas.width = videosLength > 1 ? videos[0].width * 2 : videos[0].width;
canvas.height = videosLength > 2 ? videos[0].height * 2 : videos[0].height;
}

context.drawImage(video, x, y, video.width, video.height);
return;
}
videos.forEach(drawImage);

if (videosLength === 3) {
var x = 0;
var y = 0;
setTimeout(drawVideosToCanvas, options.frameInterval);
}

if (idx === 1) {
x = video.width;
}
function drawImage(video, idx) {
var x = 0;
var y = 0;
var width = video.width;
var height = video.height;

if (idx === 2) {
y = video.height;
}
if (idx === 1) {
x = video.width;
}

context.drawImage(video, x, y, video.width, video.height);
return;
}
if (idx === 2) {
y = video.height;
}

if (videosLength === 4) {
var x = 0;
var y = 0;
if (idx === 3) {
x = video.width;
y = video.height;
}

if (idx === 1) {
x = video.width;
}
if (typeof video.stream.left !== 'undefined') {
x = video.stream.left;
}

if (idx === 2) {
y = video.height;
}
if (typeof video.stream.top !== 'undefined') {
y = video.stream.top;
}

if (idx === 3) {
x = video.width;
y = video.height;
}
if (typeof video.stream.width !== 'undefined') {
width = video.stream.width;
}

context.drawImage(video, x, y, video.width, video.height);
return;
}
});
if (typeof video.stream.height !== 'undefined') {
height = video.stream.height;
}

setTimeout(drawVideosToCanvas, options.frameInterval);
context.drawImage(video, x, y, width, height);
}

var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');

canvas.style = 'opacity:0;position:absolute;z-index:-1;top: -100000000;left:-1000000000;';

document.body.appendChild(canvas);
(document.body || document.documentElement).appendChild(canvas);

/**
* This method pauses the recording process.
Expand Down
13 changes: 10 additions & 3 deletions simple-demos/multi-cameras-recording.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

<title>Multi-Videos (Conference) recording using RecordRTC</title>

<video controls autoplay loop></video>
<video controls autoplay></video>

<script src="https://cdn.webrtc-experiment.com/RecordRTC.js"></script>
<script src="https://cdn.webrtc-experiment.com/DetectRTC.js"> </script>
Expand All @@ -22,7 +22,7 @@

DetectRTC.videoInputDevices.forEach(function(device, idx) {
navigator.webkitGetUserMedia({
audio: false,
audio: true,
video: {
mandatory: {},
optional: [{
Expand All @@ -48,10 +48,15 @@

DetectRTC.load(function() {
captureAllCameras(function(streams) {
if(streams.length == 1) {
streams.push(streams[0]);
}

var recorder = RecordRTC(streams, {
type: 'video',
mimeType: 'video/webm',
previewStream: function(s) {
document.querySelector('video').muted = true;
document.querySelector('video').src = URL.createObjectURL(s);
}
});
Expand All @@ -61,6 +66,8 @@
setTimeout(function() {
recorder.stopRecording(function() {
var blob = recorder.getBlob();

document.querySelector('video').muted = false;
document.querySelector('video').src = URL.createObjectURL(blob);

allCameraStreams.forEach(function(stream) {
Expand All @@ -73,7 +80,7 @@
});
})
});
}, 10 * 1000)
}, 5 * 1000)
});
});
</script>
Loading

0 comments on commit d0a3a30

Please sign in to comment.