Skip to content

Commit

Permalink
WebAssemblyRecorder is included by default in RecordRTC-v5.5.2
Browse files Browse the repository at this point in the history
  • Loading branch information
muaz-khan committed Jan 13, 2019
1 parent 5dd23a8 commit 1e2de6a
Show file tree
Hide file tree
Showing 10 changed files with 2,627 additions and 80 deletions.
16 changes: 14 additions & 2 deletions Gruntfile.js
Expand Up @@ -53,7 +53,7 @@ module.exports = function(grunt) {
'dev/MultiStreamsMixer.js', // github/muaz-khan/MultiStreamsMixer
'dev/MultiStreamRecorder.js',
'dev/RecordRTC.promises.js',
// 'dev/WebAssemblyRecorder.js' // grunt-contrib-uglify fails; maybe we should use uglify-es instead?
'dev/WebAssemblyRecorder.js' // grunt-contrib-uglify fails; maybe we should use uglify-es instead?
],
dest: './temp/RecordRTC.js',
},
Expand Down Expand Up @@ -116,7 +116,9 @@ module.exports = function(grunt) {
JSON: true,
typeof: true,
define: true,
EBML: true
EBML: true,
ReadableStream: true,
WritableStream: true
},
browser: true,
browserify: true,
Expand Down Expand Up @@ -214,6 +216,15 @@ module.exports = function(grunt) {
pushTo: 'upstream',
gitDescribeOptions: '--tags --always --abbrev=1 --dirty=-d'
}
},
watch: {
scripts: {
files: ['dev/*.js'],
tasks: ['concat', 'replace', 'jsbeautifier', 'jshint', 'copy', 'uglify', 'clean'],
options: {
spawn: false,
},
}
}
});

Expand All @@ -222,4 +233,5 @@ module.exports = function(grunt) {
// set default tasks to run when grunt is called without parameters
// http://gruntjs.com/api/grunt.task
grunt.registerTask('default', ['concat', 'replace', 'jsbeautifier', 'jshint', 'copy', 'uglify', 'clean']);
grunt.loadNpmTasks('grunt-contrib-watch');
};
10 changes: 6 additions & 4 deletions README.md
Expand Up @@ -238,8 +238,8 @@ Otherwise check cdnjs below.
You can even link specific [releases](https://github.com/muaz-khan/RecordRTC/releases):

```html
<!-- use 5.5.1 or any other version on cdnjs -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/RecordRTC/5.5.1/RecordRTC.js"></script>
<!-- use 5.5.2 or any other version on cdnjs -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/RecordRTC/5.5.2/RecordRTC.js"></script>
```

Note: You can use `RecordRTC.min.js` as well. (on webrtc-experiment or cdnjs)
Expand Down Expand Up @@ -1193,11 +1193,13 @@ recorder.startRecording().then(function() {
});
recorder.stopRecording().then(function(url) {
var blob = recorder.blob;
recorder.getBlob().then(function(blob) {
//
}).catch(function(error) {});
recorder.getDataURL().then(function(dataURL) {
//
}).catch(function(error) {})
}).catch(function(error) {});
}).catch(function(error) {
//
});
Expand Down
209 changes: 208 additions & 1 deletion RecordRTC.js
@@ -1,6 +1,6 @@
'use strict';

// Last time updated: 2019-01-13 11:46:56 AM UTC
// Last time updated: 2019-01-13 12:45:07 PM UTC

// ________________
// RecordRTC v5.5.2
Expand Down Expand Up @@ -5611,3 +5611,210 @@ function RecordRTCPromisesHandler(mediaStream, options) {
if (typeof RecordRTC !== 'undefined') {
RecordRTC.RecordRTCPromisesHandler = RecordRTCPromisesHandler;
}

// All Copyrights goes to: Google Inc.

This comment has been minimized.

Copy link
@thijstriemstra

thijstriemstra Jan 13, 2019

Contributor

I think you should remove this line, you do not include Google code, you only use one of their libraries (that the user includes).

// Original: https://github.com/GoogleChromeLabs/webm-wasm

// ______________________
// WebAssemblyRecorder.js

/**
* WebAssemblyRecorder lets you create webm videos in JavaScript via WebAssembly. The library consumes raw RGBA32 buffers (4 bytes per pixel) and turns them into a webm video with the given framerate and quality. This makes it compatible out-of-the-box with ImageData from a CANVAS. With realtime mode you can also use webm-wasm for streaming webm videos.
* @summary Video recording feature in Chrome, Firefox and maybe Edge.
* @license {@link https://github.com/muaz-khan/RecordRTC#license|MIT}
* @author {@link http://www.MuazKhan.com|Muaz Khan}
* @typedef WebAssemblyRecorder
* @class
* @example
* var recorder = new WebAssemblyRecorder(mediaStream);
* recorder.record();
* recorder.stop(function(blob) {
* video.src = URL.createObjectURL(blob);
* });
* @see {@link https://github.com/muaz-khan/RecordRTC|RecordRTC Source Code}
* @param {MediaStream} mediaStream - MediaStream object fetched using getUserMedia API or generated using captureStreamUntilEnded or WebAudio API.
* @param {object} config - {webAssemblyPath:'webm-wasm.wasm',workerPath: 'webm-worker.js', frameRate: 30, width: 1920, height: 1080}
*/
function WebAssemblyRecorder(stream, config) {
if (typeof ReadableStream === 'undefined' || typeof WritableStream === 'undefined') {
// because it fixes readable/writable streams issues
console.error('Following polyfill is strongly recommended: https://unpkg.com/@mattiasbuelens/web-streams-polyfill/dist/polyfill.min.js');
}

config = config || {};

config.width = config.width || 640;
config.height = config.height || 480;
config.frameRate = config.frameRate || 30;
config.bitrate = config.bitrate || 1200;

function createBufferURL(buffer, type) {
return URL.createObjectURL(new Blob([buffer], {
type: type || ''
}));
}

function cameraStream() {
return new ReadableStream({
start: function(controller) {
var cvs = document.createElement('canvas');
var video = document.createElement('video');
video.srcObject = stream;
video.onplaying = function() {
cvs.width = config.width;
cvs.height = config.height;
var ctx = cvs.getContext('2d');
var frameTimeout = 1000 / config.frameRate;
setTimeout(function f() {
ctx.drawImage(video, 0, 0);
controller.enqueue(
ctx.getImageData(0, 0, config.width, config.height)
);
setTimeout(f, frameTimeout);
}, frameTimeout);
};
video.play();
}
});
}

var worker;

function startRecording(stream, buffer) {
if (!config.workerPath && !buffer) {
// is it safe to use @latest ?
fetch(
'https://unpkg.com/webm-wasm@latest/dist/webm-worker.js'
).then(function(r) {
r.arrayBuffer().then(function(buffer) {
startRecording(stream, buffer);
});
});
return;
}

if (!config.workerPath && buffer instanceof ArrayBuffer) {
var blob = new Blob([buffer], {
type: 'text/javascript'
});
config.workerPath = URL.createObjectURL(blob);
}

if (!config.workerPath) {
console.error('workerPath parameter is missing.');
}

worker = new Worker(config.workerPath);

worker.postMessage(config.webAssemblyPath || 'https://unpkg.com/webm-wasm@latest/dist/webm-wasm.wasm');
worker.addEventListener('message', function(event) {
if (event.data === 'READY') {
worker.postMessage({
width: config.width,
height: config.height,
bitrate: config.bitrate || 1200,
timebaseDen: config.frameRate || 30,
realtime: true
});

cameraStream().pipeTo(new WritableStream({
write: function(image) {
if (!worker) {
return;
}

worker.postMessage(image.data.buffer, [image.data.buffer]);
}
}));
} else if (!!event.data) {
if (!isPaused) {
arrayOfBuffers.push(event.data);
}
}
});
}

/**
* This method records video.
* @method
* @memberof WebAssemblyRecorder
* @example
* recorder.record();
*/
this.record = function() {
arrayOfBuffers = [];
isPaused = false;
this.blob = null;
startRecording(stream);
};

var isPaused;

/**
* This method pauses the recording process.
* @method
* @memberof WebAssemblyRecorder
* @example
* recorder.pause();
*/
this.pause = function() {
isPaused = true;
};

/**
* This method resumes the recording process.
* @method
* @memberof WebAssemblyRecorder
* @example
* recorder.resume();
*/
this.resume = function() {
isPaused = false;
};

function terminate() {
if (!worker) {
return;
}

worker.postMessage(null);
worker.terminate();
worker = null;
}

var arrayOfBuffers = [];

/**
* This method stops recording video.
* @param {function} callback - Callback function, that is used to pass recorded blob back to the callee.
* @method
* @memberof WebAssemblyRecorder
* @example
* recorder.stop(function(blob) {
* video.src = URL.createObjectURL(blob);
* });
*/
this.stop = function(callback) {
terminate();

this.blob = new Blob(arrayOfBuffers, {
type: 'video/webm'
});

callback(this.blob);
};

/**
* @property {Blob} blob - The recorded blob object.
* @memberof WebAssemblyRecorder
* @example
* recorder.stop(function(){
* var blob = recorder.blob;
* });
*/
this.blob = null;
}

if (typeof RecordRTC !== 'undefined') {
RecordRTC.WebAssemblyRecorder = WebAssemblyRecorder;
}
7 changes: 4 additions & 3 deletions RecordRTC.min.js

Large diffs are not rendered by default.

0 comments on commit 1e2de6a

Please sign in to comment.