Skip to content

Commit

Permalink
GifRecorder.js, CanvasRecorder.js, RecordRTC.js, WhammyRecorder.js, C…
Browse files Browse the repository at this point in the history
…ross-Browser-Declarations.js updated.

GifRecorder.js can now record HTMLCanvasElement and
CanvasRenderingContext2D as well.

“requestAnimationFrame” is removed from CanvasRecorder.js

RecordRTC.js now forces StereoAudioRecorder.js for Microsoft Edge.

You can skip “type” parameter when using “recorderType”. E.g.

var recordAudio = RecordRTC(stream, {
     recorderType: StereoAudioRecorder
});
  • Loading branch information
muaz-khan committed Sep 18, 2015
1 parent dc2bddc commit 88d257a
Show file tree
Hide file tree
Showing 10 changed files with 256 additions and 102 deletions.
38 changes: 32 additions & 6 deletions README.md
Expand Up @@ -223,7 +223,7 @@ var options = {
frameRate: 200,
quality: 10
};
var recordRTC = RecordRTC(mediaStream, options);
var recordRTC = RecordRTC(mediaStream || canvas || context, options);
recordRTC.startRecording();
recordRTC.stopRecording(function(gifURL) {
mediaElement.src = gifURL;
Expand Down Expand Up @@ -264,12 +264,10 @@ It is a function that can be used to initiate recorder however skip getting reco

```javascript
var audioRecorder = RecordRTC(mediaStream, {
type: 'audio',
recorderType: StereoAudioRecorder
});

var videoRecorder = RecordRTC(mediaStream, {
type: 'video',
recorderType: WhammyRecorder
});

Expand Down Expand Up @@ -308,7 +306,6 @@ navigator.mediaDevices.getUserMedia({
video: true
}).then(function(stream) {
var recordRTC = RecordRTC(stream, {
type: 'video',
recorderType: WhammyRecorder
});

Expand All @@ -334,11 +331,12 @@ recorder.clearRecordedData();

## `recorderType`

If you're using `recorderType` then you don't need to use `type`. Second one will be redundant i.e. skipped.

You can force any Recorder by passing this object over RecordRTC constructor:

```javascript
var audioRecorder = RecordRTC(mediaStream, {
type: 'audio',
recorderType: StereoAudioRecorder
})
```
Expand All @@ -349,6 +347,35 @@ This feature brings remote audio recording support in Firefox, and local audio r

You can even force `WhammyRecorder` on Firefox however webp format isn't yet supported in standard Firefox builds. It simply means that, you're skipping MediaRecorder API in Firefox.

## `type`

If you are NOT using `recorderType` parameter then `type` parameter can be used to ask RecordRTC choose best recorder-type for recording.

```javascript
// if it is Firefox, then RecordRTC will be using MediaStreamRecorder.js
// if it is Chrome or Opera, then RecordRTC will be using WhammyRecorder.js
var recordVideo = RecordRTC(mediaStream, {
type: 'video'
});

// if it is Firefox, then RecordRTC will be using MediaStreamRecorder.js
// if it is Chrome or Opera or Edge, then RecordRTC will be using StereoAudioRecorder.js
var recordVideo = RecordRTC(mediaStream, {
type: 'audio'
});
```

## `frameInterval`

Set minimum interval (in milliseconds) between each time we push a frame to Whammy recorder.

```javascript
var whammyRecorder = RecordRTC(videoStream, {
recorderType: WhammyRecorder,
frameInterval: 1 // setTimeout interval
});
```

## `disableLogs`

You can disable all the RecordRTC logs by passing this Boolean:
Expand All @@ -365,7 +392,6 @@ You can force [StereoAudioRecorder](http://RecordRTC.org/StereoAudioRecorder.htm

```javascript
var audioRecorder = RecordRTC(audioStream, {
type: 'audio',
recorderType: StereoAudioRecorder,
numberOfAudioChannels: 1 // or leftChannel:true
});
Expand Down
132 changes: 88 additions & 44 deletions RecordRTC.js
Expand Up @@ -9,6 +9,8 @@

// updates?
/*
-. GifRecorder.js can now record HTMLCanvasElement|CanvasRenderingContext2D as well.
-. added: frameInterval:20 for WhammyRecorder.js
-. chrome issue audio plus 720p-video recording can be fixed by setting bufferSize:16384
-. fixed Firefox save-as dialog i.e. recordRTC.save('filen-name')
-. "indexedDB" bug fixed for Firefox.
Expand Down Expand Up @@ -90,6 +92,26 @@ function RecordRTC(mediaStream, config) {
throw 'MediaStream is mandatory.';
}

if (config.recorderType && !config.type) {
if (config.recorderType === WhammyRecorder || config.recorderType === CanvasRecorder) {
config.type = 'video';
} else if (config.recorderType === GifRecorder) {
config.type = 'gif';
} else if (config.recorderType === StereoAudioRecorder) {
config.type = 'audio';
} else if (config.recorderType === MediaStreamRecorder) {
if (mediaStream.getAudioTracks().length && mediaStream.getVideoTracks().length) {
config.type = 'video';
} else if (mediaStream.getAudioTracks().length && !mediaStream.getVideoTracks().length) {
config.type = 'audio';
} else if (!mediaStream.getAudioTracks().length && mediaStream.getVideoTracks().length) {
config.type = 'audio';
} else {
// config.type = 'UnKnown';
}
}
}

// consider default type=audio
if (!config.type) {
config.type = 'audio';
Expand Down Expand Up @@ -131,18 +153,18 @@ function RecordRTC(mediaStream, config) {

// StereoAudioRecorder can work with all three: Edge, Firefox and Chrome
// todo: detect if it is Edge, then auto use: StereoAudioRecorder
if (typeof StereoAudioRecorder !== 'undefined' && isChrome) {
if (typeof StereoAudioRecorder !== 'undefined' && (isChrome || isEdge || isOpera)) {
// Media Stream Recording API has not been implemented in chrome yet;
// That's why using WebAudio API to record stereo audio in WAV format
Recorder = StereoAudioRecorder;
}

if (typeof MediaStreamRecorder !== 'undefined' && !isChrome) {
if (typeof MediaStreamRecorder !== 'undefined' && typeof MediaRecorder !== 'undefined' && 'requestData' in MediaRecorder.prototype) {
Recorder = MediaStreamRecorder;
}

// video recorder (in WebM format)
if (config.type === 'video' && isChrome) {
if (config.type === 'video' && (isChrome || isOpera)) {
if (typeof WhammyRecorder !== 'undefined') {
Recorder = WhammyRecorder;
} else {
Expand Down Expand Up @@ -1082,7 +1104,9 @@ if (typeof URL === 'undefined' && typeof webkitURL !== 'undefined') {
var URL = webkitURL;
}

var isChrome = true;
var isEdge = navigator.userAgent.indexOf('Edge') !== -1 && (!!navigator.msSaveBlob || !!navigator.msSaveOrOpenBlob);
var isOpera = !!window.opera || navigator.userAgent.indexOf('OPR/') !== -1;
var isChrome = !isOpera && !isEdge && !!navigator.webkitGetUserMedia;

if (typeof navigator !== 'undefined') {
if (typeof navigator.webkitGetUserMedia !== 'undefined') {
Expand All @@ -1092,8 +1116,6 @@ if (typeof navigator !== 'undefined') {
if (typeof navigator.mozGetUserMedia !== 'undefined') {
navigator.getUserMedia = navigator.mozGetUserMedia;
}

isChrome = typeof navigator.webkitGetUserMedia !== 'undefined';
} else {
/*global navigator:true */
var navigator = {
Expand Down Expand Up @@ -1945,7 +1967,7 @@ function StereoAudioRecorder(mediaStream, config) {
* @typedef CanvasRecorder
* @class
* @example
* var recorder = new CanvasRecorder(htmlElement);
* var recorder = new CanvasRecorder(htmlElement, { disableLogs: true });
* recorder.record();
* recorder.stop(function(blob) {
* video.src = URL.createObjectURL(blob);
Expand Down Expand Up @@ -2091,7 +2113,7 @@ function CanvasRecorder(htmlElement, config) {
});

if (isRecording) {
requestAnimationFrame(drawCanvasFrame);
setTimeout(drawCanvasFrame, 0);
}
}
});
Expand Down Expand Up @@ -2123,6 +2145,14 @@ function WhammyRecorder(mediaStream, config) {

config = config || {};

if (!config.frameInterval) {
config.frameInterval = 10;
}

if (!config.disableLogs) {
console.log('Using frames-interval:', config.frameInterval);
}

/**
* This method records video.
* @method
Expand Down Expand Up @@ -3042,17 +3072,17 @@ var DiskStorage = {
// GifRecorder.js

/**
* GifRecorder is standalone calss used by {@link RecordRTC} to record video as animated gif image.
* GifRecorder is standalone calss used by {@link RecordRTC} to record video or canvas into animated gif.
* @typedef GifRecorder
* @class
* @example
* var recorder = new GifRecorder(mediaStream);
* var recorder = new GifRecorder(mediaStream || canvas || context, { width: 1280, height: 720, frameRate: 200, quality: 10 });
* recorder.record();
* recorder.stop(function(blob) {
* img.src = URL.createObjectURL(blob);
* });
* @param {MediaStream} mediaStream - MediaStream object fetched using getUserMedia API or generated using captureStreamUntilEnded or WebAudio API.
* @param {object} config - {disableLogs:true, initcallback: function, width: 320, height: 240, frameRate: 200, quality: 10}
* @param {MediaStream} mediaStream - MediaStream object or HTMLCanvasElement or CanvasRenderingContext2D.
* @param {object} config - {disableLogs:true, initCallback: function, width: 320, height: 240, frameRate: 200, quality: 10}
*/

function GifRecorder(mediaStream, config) {
Expand All @@ -3062,6 +3092,8 @@ function GifRecorder(mediaStream, config) {

config = config || {};

var isHTMLObject = mediaStream instanceof CanvasRenderingContext2D || mediaStream instanceof HTMLCanvasElement;

/**
* This method records MediaStream.
* @method
Expand All @@ -3070,33 +3102,35 @@ function GifRecorder(mediaStream, config) {
* recorder.record();
*/
this.record = function() {
if (!config.width) {
config.width = video.offsetWidth || 320;
}
if (!isHTMLObject) {
if (!config.width) {
config.width = video.offsetWidth || 320;
}

if (!this.height) {
config.height = video.offsetHeight || 240;
}
if (!this.height) {
config.height = video.offsetHeight || 240;
}

if (!config.video) {
config.video = {
width: config.width,
height: config.height
};
}
if (!config.video) {
config.video = {
width: config.width,
height: config.height
};
}

if (!config.canvas) {
config.canvas = {
width: config.width,
height: config.height
};
}
if (!config.canvas) {
config.canvas = {
width: config.width,
height: config.height
};
}

canvas.width = config.canvas.width;
canvas.height = config.canvas.height;
canvas.width = config.canvas.width;
canvas.height = config.canvas.height;

video.width = config.video.width;
video.height = config.video.height;
video.width = config.video.width;
video.height = config.video.height;
}

// external library to record as GIF images
gifEncoder = new GIFEncoder();
Expand Down Expand Up @@ -3147,7 +3181,7 @@ function GifRecorder(mediaStream, config) {
return;
}

if (video.paused) {
if (!isHTMLObject && video.paused) {
// via: https://github.com/muaz-khan/WebRTC-Experiment/pull/316
// Tweak for Android Chrome
video.play();
Expand Down Expand Up @@ -3259,17 +3293,27 @@ function GifRecorder(mediaStream, config) {
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');

var video = document.createElement('video');
video.muted = true;
video.autoplay = true;

if (typeof video.srcObject !== 'undefined') {
video.srcObject = mediaStream;
} else {
video.src = URL.createObjectURL(mediaStream);
if (isHTMLObject) {
if (mediaStream instanceof CanvasRenderingContext2D) {
context = mediaStream;
} else if (mediaStream instanceof HTMLCanvasElement) {
context = mediaStream.getContext('2d');
}
}

video.play();
if (!isHTMLObject) {
var video = document.createElement('video');
video.muted = true;
video.autoplay = true;

if (typeof video.srcObject !== 'undefined') {
video.srcObject = mediaStream;
} else {
video.src = URL.createObjectURL(mediaStream);
}

video.play();
}

var lastAnimationFrame = null;
var startTime, endTime, lastFrameTime;
Expand Down
4 changes: 2 additions & 2 deletions RecordRTC.min.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dev/CanvasRecorder.js
Expand Up @@ -7,7 +7,7 @@
* @typedef CanvasRecorder
* @class
* @example
* var recorder = new CanvasRecorder(htmlElement);
* var recorder = new CanvasRecorder(htmlElement, { disableLogs: true });
* recorder.record();
* recorder.stop(function(blob) {
* video.src = URL.createObjectURL(blob);
Expand Down Expand Up @@ -153,7 +153,7 @@ function CanvasRecorder(htmlElement, config) {
});

if (isRecording) {
requestAnimationFrame(drawCanvasFrame);
setTimeout(drawCanvasFrame, 0);
}
}
});
Expand Down
6 changes: 3 additions & 3 deletions dev/Cross-Browser-Declarations.js
Expand Up @@ -44,7 +44,9 @@ if (typeof URL === 'undefined' && typeof webkitURL !== 'undefined') {
var URL = webkitURL;
}

var isChrome = true;
var isEdge = navigator.userAgent.indexOf('Edge') !== -1 && (!!navigator.msSaveBlob || !!navigator.msSaveOrOpenBlob);
var isOpera = !!window.opera || navigator.userAgent.indexOf('OPR/') !== -1;
var isChrome = !isOpera && !isEdge && !!navigator.webkitGetUserMedia;

if (typeof navigator !== 'undefined') {
if (typeof navigator.webkitGetUserMedia !== 'undefined') {
Expand All @@ -54,8 +56,6 @@ if (typeof navigator !== 'undefined') {
if (typeof navigator.mozGetUserMedia !== 'undefined') {
navigator.getUserMedia = navigator.mozGetUserMedia;
}

isChrome = typeof navigator.webkitGetUserMedia !== 'undefined';
} else {
/*global navigator:true */
var navigator = {
Expand Down

0 comments on commit 88d257a

Please sign in to comment.