GithubHelp home page GithubHelp logo

streamproc / mediastreamrecorder Goto Github PK

View Code? Open in Web Editor NEW
2.6K 114.0 560.0 392 KB

Cross browser audio/video/screen recording. It supports Chrome, Firefox, Opera and Microsoft Edge. It even works on Android browsers. It follows latest MediaRecorder API standards and provides similar APIs.

Home Page: https://www.webrtc-experiment.com/msr/

License: MIT License

JavaScript 99.07% HTML 0.93%
mediastreamrecorder mediarecorder webrtc webrtc-experiments webrtc-demos

mediastreamrecorder's Introduction

npm downloads Build Status: Linux

Experiment Name Demo Source Code
Audio Recording Demo Source
Video Recording Demo Source
Gif Recording Demo Source
MultiStreamRecorder Demo Demo Source

A cross-browser implementation to record

  1. Camera
  2. Microphone
  3. Screen (full screen, apps' screens, tab, HTML elements)
  4. Canvas 2D as well as 3D animations (gaming/etc.)

You can record above four options altogether (in single container).

MediaStreamRecorder is useful in scenarios where you're planning to submit/upload recorded blobs in realtime to the server! You can get blobs after specific time-intervals.

Browser Support

Browser Support Features
Firefox Stable / Aurora / Nightly Audio+Video (Both local/remote)
Google Chrome Stable / Canary / Beta / Dev Audio+Video (Both local/remote)
Opera Stable / NEXT Audio+Video (Both local/remote)
Android Chrome / Firefox / Opera Audio+Video (Both local/remote)
Microsoft Edge Normal Build Only Audio - No Video - No Canvas - No Screen
Safari 11 preview Only Audio - No Video - No Canvas - No Screen

There is a similar project: RecordRTC! Demo - Documentation

How to link scripts?

You can install scripts using NPM:

npm install msr

# or via "bower"
bower install msr

Now try node server.js and open https://localhost:9001/

Test on NPM

var MediaStreamRecorder = require('msr');

console.log('require-msr', MediaStreamRecorder);

console.log('\n\n-------\n\n');

var recorder = new MediaStreamRecorder({});
console.log('MediaStreamRecorder', recorder);

console.log('\n\n-------\n\n');

var multiStreamRecorder = new MediaStreamRecorder.MultiStreamRecorder([]);
console.log('MultiStreamRecorder', multiStreamRecorder);

Or try npm-test.js:

cd node_modules
cd msr
node npm-test.js

Then link single/standalone "MediaStreamRecorder.js" file:

<script src="./node_modules/msr/MediaStreamRecorder.js"> </script>

<!-- or bower -->
<script src="./bower_components/msr/MediaStreamRecorder.js"></script>

<!-- 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.4/MediaStreamRecorder.js"></script>

Record audio+video

<script src="https://cdn.webrtc-experiment.com/MediaStreamRecorder.js"> </script>
<script>
var mediaConstraints = {
    audio: true,
    video: true
};

navigator.getUserMedia(mediaConstraints, onMediaSuccess, onMediaError);

function onMediaSuccess(stream) {
    var mediaRecorder = new MediaStreamRecorder(stream);
    mediaRecorder.mimeType = 'video/webm';
    mediaRecorder.ondataavailable = function (blob) {
        // POST/PUT "Blob" using FormData/XHR2
        var blobURL = URL.createObjectURL(blob);
        document.write('<a href="' + blobURL + '">' + blobURL + '</a>');
    };
    mediaRecorder.start(3000);
}

function onMediaError(e) {
    console.error('media error', e);
}
</script>

Record Multiple Videos

Record multiple videos in single WebM file.

var arrayOfStreams = [yourVideo, screen, remoteVideo1, remoteVideo2];
var multiStreamRecorder = new MultiStreamRecorder( arrayOfStreams );

You can add additional streams at runtime:

multiStreamRecorder.addStream( anotherStream );

Currently, you can only record 4-maximum videos in single WebM container.

Record audio/wav

<script src="https://cdn.webrtc-experiment.com/MediaStreamRecorder.js"> </script>
<script>
var mediaConstraints = {
    audio: true
};

navigator.getUserMedia(mediaConstraints, onMediaSuccess, onMediaError);

function onMediaSuccess(stream) {
    var mediaRecorder = new MediaStreamRecorder(stream);
    mediaRecorder.mimeType = 'audio/wav'; // check this line for audio/wav
    mediaRecorder.ondataavailable = function (blob) {
        // POST/PUT "Blob" using FormData/XHR2
        var blobURL = URL.createObjectURL(blob);
        document.write('<a href="' + blobURL + '">' + blobURL + '</a>');
    };
    mediaRecorder.start(3000);
}

function onMediaError(e) {
    console.error('media error', e);
}
</script>

How to manually stop recordings?

mediaRecorder.stop();

How to pause recordings?

mediaRecorder.pause();

How to resume recordings?

mediaRecorder.resume();

How to save recordings?

// invoke save-as dialog for all recorded blobs
mediaRecorder.save();

// or pass external blob/file
mediaRecorder.save(YourExternalBlob, 'FileName.webm');

Upload to PHP Server

Your HTML file:

mediaRecorder.ondataavailable = function(blob) {
    // upload each blob to PHP server
    uploadToPHPServer(blob);
};

function uploadToPHPServer(blob) {
    var file = new File([blob], 'msr-' + (new Date).toISOString().replace(/:|\./g, '-') + '.webm', {
        type: 'video/webm'
    });

    // create FormData
    var formData = new FormData();
    formData.append('video-filename', file.name);
    formData.append('video-blob', file);

    makeXMLHttpRequest('https://path-to-your-server/save.php', formData, function() {
        var downloadURL = 'https://path-to-your-server/uploads/' + file.name;
        console.log('File uploaded to this path:', downloadURL);
    });
}

function makeXMLHttpRequest(url, data, callback) {
    var request = new XMLHttpRequest();
    request.onreadystatechange = function() {
        if (request.readyState == 4 && request.status == 200) {
            callback();
        }
    };
    request.open('POST', url);
    request.send(data);
}

Save.php file:

<?php
// via: https://github.com/muaz-khan/RecordRTC/blob/master/RecordRTC-to-PHP/save.php
header("Access-Control-Allow-Origin: *");
function selfInvoker()
{
    if (!isset($_POST['audio-filename']) && !isset($_POST['video-filename'])) {
        echo 'PermissionDeniedError';
        return;
    }

    $fileName = '';
    $tempName = '';

    if (isset($_POST['audio-filename'])) {
        $fileName = $_POST['audio-filename'];
        $tempName = $_FILES['audio-blob']['tmp_name'];
    } else {
        $fileName = $_POST['video-filename'];
        $tempName = $_FILES['video-blob']['tmp_name'];
    }

    if (empty($fileName) || empty($tempName)) {
        echo 'PermissionDeniedError';
        return;
    }
    $filePath = 'uploads/' . $fileName;

    // make sure that one can upload only allowed audio/video files
    $allowed = array(
        'webm',
        'wav',
        'mp4',
        'mp3',
        'ogg'
    );
    $extension = pathinfo($filePath, PATHINFO_EXTENSION);
    if (!$extension || empty($extension) || !in_array($extension, $allowed)) {
        echo 'PermissionDeniedError';
        continue;
    }

    if (!move_uploaded_file($tempName, $filePath)) {
        echo ('Problem saving file.');
        return;
    }

    echo ($filePath);
}
selfInvoker();
?>

Regarding PHP upload issues:

Don't forget to create uploads directory here:

https://path-to-your-server/uploads/ ----- inside same directory as "save.php"

API Documentation

recorderType

You can force StereoAudioRecorder or WhammyRecorder or similar recorders on Firefox or Edge; even on Chrome and Opera.

All browsers will be using your specified recorder:

// force WebAudio API on all browsers
// it allows you record remote audio-streams in Firefox
// it also works in Microsoft Edge
mediaRecorder.recorderType = StereoAudioRecorder;

// force webp based webm encoder on all browsers
mediaRecorder.recorderType = WhammyRecorder;

// force MediaRecorder API on all browsers
// Chrome Canary/Dev already implemented MediaRecorder API however it is still behind a flag.
// so this property allows you force MediaRecorder in Chrome.
mediaRecorder.recorderType = MediaRecorderWrapper;

// force GifRecorder in all browsers. Both WhammyRecorder and MediaRecorder API will be ignored.
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".

mediaRecorder.audioChannels = 1;

Note: It requires following recorderType:

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".

mediaRecorder.bufferSize = 0;

sampleRate

Default "sampleRate" value is "44100". Currently you can't modify sample-rate in windows that's why this property isn't yet exposed to public API.

It accepts values only in range: 22050 to 96000

// set sampleRate for NON-windows systems
mediaRecorder.sampleRate = 96000;

video

It is recommended to pass your HTMLVideoElement to get most accurate result.

videoRecorder.video = yourHTMLVideoElement;
videoRecorder.onStartedDrawingNonBlankFrames = function() {
    // record audio here to fix sync issues
    videoRecorder.clearOldRecordedFrames(); // clear all blank frames
    audioRecorder.start(interval);
};

stop

This method allows you stop recording.

mediaRecorder.stop();

pause

This method allows you pause recording.

mediaRecorder.pause();

resume

This method allows you resume recording.

mediaRecorder.resume();

save

This method allows you save recording to disk (via save-as dialog).

// invoke save-as dialog for all recorded blobs
mediaRecorder.save();

// or pass external blob/file
mediaRecorder.save(YourExternalBlob, 'FileName.webm');

canvas

Using this property, you can pass video resolutions:

mediaRecorder.canvas = {
    width: 1280,
    height: 720
};

videoWidth and videoHeight

You can stretch video to specific width/height:

mediaRecorder.videoWidth  = 1280;
mediaRecorder.videoHeight = 720;

clearOldRecordedFrames

This method allows you clear current video-frames. You can use it to remove blank-frames.

videoRecorder.video = yourHTMLVideoElement;
videoRecorder.onStartedDrawingNonBlankFrames = function() {
    videoRecorder.clearOldRecordedFrames(); // clear all blank frames
    audioRecorder.start(interval);
};

stop

This method allows you stop entire recording process.

mediaRecorder.stop();

start

This method takes "interval" as the only argument and it starts recording process:

mediaRecorder.start(5 * 1000); // it takes milliseconds

ondataavailable

This event is fired according to your interval and "stop" method.

mediaRecorder.ondataavailable = function(blob) {
    POST_to_Server(blob);
};

onstop

This event is fired when recording is stopped, either by invoking "stop" method or in case of any unexpected error:

mediaRecorder.onstop = function() {
    // recording has been stopped.
};

mimeType

This property allows you set output media type:

// video:
videoRecorder.mimeType = 'video/webm';
videoRecorder.mimeType = 'video/mp4';

// audio:
audioRecorder.mimeType = 'audio/webm'; // MediaRecorderWrapper
audioRecorder.mimeType = 'audio/ogg'; // MediaRecorderWrapper
audioRecorder.mimeType = 'audio/wav'; // StereoAudioRecorder
audioRecorder.mimeType = 'audio/pcm'; // StereoAudioRecorder

// gif:
gifRecorder.mimeType = 'image/gif'; // GifRecorder

bitsPerSecond

// currently supported only in Firefox
videoRecorder.bitsPerSecond = 12800;

quality

// only chrome---whilst using WhammyRecorder
videoRecorder.quality = .8;

speed

// only chrome---whilst using WhammyRecorder
videoRecorder.speed = 100;

Contributors

  1. Muaz Khan
  2. neizerth
  3. andersaloof

License

MediaStreamRecorder.js library is released under MIT licence.

mediastreamrecorder's People

Contributors

andersaloof avatar muaz-khan avatar neizerth avatar phillab avatar rhema avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mediastreamrecorder's Issues

Unfortunate delay

Hello! I would want to ask if is there a possibility to reduce lag between reality and video produced by MediaStreamRecorder? Because when I move my head when camera is on me, "ondataready" produced blob is from ~2-3 seconds in the past.

I've tried reducing bufferSize to 256kb and changing type property in mediaRecorder, no success.

This is my code:

        recorder = new MediaStreamRecorder( stream );
        recorder.stream = stream;
        recorder.mimeType = 'video/mp4';
        recorder.videoWidth = 640;
        recorder.videoHeight = 480;
        recorder.bufferSize = 256;
        recorder.type = MediaRecorderWrapper;
        recorder.ondataavailable = function ( blob ) {
            console.log( blob );
            var objUrl = URL.createObjectURL( blob );
            video.src = objUrl;
            var dataBlob = { url: objUrl , frame: frameIndex++ };
            console.log( 'emitting data' );
            socket.emit( 'stream-data' , dataBlob , function () {
                var lengthEstimateKB = (dataBlob.url.length + 20) / 1024;
                transferStack += lengthEstimateKB;
                allowSend = true;
            } );
        }

        recorder.start( 50 );

        setInterval( function() {
            context.drawImage( video , 0 , 0 , video.videoWidth , video.videoHeight );
        } , 30 );

As you can see I am outputting ondataavailable immediately to video.src and then I am copying video contents into canvas to eliminate flicker by changing video.src attribute. But things in both my

Audio not getting captured after capturing it for 2-3 times.

After capturing the audio for 2-3 times. The audio stops getting captured, only a blank audio file is created. Following the console.log of the data of the Blob that I received.

data:audio/wav;base64,UklGRiygBQBXQVZFZm10IBAAAAABAAIARKwAABCxAgAEABAAZGF0Y…bI9lP2bfbx9eb1o/WB9UP0kPR488vzFPMQ8yPyQPKR8arxFvJF8iryPfJU8j/yfvGN8W/xSPE= c.html:51
data:audio/wav;base64,UklGRiwgCABXQVZFZm10IBAAAAABAAIARKwAABCxAgAEABAAZGF0Y…4EewT/A5MDZAOTA/UCtwK4AsMC8AL7ApMCiwJuASMB+wBYAb0BYgEpAgECJQMhA4sDSwPsAwkE c.html:51
data:audio/wav;base64,UklGRiwAAABXQVZFZm10IBAAAAABAAIARKwAABCxAgAEABAAZGF0YQAAAAA= c.html:51
data:audio/wav;base64,UklGRiwAAABXQVZFZm10IBAAAAABAAIARKwAABCxAgAEABAAZGF0YQAAAAA= c.html:51
data:audio/wav;base64,UklGRiwAAABXQVZFZm10IBAAAAABAAIARKwAABCxAgAEABAAZGF0YQAAAAA= c.html:51

As you can see, the last 2 console.log shows the same content every time, while the first 2 contain the actual data..

Long videos...

Hello im tring to record long videos en the browser, and then send it to the server side.

When the videos are longer that 3 minutes, the videos start to be intermittent
looks like if some buffer get full because many frames get lost

im trying here:
https://www.webrtc-experiment.com/msr/video-recorder.html

Any idea what could be the problem? maybe the browser buffer?

Edited:
I can see the same problem on the alternative project
https://www.webrtc-experiment.com/RecordRTC/

any suggestion ?

Audio ogg vs wav vs webm file size

Hello,

I've been trying to use the audio recording features of this library however I've noticed that no matter what mime type / file type I save it to/configure (ogg, wav or webm) it ends up being the same size. Is there an actual difference in how it's encoding these audio files? As it ends up being ~1MB for just 5 or 6 seconds or audio...

Thanks

Audio Recording bug

I use follwoing js

   var mediaRecorder = new MediaStreamRecorder(e.stream);
                mediaRecorder.mimeType = 'audio/ogg';
                mediaRecorder.ondataavailable = function (blob) {
                    // POST/PUT "Blob" using FormData/XHR2

                    // or read as DataURL
                    var reader = new FileReader();
                    reader.onload = function (e) {
                        console.log(e);
                    };
                    reader.readAsDataURL(blob);
                };
                mediaRecorder.start(3000);

after first file, its creating empty blob file.

ProgressEvent {total: 475180, loaded: 475180, lengthComputable: true, clipboardData: undefined, cancelBubble: false…}
 meet.html:120
ProgressEvent {total: 44, loaded: 44, lengthComputable: true, clipboardData: undefined, cancelBubble: false…}
 meet.html:120
ProgressEvent {total: 44, loaded: 44, lengthComputable: true, clipboardData: undefined, cancelBubble: false…}
 meet.html:120
ProgressEvent {total: 44, loaded: 44, lengthComputable: true, clipboardData: undefined, cancelBubble: false…}
 meet.html:120
ProgressEvent {total: 44, loaded: 44, lengthComputable: true, clipboardData: undefined, cancelBubble: false…}
 meet.html:120
ProgressEvent {total: 44, loaded: 44, lengthComputable: true, clipboardData: undefined, cancelBubble: false…}
 meet.html:120
ProgressEvent {total: 44, loaded: 44, lengthComputable: true, clipboardData: undefined, cancelBubble: false…}
 meet.html:120
ProgressEvent {total: 44, loaded: 44, lengthComputable: true, clipboardData: undefined, cancelBubble: false…}
 meet.html:120
ProgressEvent {total: 44, loaded: 44, lengthComputable: true, clipboardData: undefined, cancelBubble: false…}
 meet.html:120
ProgressEvent {total: 44, loaded: 44, lengthComputable: true, clipboardData: undefined, cancelBubble: false…}
 meet.html:120
ProgressEvent {total: 44, loaded: 44, lengthComputable: true, clipboardData: undefined, cancelBubble: false…}
 meet.html:120
ProgressEvent {total: 44, loaded: 44, lengthComputable: true, clipboardData: undefined, cancelBubble: false…}
 meet.html:120
ProgressEvent {total: 44, loaded: 44, lengthComputable: true, clipboardData: undefined, cancelBubble: false…}

MultiStreamRecorder can't replay audio on second recording session

I have a sample application that acquires local media and records audio and video. On user click 'replay' the just recorded blobs are replayed. When acquiring local media the second time to record and replay the audio/video blobs, audio is missing. This has been tested on Chrome.

Please take a look at the fiddle
https://jsfiddle.net/ufpeak2x/

  1. run the fiddle
  2. press 'replay'
  3. press 'rerecord'
  4. press 'replay'

Chrome Version 41.0.2272.104 (64-bit), Mac

can not record local Stream and remote Stream at the same time

i try to record local stream and remote stream when two peers established a p2p connection(video chat), then upload the record-file to server ,but only remoteStream can be recorded, here's my code

            pc.oniceconnectionstatechange = function(event) {
    console.log("iceConnectionState:" + pc.iceConnectionState);
    if (pc.iceConnectionState == 'connected') {
        // when connected, start to recording
                    localRecorder = new MultiStreamRecorder(localStream);
        localRecorder.video = inputElement; // to get maximum accuracy
        localRecorder.audioChannels = 1;
        localRecorder.ondataavailable = function (blobs) {
            if (blobs.audio)
                console.log("recorded local audio");
            if (blobs.video)
                console.log("recorded local video");
            var currentIndex = localIndex ++;
            var fileName = 'localVideo-' + currentIndex +'.webm';  // 
            var formData = new FormData();
            // append video blob
            formData.append('videoFileName', fileName);
            formData.append('videoFile', blobs.video);
            // append audio blob
            fileName = 'localAudio-' + currentIndex +'.wav';  //
            formData.append('audioFileName', fileName);
            formData.append('audioFile', blobs.audio);
            uploadFile(formData);
        };
        localRecorder.start(3 * 1000);

                     //record remoteStream
                    remoteRecorder = new MultiStreamRecorder(remoteStream);
        remoteRecorder.video = videoOutput; // to get maximum accuracy
        remoteRecorder.audioChannels = 1;
        remoteRecorder.ondataavailable = function (blobs) {
            // blobs.audio
            // blobs.video
            if (blobs.audio)
                console.log("recorded remote audio");
            if (blobs.video)
                console.log("recorded remote video");
            var currentIndex = remoteIndex ++;
            var fileName = 'remoteVideo-' + currentIndex +'.webm';
            var formData = new FormData();
            // append video blob
            formData.append('videoFileName', fileName);
            formData.append('videoFile', blobs.video);
            // append audio blob
            fileName = 'remoteAudio-' + currentIndex +'.wav'; 
            formData.append('audioFileName', fileName);
            formData.append('audioFile', blobs.audio);
            uploadFile(formData);
        };
        remoteRecorder.start(3 * 1000);
    }
}

Use PNaCl extension for Chrome instead of Whammy.js

Chrome will be releasing a video encoding pepper API for with Chrome 45. Since using Chrome's Portable Native Extensions (PNaCl) is invisible to the user (no installation steps necessary), I think it would be a good fit for your library. The Whammy method is interesting, but I cannot see it being used for any production use.

Example using the encoder: https://codereview.chromium.org/937643006/

There are still some issues with the example given and I am working with the Chromium team to address them:

https://codereview.chromium.org/1218513003
https://codereview.chromium.org/1187193006/
https://code.google.com/p/chromium/issues/detail?id=503153

Is it possible/good practice to not get blobs after certain intervals, but rather as one full webm file after hitting stop?

Right now it seems this is architected to be able to work for realtime video to send chunks of video back to a server. However, I don't need to do this necessarily. All I need to do is record audio + video in the browser and then upload it to a server all at once, once the stop button is pressed. I may want to even preview the video before upload first. I'm looking into how to do this, but I'm not sure yet how to do it. Any advice or pointers?

[Feature request] node.js-compatibility

Currently MediaStreamRecorder is available via "npm install msr" but not usable as a module in Electron or NW.js, because it lacks the proper export definition. Please assign module.exports if node.js is detected. Support for AMD (asynchronous module definition) would be nice, too.

Audio Recorder does not fire dataavailable event when stop button is pressed

Hello,

i'm using FF Developer Edition version 38.
On the audio demo, when I click on the stop button, I have to wait for the time interval end to get the last blob. This prevent me for setting a bigger time slice (let's say 1 min).

From the media recorder page on MDN, it is indicated :
In each case, the stop event is preceded by a dataavailable event, making the Blob captured up to that point available for you to use in your application.

It does not seem to be the case with your wonderful library. Doyou think there is something to do to get the correct behaviour ?

Thx in advance

Media Stream Recorder "Bug" must be fixed.

MediaRecorder must work fine on latest Firefox Nightlies; without any single crash.

Bug: Line 27
mediaRecorder.onstop = function () {
    if (mediaRecorder.state == 'inactive') {
        // bug: it is a temporary workaround; it must be fixed.
        mediaRecorder = new MediaRecorder(mediaStream);
        mediaRecorder.ondataavailable = self.ondataavailable;
        mediaRecorder.onstop = self.onstop;
        mediaRecorder.mimeType = self.mimeType;
        mediaRecorder.start(timeSlice);
    }
};

  1. We must not call stop automatically and repeatedly.
  2. start method must be invoked once until mediaRecorder.stop method is manually called by the end-user.

Regardless of whether it is Windows 7, 8 or Mac. MediaRecorder.js must work fine; all the time.

Bad Gateway when trying to access cdn file

When I am trying to access cdn file from here https://cdn.webrtc-experiment.com/MediaStreamRecorder.js I see 502 Bad Gateway error everytime.
Adding the screen shot below
screenshot from 2015-05-28 18 03 40

JS error after capturing some frames.

Kudos to the team for making this fabulous library.

I am getting following JavaScript error when I try to record videos.

Uncaught TypeError: Cannot read property 'width' of undefined MediaStreamRecorder.js:668
checkFrames MediaStreamRecorder.js:668
toWebM MediaStreamRecorder.js:524
WhammyVideo.compile MediaStreamRecorder.js:914
(anonymous function) MediaStreamRecorder.js:357

I am able to capture lot of frames, but problem occurs after some time, which is quite random. After this JS error occurs, the capturing of frames stops permanently.

Stream not clear

I am trying to record only audio using your api.
There are one issue how to clear a stream without refreshing page.
Because in my one HTML page there are 7 record buttons. and i not need to ask for share device on each and every click of button.
for that i want to create a stream only once.
and after stop i need to clear stream and record again.
Please help me to do this.

Missing timing informations in recorded blobs

I'm sending the recorded video/audio data to a server in pieces. Once the recording is done I'm combining the media files using the following command:

ffmpeg -f concat -i files.txt -codec copy combined.webm

The issue with that is, that the first few seconds (from the first blob) works fine but than the video stops the only the audio continues. During the combining I'm seeing a lot of errors like the following one:

[concat @ 0x7fa59981cc00] DTS 0 < 2700 out of order
[webm @ 0x7fa599829e00] Non-monotonous DTS in output stream 0:0; previous: 2700, current: 0; changing to 2700. This may result in incorrect timestamps in the output file.

How do you combine the recorded blobs on the server? Me current fix is to re-encode the single files into mp4 before combining them, but that obviously takes a long time.

Audio is slowed when recording

Using pretty much the example off the demo, it was working fine then for some reason today the audio started to sound "slowed" and "deeper"

I've adjusted the bitrates and the buffer stream, but none of those seem to have an effect on the results. I have tried on different computers, so not just a system / microphone issue.

Any ideas?

Sample audio I recorded (much deeper and slower):
https://drive.google.com/file/d/0B0Xd8Envj6lxR19kVlhQMnZUMms/view?usp=sharing

Update
I've added an SSL to my site, thinking that might be the issue (Chrome perhaps implementing some weird functionality) but that did not help. I have uploaded the demo onto my server and receive the same result: https://starkenglish.com/try.html

30 second limit?

My videos seem to stop at the 32 second mark -- any reason why this is? I've seen online that Whammy might have something to do with it? Thank you for any help.

Record & stop more then 6 times

#32 was fixed, but I have another issue related to it

https://jsfiddle.net/ufpeak2x/6/

To try to record and stop/replay 7 times. It will work 5 or 6 times.
Then you will get this error in console:

Uncaught NotSupportedError: Failed to construct 'AudioContext': The number of hardware contexts provided (6) is greater than or equal to the maximum bound (6).

problems recording in chorme

Hi!
I'm using the lib just to record audio and it worked perfectly fine a couple of weeks ago in chrome on windows and mac os, but now it doesn't work in chrome on windows. the output is much longer and slower than what It was recorded.
why did this happened? is there any solution?
thank you

Stop doesn't work in Chrome.

Woops, didn't mean to submit the empty issue. Sorry about that!

I have something like this (pretty much identical to the demo). I've been playing with calling stop in a timeout or something along those lines, but for testing I've been attempting to stop recording from the console.

  streamRecorder = new MediaStreamRecorder(stream);
  streamRecorder.mimeType = 'video/webm';
  streamRecorder.ondataavailable = function (blob) {
    var a = document.createElement('a');
    a.target = '_blank';
    a.innerHTML = 'Open Recorded Video No. ' + (index++);

    a.href = URL.createObjectURL(blob);

    videosContainer.appendChild(a);
    videosContainer.appendChild(document.createElement('hr'));
  };
  streamRecorder.start(5000);

In Firefox, calling streamRecorder.stop() after a few cycles works exactly as expected. In Chrome, however, there doesn't seem to be any way of stopping the loop beyond closing the tab. I assume this is because the shim isn't behaving properly (whammy?), but I haven't looked into a fix yet.

ability to specify quality

right now you cant change the quality of the recording, seems like a huge API missing.

the GIF encoder defaults to 1 (full quality), whammy for webm defaults to 0.8 (80% quality) and there is no way to change this whatsoever.

Each audio chunk first second corrupt

Hi. I am using (currently only audio) your library for recording purposes.
I'm writing 60 second chunks and send them to server, where I merge them.
All work fine. But one moment: almost each chunk's first second is broken. It sounds like repeated sound with high frequency... I hear it on the very first chunks I recieve from frontend, so that's why asking for your help.

I've tried switching audio formats, but that doesn't help( tried 'wav,ogg' ).

Also I have option for writing video(with audio) same problem with audio there, but video file looks straight.

Any suggestions?
Forgot to mention, that I'm using simple constraints while { audio : "true" }.

I've experimented a little with duration. Looks like with less duration comes less noise. And this noise happens even on first chunk, at start.

Silence detection in audio (onspeaking and onsilence events)

First of all, thanks for providing this library - it is a lifesaver!

The RTCMultiConnection library has silence detection, which I believe would be useful in MediaStreamRecorder. Instead of saving blobs on an interval (such as every 5 seconds), we can upload the blobs when the user stops speaking. Is this feature in the roadmap for this library (or is it easy to integrate)?

Thanks!

Black frame on gif generation

Every GIF I generate starts with a black frame. It looks like it starts recording before the camera gets loaded. Using Chrome Version 37.0.2062.94 (64-bit) on linux

Audio-Recording modules

  1. Use MediaRecorder API to record audio; if available
  2. Otherwise; use Web Audio API (something like Recorderjs) to record stereo audio in WAV format
  3. Fallback to jRecorder for chrome & mono audio

Syntax Hints
var recordMediaStream = new RecordMediaStream( MediaStream );

recordMediaStream.ondataavailable = function(e) {
     // e.data ---- type: Blob
};

recordMediaStream.onstop = function() { }

// void start(optional long timeSlice)
// timestamp to fire "ondataavailable"
recordMediaStream.start(interval);

recordMediaStream.stop();

For further events and methods: https://dvcs.w3.org/hg/dap/raw-file/tip/media-stream-capture/MediaRecorder.html

We need to decide whether storing data in Blob is better; or ArrayBuffer should be used. Read this thread for further info.

What about this flash-based recorder.js?

What about wami-recorder?

Need to list other available options & scenarios.

Platforms & Devices

  1. Chrome for Desktop (Windows/Mac/Unix)
  2. Firefox for Desktop (Windows/Mac/Unix)
  3. Chrome Beta for Android

Implementing Chrome desktopCapture with MediaStreamRecorder.

Hello,
This library saved my day.
I was implementing desktopCapture api with MediaStreamRecorder. Everything works perfect but the video quality is so blurred and bad! 1 minute desktop capturing video takes 14MB.
Is there any way to increase quality of the video? and is thr any way to compress video size too?

below is my code:

 var pending_request_id;

 chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
 startRecording();
 sendResponse({"success": true});
  });

function getUserMediaError() {
console.log("getUserMedia() failed.");
}

function onAccessApproved(id) {
 if (!id) {
 console.log("Access rejected.");
 return;
 }
  navigator.webkitGetUserMedia({
     audio:false,
    video: { mandatory: { chromeMediaSource: "desktop",
                        chromeMediaSourceId: id } }
  }, onMediaSuccess, getUserMediaError);
}

function startRecording()  {
pending_request_id = chrome.desktopCapture.chooseDesktopMedia(
   ["window"], onAccessApproved);
}



function onMediaSuccess(stream) {
 console.log("rcvd stream");
 var mediaRecorder = new MediaStreamRecorder(stream);
 mediaRecorder.mimeType = 'video/mp4';

 //i dont want strechy video so i fixed the width and height of recorder equal to window
mediaRecorder.width = window.screen.width; 
mediaRecorder.height = window.screen.height;

mediaRecorder.ondataavailable = function (blob) {

    var blobURL = URL.createObjectURL(blob);
    console.log('<a href="' + blobURL + '">' + blobURL + '</a>');


    var link=blobURL;
var videoInfo="Compiled Video file size: " + Math.ceil(blob.size / 1024) + "KB";

console.log(link);
console.log(videoInfo);

};
mediaRecorder.start(30000); // i want unlimited recording time so i increased the timeslice
  stream.onended = function() {
      mediaRecorder.stop();
  //finalizeVideo();
  console.log("Ended"); };
   }


function onMediaError(e) {
console.error('media error', e);
}

Before using this library i tried to save streaming video using whammy. but i failed to do so. then i found this library.

Pause/Resume missing

@muaz-khan I does not find anything for pause/resume recording. I have found recordRTC.pauseRecording() in RecordRTC. Can you please tell me how to Pause/Resume recording with MediaStreamRecorder . Thanks

MultiStreamRecoder : Inconsistent video blob duration

If we set timeInterval of 3000, then for every 3 seconds, onDataAvailbale method gets called. It contains two blobs

  1. blob.video
  2. blob.audio
    blob.audio duration is more or less consistent 3 seconds. But the video blob duration is mostly 2 seconds.

How to approach this issue?

Include external js

What do you think about case of including of external js libs?

I request to add some functional as FileSystem/ Base.js which will contains include function.
Your opinion?

Not generating multiple links

I am trying to run the same code in my local system for MultiStreamRecorder but its not generating multiple blobs url.
OS->OS X 10.10.3
Browser->Firefox 38.0.5

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.