{"id":13402286,"url":"https://github.com/streamproc/MediaStreamRecorder","last_synced_at":"2025-03-14T07:32:38.383Z","repository":{"id":9551712,"uuid":"11459116","full_name":"streamproc/MediaStreamRecorder","owner":"streamproc","description":"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.","archived":false,"fork":false,"pushed_at":"2018-07-04T13:42:21.000Z","size":392,"stargazers_count":2632,"open_issues_count":130,"forks_count":562,"subscribers_count":114,"default_branch":"master","last_synced_at":"2024-10-29T15:28:52.276Z","etag":null,"topics":["mediarecorder","mediastreamrecorder","webrtc","webrtc-demos","webrtc-experiments"],"latest_commit_sha":null,"homepage":"https://www.webrtc-experiment.com/msr/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/streamproc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-07-16T20:11:01.000Z","updated_at":"2024-10-24T12:16:30.000Z","dependencies_parsed_at":"2022-08-07T05:01:07.557Z","dependency_job_id":null,"html_url":"https://github.com/streamproc/MediaStreamRecorder","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/streamproc%2FMediaStreamRecorder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/streamproc%2FMediaStreamRecorder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/streamproc%2FMediaStreamRecorder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/streamproc%2FMediaStreamRecorder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/streamproc","download_url":"https://codeload.github.com/streamproc/MediaStreamRecorder/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243475366,"owners_count":20296711,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["mediarecorder","mediastreamrecorder","webrtc","webrtc-demos","webrtc-experiments"],"created_at":"2024-07-30T19:01:14.003Z","updated_at":"2025-03-14T07:32:38.376Z","avatar_url":"https://github.com/streamproc.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","webrtc","Libraries"],"sub_categories":["JavaScript"],"readme":"# [MediaStreamRecorder.js](https://github.com/streamproc/MediaStreamRecorder) - [Demos](https://www.webrtc-experiment.com/msr/)\n\n[![npm](https://img.shields.io/npm/v/msr.svg)](https://npmjs.org/package/msr) [![downloads](https://img.shields.io/npm/dm/msr.svg)](https://npmjs.org/package/msr) [![Build Status: Linux](https://travis-ci.org/streamproc/MediaStreamRecorder.png?branch=master)](https://travis-ci.org/streamproc/MediaStreamRecorder)\n\n## [Demos](https://www.webrtc-experiment.com/msr/) using [MediaStreamRecorder.js](https://github.com/streamproc/MediaStreamRecorder) library\n\n| Experiment Name        | Demo           | Source Code |\n| ------------- |-------------|-------------|\n| **Audio Recording** | [Demo](https://www.webrtc-experiment.com/msr/audio-recorder.html) | [Source](https://github.com/streamproc/MediaStreamRecorder/tree/master/demos/audio-recorder.html) |\n| **Video Recording** | [Demo](https://www.webrtc-experiment.com/msr/video-recorder.html) | [Source](https://github.com/streamproc/MediaStreamRecorder/tree/master/demos/video-recorder.html) |\n| **Gif Recording** | [Demo](https://www.webrtc-experiment.com/msr/gif-recorder.html) | [Source](https://github.com/streamproc/MediaStreamRecorder/tree/master/demos/gif-recorder.html) |\n| **MultiStreamRecorder Demo** | [Demo](https://www.webrtc-experiment.com/msr/MultiStreamRecorder.html) | [Source](https://github.com/streamproc/MediaStreamRecorder/tree/master/demos/MultiStreamRecorder.html) |\n\nA cross-browser implementation to record\n\n1. Camera\n2. Microphone\n3. Screen (full screen, apps' screens, tab, HTML elements)\n4. Canvas 2D as well as 3D animations (gaming/etc.)\n\nYou can record above four options altogether (in single container).\n\nMediaStreamRecorder 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.\n\n## Browser Support\n\n| Browser        | Support           | Features |\n| ------------- |-------------|-------------|\n| Firefox | [Stable](http://www.mozilla.org/en-US/firefox/new/) / [Aurora](http://www.mozilla.org/en-US/firefox/aurora/) / [Nightly](http://nightly.mozilla.org/) | Audio+Video (Both local/remote) |\n| Google Chrome | [Stable](https://www.google.com/intl/en_uk/chrome/browser/) / [Canary](https://www.google.com/intl/en/chrome/browser/canary.html) / [Beta](https://www.google.com/intl/en/chrome/browser/beta.html) / [Dev](https://www.google.com/intl/en/chrome/browser/index.html?extra=devchannel#eula) | Audio+Video (Both local/remote) |\n| Opera | [Stable](http://www.opera.com/) / [NEXT](http://www.opera.com/computer/next)  | Audio+Video (Both local/remote) |\n| Android | [Chrome](https://play.google.com/store/apps/details?id=com.chrome.beta\u0026hl=en) / [Firefox](https://play.google.com/store/apps/details?id=org.mozilla.firefox) / [Opera](https://play.google.com/store/apps/details?id=com.opera.browser) | Audio+Video (Both local/remote) |\n| Microsoft Edge | [Normal Build](https://www.microsoft.com/en-us/windows/microsoft-edge) | **Only Audio** - No Video - No Canvas - No Screen |\n| Safari 11 | preview | **Only Audio** - No Video - No Canvas - No Screen |\n\n\u003e There is a similar project: **RecordRTC**! [Demo](https://www.webrtc-experiment.com/RecordRTC/) - [Documentation](https://github.com/muaz-khan/RecordRTC)\n\n## How to link scripts?\n\nYou can [install scripts using NPM](https://www.npmjs.org/package/msr):\n\n```javascript\nnpm install msr\n\n# or via \"bower\"\nbower install msr\n```\n\nNow try `node server.js` and open `https://localhost:9001/`\n\n# Test on NPM\n\n```javascript\nvar MediaStreamRecorder = require('msr');\n\nconsole.log('require-msr', MediaStreamRecorder);\n\nconsole.log('\\n\\n-------\\n\\n');\n\nvar recorder = new MediaStreamRecorder({});\nconsole.log('MediaStreamRecorder', recorder);\n\nconsole.log('\\n\\n-------\\n\\n');\n\nvar multiStreamRecorder = new MediaStreamRecorder.MultiStreamRecorder([]);\nconsole.log('MultiStreamRecorder', multiStreamRecorder);\n```\n\n* Live NPM test: https://tonicdev.com/npm/msr\n\nOr try `npm-test.js`:\n\n```\ncd node_modules\ncd msr\nnode npm-test.js\n```\n\nThen link single/standalone \"MediaStreamRecorder.js\" file:\n\n```html\n\u003cscript src=\"./node_modules/msr/MediaStreamRecorder.js\"\u003e \u003c/script\u003e\n\n\u003c!-- or bower --\u003e\n\u003cscript src=\"./bower_components/msr/MediaStreamRecorder.js\"\u003e\u003c/script\u003e\n\n\u003c!-- CDN --\u003e\n\u003cscript src=\"https://cdn.webrtc-experiment.com/MediaStreamRecorder.js\"\u003e \u003c/script\u003e\n\n\u003c!-- WWW --\u003e\n\u003cscript src=\"https://www.webrtc-experiment.com/MediaStreamRecorder.js\"\u003e \u003c/script\u003e\n\n\u003c!-- or link specific release --\u003e\n\u003cscript src=\"https://github.com/streamproc/MediaStreamRecorder/releases/download/1.3.4/MediaStreamRecorder.js\"\u003e\u003c/script\u003e\n```\n\n## Record audio+video\n\n```html\n\u003cscript src=\"https://cdn.webrtc-experiment.com/MediaStreamRecorder.js\"\u003e \u003c/script\u003e\n\u003cscript\u003e\nvar mediaConstraints = {\n    audio: true,\n    video: true\n};\n\nnavigator.getUserMedia(mediaConstraints, onMediaSuccess, onMediaError);\n\nfunction onMediaSuccess(stream) {\n    var mediaRecorder = new MediaStreamRecorder(stream);\n    mediaRecorder.mimeType = 'video/webm';\n    mediaRecorder.ondataavailable = function (blob) {\n        // POST/PUT \"Blob\" using FormData/XHR2\n        var blobURL = URL.createObjectURL(blob);\n        document.write('\u003ca href=\"' + blobURL + '\"\u003e' + blobURL + '\u003c/a\u003e');\n    };\n    mediaRecorder.start(3000);\n}\n\nfunction onMediaError(e) {\n    console.error('media error', e);\n}\n\u003c/script\u003e\n```\n\n## Record Multiple Videos\n\n\u003e Record multiple videos in single WebM file.\n\n```javascript\nvar arrayOfStreams = [yourVideo, screen, remoteVideo1, remoteVideo2];\nvar multiStreamRecorder = new MultiStreamRecorder( arrayOfStreams );\n```\n\nYou can add additional streams at runtime:\n\n```javascript\nmultiStreamRecorder.addStream( anotherStream );\n```\n\nCurrently, you can only record 4-maximum videos in single WebM container.\n\n## Record audio/wav\n\n```html\n\u003cscript src=\"https://cdn.webrtc-experiment.com/MediaStreamRecorder.js\"\u003e \u003c/script\u003e\n\u003cscript\u003e\nvar mediaConstraints = {\n    audio: true\n};\n\nnavigator.getUserMedia(mediaConstraints, onMediaSuccess, onMediaError);\n\nfunction onMediaSuccess(stream) {\n    var mediaRecorder = new MediaStreamRecorder(stream);\n    mediaRecorder.mimeType = 'audio/wav'; // check this line for audio/wav\n    mediaRecorder.ondataavailable = function (blob) {\n        // POST/PUT \"Blob\" using FormData/XHR2\n        var blobURL = URL.createObjectURL(blob);\n        document.write('\u003ca href=\"' + blobURL + '\"\u003e' + blobURL + '\u003c/a\u003e');\n    };\n    mediaRecorder.start(3000);\n}\n\nfunction onMediaError(e) {\n    console.error('media error', e);\n}\n\u003c/script\u003e\n```\n\n## How to manually stop recordings?\n\n```javascript\nmediaRecorder.stop();\n```\n\n## How to pause recordings?\n\n```javascript\nmediaRecorder.pause();\n```\n\n## How to resume recordings?\n\n```javascript\nmediaRecorder.resume();\n```\n\n## How to save recordings?\n\n```javascript\n// invoke save-as dialog for all recorded blobs\nmediaRecorder.save();\n\n// or pass external blob/file\nmediaRecorder.save(YourExternalBlob, 'FileName.webm');\n```\n\n## Upload to PHP Server\n\nYour HTML file:\n\n```javascript\nmediaRecorder.ondataavailable = function(blob) {\n    // upload each blob to PHP server\n    uploadToPHPServer(blob);\n};\n\nfunction uploadToPHPServer(blob) {\n    var file = new File([blob], 'msr-' + (new Date).toISOString().replace(/:|\\./g, '-') + '.webm', {\n        type: 'video/webm'\n    });\n\n    // create FormData\n    var formData = new FormData();\n    formData.append('video-filename', file.name);\n    formData.append('video-blob', file);\n\n    makeXMLHttpRequest('https://path-to-your-server/save.php', formData, function() {\n        var downloadURL = 'https://path-to-your-server/uploads/' + file.name;\n        console.log('File uploaded to this path:', downloadURL);\n    });\n}\n\nfunction makeXMLHttpRequest(url, data, callback) {\n    var request = new XMLHttpRequest();\n    request.onreadystatechange = function() {\n        if (request.readyState == 4 \u0026\u0026 request.status == 200) {\n            callback();\n        }\n    };\n    request.open('POST', url);\n    request.send(data);\n}\n```\n\nSave.php file:\n\n```php\n\u003c?php\n// via: https://github.com/muaz-khan/RecordRTC/blob/master/RecordRTC-to-PHP/save.php\nheader(\"Access-Control-Allow-Origin: *\");\nfunction selfInvoker()\n{\n    if (!isset($_POST['audio-filename']) \u0026\u0026 !isset($_POST['video-filename'])) {\n        echo 'PermissionDeniedError';\n        return;\n    }\n\n    $fileName = '';\n    $tempName = '';\n\n    if (isset($_POST['audio-filename'])) {\n        $fileName = $_POST['audio-filename'];\n        $tempName = $_FILES['audio-blob']['tmp_name'];\n    } else {\n        $fileName = $_POST['video-filename'];\n        $tempName = $_FILES['video-blob']['tmp_name'];\n    }\n\n    if (empty($fileName) || empty($tempName)) {\n        echo 'PermissionDeniedError';\n        return;\n    }\n    $filePath = 'uploads/' . $fileName;\n\n    // make sure that one can upload only allowed audio/video files\n    $allowed = array(\n        'webm',\n        'wav',\n        'mp4',\n        'mp3',\n        'ogg'\n    );\n    $extension = pathinfo($filePath, PATHINFO_EXTENSION);\n    if (!$extension || empty($extension) || !in_array($extension, $allowed)) {\n        echo 'PermissionDeniedError';\n        continue;\n    }\n\n    if (!move_uploaded_file($tempName, $filePath)) {\n        echo ('Problem saving file.');\n        return;\n    }\n\n    echo ($filePath);\n}\nselfInvoker();\n?\u003e\n```\n\nRegarding PHP upload issues:\n\n* https://github.com/muaz-khan/RecordRTC/wiki/PHP-Upload-Issues\n\nDon't forget to create uploads directory here:\n\n```\nhttps://path-to-your-server/uploads/ ----- inside same directory as \"save.php\"\n```\n\n# API Documentation\n\n## `recorderType`\n\nYou can force StereoAudioRecorder or WhammyRecorder or similar recorders on Firefox or Edge; even on Chrome and Opera.\n\nAll browsers will be using your specified recorder:\n\n```javascript\n// force WebAudio API on all browsers\n// it allows you record remote audio-streams in Firefox\n// it also works in Microsoft Edge\nmediaRecorder.recorderType = StereoAudioRecorder;\n\n// force webp based webm encoder on all browsers\nmediaRecorder.recorderType = WhammyRecorder;\n\n// force MediaRecorder API on all browsers\n// Chrome Canary/Dev already implemented MediaRecorder API however it is still behind a flag.\n// so this property allows you force MediaRecorder in Chrome.\nmediaRecorder.recorderType = MediaRecorderWrapper;\n\n// force GifRecorder in all browsers. Both WhammyRecorder and MediaRecorder API will be ignored.\nmediaRecorder.recorderType = GifRecorder;\n```\n\n## `audioChannels`\n\n\u003e To choose between Stereo or Mono audio.\n\nIt 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\".\n\n```javascript\nmediaRecorder.audioChannels = 1;\n```\n\nNote: It requires following recorderType:\n\n```javascript\nmediaRecorder.recorderType = StereoAudioRecorder;\n```\n\n## `bufferSize`\n\nYou 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\".\n\n```javascript\nmediaRecorder.bufferSize = 0;\n```\n\n## `sampleRate`\n\nDefault \"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.\n\nIt accepts values only in range: 22050 to 96000\n\n```javascript\n// set sampleRate for NON-windows systems\nmediaRecorder.sampleRate = 96000;\n```\n\n## `video`\n\nIt is recommended to pass your HTMLVideoElement to get most accurate result.\n\n```javascript\nvideoRecorder.video = yourHTMLVideoElement;\nvideoRecorder.onStartedDrawingNonBlankFrames = function() {\n    // record audio here to fix sync issues\n    videoRecorder.clearOldRecordedFrames(); // clear all blank frames\n    audioRecorder.start(interval);\n};\n```\n\n## `stop`\n\nThis method allows you stop recording.\n\n```javascript\nmediaRecorder.stop();\n```\n\n## `pause`\n\nThis method allows you pause recording.\n\n```javascript\nmediaRecorder.pause();\n```\n\n## `resume`\n\nThis method allows you resume recording.\n\n```javascript\nmediaRecorder.resume();\n```\n\n## `save`\n\nThis method allows you save recording to disk (via save-as dialog).\n\n```javascript\n// invoke save-as dialog for all recorded blobs\nmediaRecorder.save();\n\n// or pass external blob/file\nmediaRecorder.save(YourExternalBlob, 'FileName.webm');\n```\n\n## canvas\n\nUsing this property, you can pass video resolutions:\n\n```javascript\nmediaRecorder.canvas = {\n    width: 1280,\n    height: 720\n};\n```\n\n## videoWidth and videoHeight\n\nYou can stretch video to specific width/height:\n\n```javascript\nmediaRecorder.videoWidth  = 1280;\nmediaRecorder.videoHeight = 720;\n```\n\n## clearOldRecordedFrames\n\nThis method allows you clear current video-frames. You can use it to remove blank-frames.\n\n```javascript\nvideoRecorder.video = yourHTMLVideoElement;\nvideoRecorder.onStartedDrawingNonBlankFrames = function() {\n    videoRecorder.clearOldRecordedFrames(); // clear all blank frames\n    audioRecorder.start(interval);\n};\n```\n\n## stop\n\nThis method allows you stop entire recording process.\n\n```javascript\nmediaRecorder.stop();\n```\n\n## start\n\nThis method takes \"interval\" as the only argument and it starts recording process:\n\n```javascript\nmediaRecorder.start(5 * 1000); // it takes milliseconds\n```\n\n## ondataavailable\n\nThis event is fired according to your interval and \"stop\" method.\n\n```javascript\nmediaRecorder.ondataavailable = function(blob) {\n    POST_to_Server(blob);\n};\n```\n\n## onstop\n\nThis event is fired when recording is stopped, either by invoking \"stop\" method or in case of any unexpected error:\n\n```javascript\nmediaRecorder.onstop = function() {\n    // recording has been stopped.\n};\n```\n\n## mimeType\n\nThis property allows you set output media type:\n\n```javascript\n// video:\nvideoRecorder.mimeType = 'video/webm';\nvideoRecorder.mimeType = 'video/mp4';\n\n// audio:\naudioRecorder.mimeType = 'audio/webm'; // MediaRecorderWrapper\naudioRecorder.mimeType = 'audio/ogg'; // MediaRecorderWrapper\naudioRecorder.mimeType = 'audio/wav'; // StereoAudioRecorder\naudioRecorder.mimeType = 'audio/pcm'; // StereoAudioRecorder\n\n// gif:\ngifRecorder.mimeType = 'image/gif'; // GifRecorder\n```\n\n## bitsPerSecond\n\n```javascript\n// currently supported only in Firefox\nvideoRecorder.bitsPerSecond = 12800;\n```\n\n## quality\n\n```javascript\n// only chrome---whilst using WhammyRecorder\nvideoRecorder.quality = .8;\n```\n\n## speed\n\n```javascript\n// only chrome---whilst using WhammyRecorder\nvideoRecorder.speed = 100;\n```\n\n## Contributors\n\n1. [Muaz Khan](https://github.com/muaz-khan)\n2. [neizerth](https://github.com/neizerth)\n3. [andersaloof](https://github.com/andersaloof)\n\n## License\n\n[MediaStreamRecorder.js](https://github.com/streamproc/MediaStreamRecorder) library is released under [MIT licence](https://github.com/streamproc/MediaStreamRecorder/blob/master/LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstreamproc%2FMediaStreamRecorder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstreamproc%2FMediaStreamRecorder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstreamproc%2FMediaStreamRecorder/lists"}