Skip to content

Commit

Permalink
Added msr@1.3.3 Fixed #97, Merged & Closed #70, Closed #71
Browse files Browse the repository at this point in the history
  • Loading branch information
muaz-khan committed Jul 3, 2016
1 parent 62ab10e commit 7f5bcd5
Show file tree
Hide file tree
Showing 9 changed files with 188 additions and 60 deletions.
34 changes: 26 additions & 8 deletions AudioStreamRecorder/MediaRecorderWrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ function MediaRecorderWrapper(mediaStream) {
self.mimeType = IsChrome ? 'audio/webm' : 'audio/ogg';
}

self.blob = null;
self.dontFireOnDataAvailableEvent = false;

var recorderHints = {
Expand All @@ -72,7 +71,13 @@ function MediaRecorderWrapper(mediaStream) {

// starting a recording session; which will initiate "Reading Thread"
// "Reading Thread" are used to prevent main-thread blocking scenarios
mediaRecorder = new MediaRecorder(mediaStream, recorderHints);
try {
mediaRecorder = new MediaRecorder(mediaStream, recorderHints);
} catch (e) {
// if someone passed NON_supported mimeType
// or if Firefox on Android
mediaRecorder = new MediaRecorder(mediaStream);
}

if ('canRecordMimeType' in mediaRecorder && mediaRecorder.canRecordMimeType(self.mimeType) === false) {
if (!self.disableLogs) {
Expand All @@ -84,25 +89,34 @@ function MediaRecorderWrapper(mediaStream) {
// when video is resumed. E.g. yourStream.getVideoTracks()[0].muted = true; // it will auto-stop recording.
mediaRecorder.ignoreMutedMedia = self.ignoreMutedMedia || false;

var firedOnDataAvailableOnce = false;

// Dispatching OnDataAvailable Handler
mediaRecorder.ondataavailable = function(e) {
if (self.dontFireOnDataAvailableEvent) {
return;
}

if (!e.data || !e.data.size || e.data.size < 100 || self.blob) {
// how to fix FF-corrupt-webm issues?
// should we leave this? e.data.size < 26800
if (!e.data || !e.data.size || e.data.size < 26800 || firedOnDataAvailableOnce) {

This comment has been minimized.

Copy link
@marcusglowe

marcusglowe Jul 28, 2017

@muaz-khan this change to e.data.size check seems to break when using a format like audio/webm. I don't have a ton of context here but a 1 second audio recording of audio/webm had a size of around 6400 when testing on my computer. This leads to needing to chunk in at least 4.2s increments. Locally I'm planning on removing this check, but curious to know context on the FF corrupt webm issues...

return;
}

firedOnDataAvailableOnce = true;

var blob = self.getNativeBlob ? e.data : new Blob([e.data], {
type: self.mimeType || 'video/webm'
});

self.ondataavailable(blob);

self.dontFireOnDataAvailableEvent = true;
mediaRecorder.stop();
mediaRecorder = null;

if (!!mediaRecorder) {
mediaRecorder.stop();
mediaRecorder = null;
}

// record next interval
self.start(timeSlice, '__disableLogs');
Expand Down Expand Up @@ -131,7 +145,7 @@ function MediaRecorderWrapper(mediaStream) {
// if the timeSlice value is small. Callers should
// consider timeSlice as a minimum value

if (mediaRecorder.state !== 'inactive' && mediaRecorder.state !== 'stopped') {
if (!!mediaRecorder && mediaRecorder.state !== 'inactive' && mediaRecorder.state !== 'stopped') {
mediaRecorder.stop();
}
};
Expand All @@ -141,7 +155,11 @@ function MediaRecorderWrapper(mediaStream) {
// handler. "mTimeSlice < 0" means Session object does not push encoded data to
// onDataAvailable, instead, it passive wait the client side pull encoded data
// by calling requestData API.
mediaRecorder.start(3.6e+6);
try {
mediaRecorder.start(3.6e+6);
} catch (e) {
mediaRecorder = null;
}

setTimeout(function() {
if (!mediaRecorder) {
Expand Down Expand Up @@ -184,7 +202,7 @@ function MediaRecorderWrapper(mediaStream) {

setTimeout(function() {
self.dontFireOnDataAvailableEvent = true;
if (mediaRecorder.state === 'recording') {
if (!!mediaRecorder && mediaRecorder.state === 'recording') {
mediaRecorder.stop();
}
mediaRecorder = null;
Expand Down
15 changes: 9 additions & 6 deletions AudioStreamRecorder/StereoAudioRecorderHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,13 @@ function StereoAudioRecorderHelper(mediaStream, root) {

// we flat the left and right channels down
var leftBuffer = mergeBuffers(internalLeftChannel, internalRecordingLength);
var rightBuffer = mergeBuffers(internalLeftChannel, internalRecordingLength);

var interleaved = leftBuffer;

// we interleave both channels together
if (numChannels === 2) {
var interleaved = interleave(leftBuffer, rightBuffer);
} else {
var interleaved = leftBuffer;
var rightBuffer = mergeBuffers(internalRightChannel, internalRecordingLength); // bug fixed via #70,#71
interleaved = interleave(leftBuffer, rightBuffer);
}

// we create our wav file
Expand All @@ -72,7 +72,10 @@ function StereoAudioRecorderHelper(mediaStream, root) {

// RIFF chunk descriptor
writeUTFBytes(view, 0, 'RIFF');
view.setUint32(4, 44 + interleaved.length * 2, true);

// -8 (via #97)
view.setUint32(4, 44 + interleaved.length * 2 - 8, true);

writeUTFBytes(view, 8, 'WAVE');
// FMT sub-chunk
writeUTFBytes(view, 12, 'fmt ');
Expand All @@ -81,7 +84,7 @@ function StereoAudioRecorderHelper(mediaStream, root) {
// stereo (2 channels)
view.setUint16(22, numChannels, true);
view.setUint32(24, sampleRate, true);
view.setUint32(28, sampleRate * 4, true);
view.setUint32(28, sampleRate * numChannels * 2, true); // numChannels * 2 (via #71)
view.setUint16(32, numChannels * 2, true);
view.setUint16(34, 16, true);
// data sub-chunk
Expand Down
51 changes: 36 additions & 15 deletions MediaStreamRecorder.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Last time updated: 2016-05-15 5:22:54 AM UTC
// Last time updated: 2016-07-03 8:17:15 AM UTC

// links:
// Open-Sourced: https://github.com/streamproc/MediaStreamRecorder
Expand Down Expand Up @@ -637,7 +637,6 @@ function MediaRecorderWrapper(mediaStream) {
self.mimeType = IsChrome ? 'audio/webm' : 'audio/ogg';
}

self.blob = null;
self.dontFireOnDataAvailableEvent = false;

var recorderHints = {
Expand All @@ -664,7 +663,13 @@ function MediaRecorderWrapper(mediaStream) {

// starting a recording session; which will initiate "Reading Thread"
// "Reading Thread" are used to prevent main-thread blocking scenarios
mediaRecorder = new MediaRecorder(mediaStream, recorderHints);
try {
mediaRecorder = new MediaRecorder(mediaStream, recorderHints);
} catch (e) {
// if someone passed NON_supported mimeType
// or if Firefox on Android
mediaRecorder = new MediaRecorder(mediaStream);
}

if ('canRecordMimeType' in mediaRecorder && mediaRecorder.canRecordMimeType(self.mimeType) === false) {
if (!self.disableLogs) {
Expand All @@ -676,25 +681,34 @@ function MediaRecorderWrapper(mediaStream) {
// when video is resumed. E.g. yourStream.getVideoTracks()[0].muted = true; // it will auto-stop recording.
mediaRecorder.ignoreMutedMedia = self.ignoreMutedMedia || false;

var firedOnDataAvailableOnce = false;

// Dispatching OnDataAvailable Handler
mediaRecorder.ondataavailable = function(e) {
if (self.dontFireOnDataAvailableEvent) {
return;
}

if (!e.data || !e.data.size || e.data.size < 100 || self.blob) {
// how to fix FF-corrupt-webm issues?
// should we leave this? e.data.size < 26800
if (!e.data || !e.data.size || e.data.size < 26800 || firedOnDataAvailableOnce) {
return;
}

firedOnDataAvailableOnce = true;

var blob = self.getNativeBlob ? e.data : new Blob([e.data], {
type: self.mimeType || 'video/webm'
});

self.ondataavailable(blob);

self.dontFireOnDataAvailableEvent = true;
mediaRecorder.stop();
mediaRecorder = null;

if (!!mediaRecorder) {
mediaRecorder.stop();
mediaRecorder = null;
}

// record next interval
self.start(timeSlice, '__disableLogs');
Expand Down Expand Up @@ -723,7 +737,7 @@ function MediaRecorderWrapper(mediaStream) {
// if the timeSlice value is small. Callers should
// consider timeSlice as a minimum value

if (mediaRecorder.state !== 'inactive' && mediaRecorder.state !== 'stopped') {
if (!!mediaRecorder && mediaRecorder.state !== 'inactive' && mediaRecorder.state !== 'stopped') {
mediaRecorder.stop();
}
};
Expand All @@ -733,7 +747,11 @@ function MediaRecorderWrapper(mediaStream) {
// handler. "mTimeSlice < 0" means Session object does not push encoded data to
// onDataAvailable, instead, it passive wait the client side pull encoded data
// by calling requestData API.
mediaRecorder.start(3.6e+6);
try {
mediaRecorder.start(3.6e+6);
} catch (e) {
mediaRecorder = null;
}

setTimeout(function() {
if (!mediaRecorder) {
Expand Down Expand Up @@ -776,7 +794,7 @@ function MediaRecorderWrapper(mediaStream) {

setTimeout(function() {
self.dontFireOnDataAvailableEvent = true;
if (mediaRecorder.state === 'recording') {
if (!!mediaRecorder && mediaRecorder.state === 'recording') {
mediaRecorder.stop();
}
mediaRecorder = null;
Expand Down Expand Up @@ -1004,13 +1022,13 @@ function StereoAudioRecorderHelper(mediaStream, root) {

// we flat the left and right channels down
var leftBuffer = mergeBuffers(internalLeftChannel, internalRecordingLength);
var rightBuffer = mergeBuffers(internalLeftChannel, internalRecordingLength);

var interleaved = leftBuffer;

// we interleave both channels together
if (numChannels === 2) {
var interleaved = interleave(leftBuffer, rightBuffer);
} else {
var interleaved = leftBuffer;
var rightBuffer = mergeBuffers(internalRightChannel, internalRecordingLength); // bug fixed via #70,#71
interleaved = interleave(leftBuffer, rightBuffer);
}

// we create our wav file
Expand All @@ -1019,7 +1037,10 @@ function StereoAudioRecorderHelper(mediaStream, root) {

// RIFF chunk descriptor
writeUTFBytes(view, 0, 'RIFF');
view.setUint32(4, 44 + interleaved.length * 2, true);

// -8 (via #97)
view.setUint32(4, 44 + interleaved.length * 2 - 8, true);

writeUTFBytes(view, 8, 'WAVE');
// FMT sub-chunk
writeUTFBytes(view, 12, 'fmt ');
Expand All @@ -1028,7 +1049,7 @@ function StereoAudioRecorderHelper(mediaStream, root) {
// stereo (2 channels)
view.setUint16(22, numChannels, true);
view.setUint32(24, sampleRate, true);
view.setUint32(28, sampleRate * 4, true);
view.setUint32(28, sampleRate * numChannels * 2, true); // numChannels * 2 (via #71)
view.setUint16(32, numChannels * 2, true);
view.setUint16(34, 16, true);
// data sub-chunk
Expand Down
6 changes: 3 additions & 3 deletions MediaStreamRecorder.min.js

Large diffs are not rendered by default.

13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,11 @@ Then link single/standalone "MediaStreamRecorder.js" file:
<!-- CDN -->
<script src="https://cdn.webrtc-experiment.com/MediaStreamRecorder.js"> </script>

<!-- WWW -->
<script src="https://www.webrtc-experiment.com/MediaStreamRecorder.js"> </script>

<!-- or link specific release -->
<script src="https://github.com/streamproc/MediaStreamRecorder/releases/download/1.3.2/MediaStreamRecorder.js"></script>
<script src="https://github.com/streamproc/MediaStreamRecorder/releases/download/1.3.3/MediaStreamRecorder.js"></script>
```

## Record audio+video
Expand Down Expand Up @@ -239,12 +242,20 @@ mediaRecorder.recorderType = GifRecorder;

## `audioChannels`

> To choose between Stereo or Mono audio.
It is an integer value that accepts either 1 or 2. "1" means record only left-channel and skip right-one. The default value is "2".

```javascript
mediaRecorder.audioChannels = 1;
```

Note: It requires following recorderType:

```javascript
mediaRecorder.recorderType = StereoAudioRecorder;
```

## `bufferSize`

You can set following audio-bufferSize values: 0, 256, 512, 1024, 2048, 4096, 8192, and 16384. "0" means: let chrome decide the device's default bufferSize. Default value is "2048".
Expand Down
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "msr",
"version": "1.3.2",
"version": "1.3.3",
"authors": [
{
"name": "Muaz Khan",
Expand Down
Loading

0 comments on commit 7f5bcd5

Please sign in to comment.