{"id":13433286,"url":"https://github.com/ai/audio-recorder-polyfill","last_synced_at":"2025-07-19T02:31:37.671Z","repository":{"id":26964084,"uuid":"112011548","full_name":"ai/audio-recorder-polyfill","owner":"ai","description":"MediaRecorder polyfill to record audio in Edge and Safari","archived":true,"fork":false,"pushed_at":"2024-09-21T09:30:02.000Z","size":2418,"stargazers_count":587,"open_issues_count":13,"forks_count":76,"subscribers_count":16,"default_branch":"main","last_synced_at":"2025-07-07T09:19:27.557Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://ai.github.io/audio-recorder-polyfill/","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/ai.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"ai"}},"created_at":"2017-11-25T14:53:51.000Z","updated_at":"2025-07-02T23:33:18.000Z","dependencies_parsed_at":"2024-10-27T12:50:59.361Z","dependency_job_id":"1aeb385a-5408-46fc-8fa2-2f3f245cfa86","html_url":"https://github.com/ai/audio-recorder-polyfill","commit_stats":{"total_commits":227,"total_committers":16,"mean_commits":14.1875,"dds":0.2070484581497798,"last_synced_commit":"bc9da8be40806d31a5aa12965984b4307a2b2c1d"},"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"purl":"pkg:github/ai/audio-recorder-polyfill","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ai%2Faudio-recorder-polyfill","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ai%2Faudio-recorder-polyfill/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ai%2Faudio-recorder-polyfill/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ai%2Faudio-recorder-polyfill/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ai","download_url":"https://codeload.github.com/ai/audio-recorder-polyfill/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ai%2Faudio-recorder-polyfill/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265876884,"owners_count":23842956,"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":[],"created_at":"2024-07-31T02:01:23.635Z","updated_at":"2025-07-19T02:31:37.319Z","avatar_url":"https://github.com/ai.png","language":"JavaScript","funding_links":["https://github.com/sponsors/ai"],"categories":["JavaScript"],"sub_categories":[],"readme":"# Audio Recorder Polyfill\n\n\u003cimg align=\"right\" width=\"80\" height=\"80\"\n     src=\"./logo.svg\"\n     title=\"Audio Recorder Polyfill Logo\"\u003e\n\n\u003e [!WARNING]\n\u003e **Deprecated: You do not need this polyfill for modern browsers**\n\n[MediaRecorder] polyfill to record audio in Edge and Safari.\nTry it in **[online demo]** and see **[API]**.\n\n* **Spec compatible.** In the future when all browsers will support\n  MediaRecorder, you will remove polyfill.\n* **Small.** 1.11 KB (minified and gzipped). No dependencies.\n  It uses [Size Limit] to control size.\n* **One file.** In contrast to other recorders, this polyfill uses\n  “inline worker” and don’t need a separated file for Web Worker.\n* **MP3** and **WAV** encoder support.\n\n```js\nnavigator.mediaDevices.getUserMedia({ audio: true }).then(stream =\u003e {\n  recorder = new MediaRecorder(stream)\n  recorder.addEventListener('dataavailable', e =\u003e {\n    audio.src = URL.createObjectURL(e.data)\n  })\n  recorder.start()\n})\n```\n\n[MediaRecorder]: https://developers.google.com/web/updates/2016/01/mediarecorder\n[online demo]:   https://ai.github.io/audio-recorder-polyfill/\n[Size Limit]:    https://github.com/ai/size-limit\n[API]:           https://ai.github.io/audio-recorder-polyfill/api/\n\n\u003ca href=\"https://evilmartians.com/?utm_source=audio-recorder-polyfill\"\u003e\n  \u003cimg src=\"https://evilmartians.com/badges/sponsored-by-evil-martians.svg\"\n       alt=\"Sponsored by Evil Martians\" width=\"236\" height=\"54\"\u003e\n\u003c/a\u003e\n\n\n## Install\n\nInstall package:\n\n```sh\nnpm install --save audio-recorder-polyfill\n```\n\nWe recommend creating separated webpack/Parcel bundle with polyfill.\nIn this case, polyfill will be downloaded only by Edge and Safari.\nGood browsers will download less.\n\nFiles recorded without the polyfill will not be playable on Safari,\nit is highly recommended to convert it to MP3 on the back-end\nof your application. If that’s not an option you can use the polyfill\nin all browsers to force the audio to be converted to the right format\nwith the price of client’s performance.\n\n```diff\n  entry: {\n    app: './src/app.js',\n+   polyfill: './src/polyfill.js'\n  }\n```\n\nInstall polyfill as MediaRecorder in this new bundle `src/polyfill.js`:\n\n```js\nimport AudioRecorder from 'audio-recorder-polyfill'\nwindow.MediaRecorder = AudioRecorder\n```\n\nAdd this code to your HTML to load this new bundle only for browsers\nwithout MediaRecorder support:\n\n```diff\n+   \u003cscript\u003e\n+     if (!window.MediaRecorder) {\n+       document.write(\n+         decodeURI('%3Cscript defer src=\"/polyfill.js\"\u003e%3C/script\u003e')\n+       )\n+     }\n+   \u003c/script\u003e\n    \u003cscript src=\"/app.js\" defer\u003e\u003c/script\u003e\n```\n\n## ES Modules\n\nPolyfill supports ES modules. You do not need to do anything for bundlers.\n\nFor quick hacks you can load polyfill from CDN. Do not use it in production\nbecause of low performance.\n\n```js\nimport AudioRecorder from 'https://cdn.jsdelivr.net/npm/audio-recorder-polyfill/index.js'\nwindow.MediaRecorder = AudioRecorder\n```\n\n\n## Usage\n\nIn the beginning, we need to show a warning in browsers without Web Audio API:\n\n```js\nif (MediaRecorder.notSupported) {\n  noSupport.style.display = 'block'\n  dictaphone.style.display = 'none'\n}\n```\n\nThen you can use standard MediaRecorder [API]:\n\n```js\nlet recorder\n\nrecordButton.addEventListener('click', () =\u003e {\n  // Request permissions to record audio\n  navigator.mediaDevices.getUserMedia({ audio: true }).then(stream =\u003e {\n    recorder = new MediaRecorder(stream)\n\n    // Set record to \u003caudio\u003e when recording will be finished\n    recorder.addEventListener('dataavailable', e =\u003e {\n      audio.src = URL.createObjectURL(e.data)\n    })\n\n    // Start recording\n    recorder.start()\n  })\n})\n\nstopButton.addEventListener('click', () =\u003e {\n  // Stop recording\n  recorder.stop()\n  // Remove “recording” icon from browser tab\n  recorder.stream.getTracks().forEach(i =\u003e i.stop())\n})\n```\n\nIf you need to upload record to the server, we recommend using `timeslice`.\nMediaRecorder will send recorded data every specified millisecond.\nSo you will start uploading before recording would finish.\n\n```js\n// Will be executed every second with next part of audio file\nrecorder.addEventListener('dataavailable', e =\u003e {\n  sendNextPiece(e.data)\n})\n// Dump audio data every second\nrecorder.start(1000)\n```\n\n[API]: https://developer.mozilla.org/en-US/docs/Web/API/MediaStream_Recording_API/Using_the_MediaStream_Recording_API\n\n\n## Audio Formats\n\nChrome records natively only to `.webm` files. Firefox to `.ogg`.\n\nYou can get used file format in `e.data.type`:\n\n```js\nrecorder.addEventListener('dataavailable', e =\u003e {\n  e.data.type //=\u003e 'audio/wav' with polyfill\n              //   'audio/webm' in Chrome\n              //   'audio/ogg' in Firefox\n})\n```\n\n\n### WAV\n\nAs default, this polyfill saves records to `.wav` files. Compression\nis not very good, but encoding is fast and simple.\n\n\n### MP3\n\nFor better compression you may use the MP3 encoder.\n\n```js\nimport AudioRecorder from 'audio-recorder-polyfill'\nimport mpegEncoder from 'audio-recorder-polyfill/mpeg-encoder'\n\nAudioRecorder.encoder = mpegEncoder\nAudioRecorder.prototype.mimeType = 'audio/mpeg'\nwindow.MediaRecorder = AudioRecorder\n```\n\n\n## Limitations\n\nThis polyfill tries to be MediaRecorder API compatible.\nBut it still has small differences.\n\n* WAV format contains duration in the file header. As result, with `timeslice`\n  or `requestData()` call, `dataavailable` will receive a separated file\n  with header on every call. In contrast, MediaRecorder sends header only\n  to first `dataavailable`. Other events receive addition bytes\n  to the same file.\n* Constructor options are not supported.\n* `BlobEvent.timecode` is not supported.\n\n\n## Custom Encoder\n\nIf you need audio format with better compression,\nyou can change polyfill’s encoder:\n\n```diff\n  import AudioRecorder from 'audio-recorder-polyfill'\n+ import customEncoder from './ogg-opus-encoder'\n+\n+ AudioRecorder.encoder = customEncoder\n+ AudioRecorder.prototype.mimeType = 'audio/ogg'\n  window.MediaRecorder = AudioRecorder\n```\n\nThe encoder should be a function with Web Worker in the body.\nPolyfill converts function to the string to make Web Worker.\n\n```js\nmodule.exports = () =\u003e {\n  function init (sampleRate) {\n    …\n  }\n\n  function encode (input) {\n    …\n  }\n\n  function dump (sampleRate) {\n    …\n    postMessage(output)\n  }\n\n  onmessage = e =\u003e {\n    if (e.data[0] === 'init') {\n      init(e.data[1])\n    } else if (e.data[0] === 'encode') {\n      encode(e.data[1])\n    } else if (e.data[0] === 'dump') {\n      dump(e.data[1])\n    }\n  }\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fai%2Faudio-recorder-polyfill","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fai%2Faudio-recorder-polyfill","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fai%2Faudio-recorder-polyfill/lists"}