Recorder records any MediaStream in mono, with mp3 by default
HTML5/JS audio recorder supporting mp3, wav, ogg, webm, amr, g711a and g711u formats, for PC and some Android/iOS web browsers, hybrid apps (with Android/iOS app source code) and WeChat. Includes ASR speech-to-text, an H5 voice-call chat demo, and DTMF encoding/decoding.
At a glance
- What is it?
- xiangyuecn's Recorder is a JavaScript recording library for html5 pages, hybrid apps and nodejs. It captures any MediaStream, transcodes through rec.mock into mp3, wav, pcm, g711, ogg, amr or webm, and supports one channel only. MIT licensed, shipped as two minified bundles and as recorder-core on npm.
- Who is it for?
- Recorder is worth a look if you record speech in a browser, a WeChat WebView, a mini program or nodejs, and you want realtime encoding, upload and playback in one file rather than three. It will not do stereo, it will not do WebM without accepting a beta tag, and its long recording story depends on you draining onProcess.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 107 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.
Star history
- xiangyuecn/Recorder5,641 ★ · +5
| Repository | 2026-09-23 | 2026-11-14 |
|---|---|---|
| xiangyuecn/Recorder | 5.6k | 5.6k |
5 Stars in the last 52 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
getUserMedia decides everything, and the browser list names who is left out
Recorder's first gate is the browser, not its API. The supported list is explicit: Chrome, Firefox, Safari, iOS 14.3+, Android WebView, the Tencent Android X5 kernel behind QQ, WeChat and mini program WebViews, Electron, most Android phone browsers updated after 2021, and the UC kernel versions updated after 2024, which covers UC, Alipay and DingTalk. Two exclusions are listed, though struck through in the README: old domestic phone browsers, and anything other than Safari on iOS 11.0 through 14.2.
That list matters more than a feature table, because a missing getUserMedia implementation ends the session before a single Recorder option is read. Rather than restating support itself, the project links caniuse filtered on getUserMedia, which points at the capability check living in the platform. It also means one bundle is expected to run in a desktop browser, inside a WeChat WebView and under Electron without a separate build.
Mono only, and long recordings lean on onProcess to release memory
Recorder is built for speech, so it handles a single channel and leaves stereo unadapted. That decision reaches upward into everything else: a stereo MediaStream input sits outside what the library claims, and the format list is assembled for voice rather than music.
Recording length is the other half of the same constraint. Long sessions are handled through the realtime process callback onProcess, which cleans up and releases memory as it runs, and that is the mechanism the README points at for very long recordings. It also explains why realtime processing is presented as a core capability rather than a plugin extra: the callback is the pressure valve. Draining onProcess correctly is what keeps an hours-long capture from turning into a memory problem, so it deserves attention before the encoder choice does.
mp3 by default, and webm is the one format still tagged beta
The default container is mp3. Beyond it the library offers wav, pcm, g711a, g711u, ogg, amr and webm, which is the entry marked beta, and it accepts any other format as long as you supply the encoder.
Transcoding is not limited to what the microphone produced. Recorded buffers and arbitrary PCM data can be converted into whichever of those formats you need through the rec.mock method, which turns a capture tool into a converter as well. A page that already holds PCM from somewhere else can push it through the same encoders the live path uses. The cost is that you now own codec choice and its file size, and the beta tag on webm says the formats here are not equally settled.
Two minified bundles at the root, and a first run from QuickStart.html
The repository root is the delivery mechanism: two minified bundles, the source, the demos and the quick start page.
recorder.mp3.min.js
recorder.wav.min.js
QuickStart.html
index.html
src/
dist/
assets/
app-support-sample/recorder.mp3.min.js is 150kb and records mp3, while recorder.wav.min.js is 25kb and records wav, and both support realtime transcoding and realtime transfer, so the size gap is a codec decision rather than a feature cut. For a first run, the documented path is the set of demo pages hosted on github.io, including H5 online test, H5 QuickStart and vue, ts and es module variants. The fallback is stated plainly: download the source and open the html file locally. The npm package is recorder-core, and JsDelivr and unpkg copies of the repository are linked beside it.
Any MediaStream can be the source, not only a microphone
Recorder does not insist on getUserMedia output. Any MediaStream can be recorded and processed in realtime, and four sources are named: the stream getUserMedia returns, a remote stream from WebRTC, whatever the captureStream method of an audio or video element returns, and a stream you construct yourself.
That widens what the library is for. A WebRTC call can be recorded without a second capture path, an audio element playing a file can run through the same encoders, and a synthesised stream can be recorded like a microphone feed. The demo index backs that up, including a test that turns numbered musical notation text into PCM. Upload is documented just as carefully as capture, with separate realtime encode-and-transfer demos for the frame callback version, for fixed frame sizes, and for a general older path.
Playback splits between a finished file on audio.src and a fragment on BufferStreamPlayer
A finished recording plays through an ordinary Audio tag: assign the link of the uploaded file to audio.src. A local blob goes through URL.createObjectURL to get a local link for the same attribute, or the blob object can be assigned straight to audio.srcObject, which the README flags as the less compatible of the two. Realtime fragments are a third case with their own plugin, BufferStreamPlayer, shipped in the library, so encoded chunks can be played as they arrive instead of after the recording ends.
The three paths cover the cases that break naive implementations: a file already on a server, a blob that never leaves the browser, and a partial stream with no complete file behind it. BufferStreamPlayer is the part you would otherwise write yourself, and the demo list shows it decoding realtime encoded fragments back to sound.
RecordApp carries the same code into mini programs, uni-app and nodejs
Outside a browser, the README claims partial support in nodejs and in programs built with js, and RecordApp, the sample under app-support-sample, records directly inside WeChat mini programs and uni-app. Source for the mini program and the uni-app demo sits in that directory, next to an Android demo app offered as a 40kb APK archive with its source, and iOS source you compile yourself.
The demo index is where the plugin surface shows: realtime speech recognition turning audio into text (an Aliyun version), DTMF decode and encode, realtime multi-channel mixing, speed and pitch transformation, IIR low and high pass filters, FFT spectrum analysis, conversion between mp3, wav and amr, and merging several mp3 or wav fragments into one file. That is a signal processing bench attached to a recorder core, and it is documented with demo pages rather than prose.
MIT licensed, shipped as recorder-core, last pushed on 2026-07-30
Distribution runs three ways: the minified files in the repository, the recorder-core package on npm, and CDN copies on JsDelivr and unpkg. The licence is MIT and the default branch is master.
The maintenance picture is uneven. The last push was on 2026-07-30, and the three most recent releases are 1.3.26070800 on 2026-07-08, 1.3.25011100 on 2025-01-11 and 1.3.24102001 on 2024-10-20, so the gap between releases runs from about three months to a year and a half. Support is not an issue tracker workflow: the project asks you to join one of four QQ groups and send the lowercase passphrase `recorder`. Custom recording work is offered by the author through those same groups, which tells you where maintenance pressure sits when something breaks.
Editorial conclusion
Recorder is worth a look if you record speech in a browser, a WeChat WebView, a mini program or nodejs, and you want realtime encoding, upload and playback in one file rather than three. It will not do stereo, it will not do WebM without accepting a beta tag, and its long recording story depends on you draining onProcess. Before you commit, check two things: whether your target browser is outside the excluded group of old domestic phone browsers and non-Safari browsers on iOS 11.0 through 14.2, and how old the version you would pin is, since the newest release tag is 1.3.26070800 from 2026-07-08.
Frequently asked questions
Which formats can Recorder record and convert to?
The default output is mp3, with wav, pcm, g711a, g711u, ogg, amr and webm (beta) available, and any other format can be added given the right encoder. Recorded buffers and arbitrary PCM data are converted through the rec.mock method.
Which browsers can Recorder capture microphone audio in?
Most browsers that have implemented getUserMedia: Chrome, Firefox, Safari, iOS 14.3+, Android WebView, the Tencent X5 kernel behind QQ, WeChat and mini programs, Electron, and most Android phone browsers updated after 2021. The README lists old domestic phone browsers, and anything other than Safari on iOS 11.0 to 14.2, as unsupported, though that list is struck through.
Can Recorder record two channels at once?
No. It is built for voice recording and supports mono only, with stereo unadapted. Very long recordings are handled through the realtime onProcess callback, which cleans up and releases memory while it runs.
How do I play a recording made with Recorder?
For an uploaded file, assign its link to audio.src on a normal Audio tag. For a local blob, create a local link with URL.createObjectURL for audio.src, or assign the blob straight to audio.srcObject, which has lower compatibility. Realtime fragments play through the bundled BufferStreamPlayer plugin.
Does Recorder work inside a WeChat mini program?
Yes. The RecordApp sample under app-support-sample records directly in WeChat mini programs and uni-app, and the repository ships mini program and uni-app source alongside an Android demo APK and iOS source you compile yourself.
Is there an npm package for Recorder?
The project links recorder-core on npm, plus JsDelivr and unpkg CDN copies of the GitHub repository. The two minified files in the repository are recorder.mp3.min.js at 150kb and recorder.wav.min.js at 25kb, and the licence is MIT.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/xiangyuecn-recorder)Star history chart for your README
[](https://hysenlabs.com/projects/xiangyuecn-recorder)Was this useful?