# AMR Recorder
[](https://www.npmjs.com/package/benz-amr-recorder)
[](https://www.npmjs.com/package/benz-amr-recorder)
[](https://gitHub.com/BenzLeung/benz-amr-recorder/BenzAMRRecorder.min.js)
[](https://gitHub.com/BenzLeung/benz-amr-recorder/BenzAMRRecorder.min.js)
Play, record, reformat AMR audio, in pure Javascript, without any server.
This project is based on [amr.js](https://github.com/jpemartins/amr.js) and [RecorderJs](https://github.com/jergason/Recorderjs).
NOTE: Since amr.js is used for encoding and decoding, the js file is close to 500 KB (minified, no gzipped), please consider before use.
## Feature
- Simple API for playing and recording AMR audio.
- Supported url or blob (e.g. ``) to initialize AMR.
- Supported reformat audio which browser is supported (such as MP3 or OGG) to AMR audio.
- AMR that is encoded could be downloaded, without any server.
## Demo
[demo-en.html](https://benzleung.github.io/benz-amr-recorder/demo-en.html)
## Browser Compatibility
For the latest browser compatibility, please refer to [Can I Use](https://caniuse.com/#feat=audio-api).
- Play only: [https://caniuse.com/#feat=audio-api](https://caniuse.com/#feat=audio-api)
- Play + Record: [https://caniuse.com/#feat=stream](https://caniuse.com/#feat=stream)
## Setup
Load the JS file directly:
```html
```
OR use npm:
[](https://www.npmjs.com/package/benz-amr-recorder)
```
npm install benz-amr-recorder
```
```javascript
var BenzAMRRecorder = require('benz-amr-recorder');
```
## Usage
**Note:** It is recommended to bind the `initWithXXX()` or `play()` methods to a user event (eg `click`, `touchstart`). Because almost all mobile devices (and the desktop version of Chrome 70+) prohibit JavaScript from playing audio automatically. reference:
- [https://webkit.org/blog/6784/new-video-policies-for-ios/](https://webkit.org/blog/6784/new-video-policies-for-ios/)
- [https://developers.google.com/web/updates/2017/09/autoplay-policy-changes](https://developers.google.com/web/updates/2017/09/autoplay-policy-changes)
Play an AMR:
```javascript
var amr = new BenzAMRRecorder();
amr.initWithUrl('path/to/voice.amr').then(function() {
amr.play();
});
amr.onEnded(function() {
alert('play ended');
})
```
Play a local file:
```html
```
```javascript
var amr = new BenzAMRRecorder();
var amrFileObj = document.getElementById('amr-file');
amrFileObj.onchange = function() {
amr.initWithBlob(this.files[0]).then(function() {
amr.play();
});
}
```
Record AMR:
```javascript
var amrRec = new BenzAMRRecorder();
amrRec.initWithRecord().then(function() {
amrRec.startRecord();
});
```
Download AMR:
```javascript
window.location.href = window.URL.createObjectURL(amr.getBlob());
```
Reformat MP3 to AMR (Need browser support MP3 format):
```javascript
var amrFromMp3 = new BenzAMRRecorder();
amrFromMp3.initWithUrl('path/to/file.mp3').then(function() {
// Download the AMR file
window.location.href = window.URL.createObjectURL(amrFromMp3.getBlob());
})
```
## API
#### Initialize
```javascript
/**
* If AMR was initialized
* @return {boolean}
*/
amr.isInit();
```
```javascript
/**
* Init with Float32Array
* @param {Float32Array} array
* @return {Promise}
*/
amr.initWithArrayBuffer(array);
```
```javascript
/**
* Init with Blob object ( )
* @param {Blob} blob
* @return {Promise}
*/
amr.initWithBlob(blob);
```
```javascript
/**
* Init with URL
* @param {string} url
* @return {Promise}
*/
amr.initWithUrl(url);
```
```javascript
/**
* Initialize record
* @return {Promise}
*/
amr.initWithRecord();
```
#### Event listeners
**Notice: They will NOT add the event listener. They simply cover the old listener only.**
```javascript
/**
* On play
* @param {Function | null} fn
*/
amr.onPlay(function() {
console.log('play');
});
```
```javascript
/**
* On stop (Include onEnded)
* @param {Function | null} fn
*/
amr.onStop(function() {
console.log('stop playing');
});
```
```javascript
/**
* On pause
* @param {Function | null} fn
*/
amr.onPause(function() {
console.log('pause');
});
```
```javascript
/**
* On resume (form the paused state)
* @param {Function | null} fn
*/
amr.onResume(function() {
console.log('resume');
});
```
```javascript
/**
* on play ended
* @param {Function | null} fn
*/
amr.onEnded(function() {
console.log('play ended');
});
```
```javascript
/**
* on play to end and automatically ended
* @param {Function | null} fn
*/
amr.onAutoEnded(function() {
console.log('play automatically ended');
});
```
```javascript
/**
* on start record
* @param {Function | null} fn
*/
amr.onStartRecord(function() {
console.log('start record');
});
```
```javascript
/**
* on finish record
* @param {Function | null} fn
*/
amr.onFinishRecord(function() {
console.log('finish record');
});
```
#### Playing controls
```javascript
/**
* play (ignore the paused state)
* @param {number?} startTime - specify the start position (in seconds, float number, optional)
*/
amr.play();
```
```javascript
/**
* stop
*/
amr.stop();
```
```javascript
/**
* pause
* @since 1.1.0
*/
amr.pause();
```
```javascript
/**
* resume from the paused state
* @since 1.1.0
*/
amr.resume();
```
```javascript
/**
* Integrate `play()` and `resume()`, if it is paused, continue, otherwise play from the beginning
* @since 1.1.0
*/
amr.playOrResume();
```
```javascript
/**
* Integrate `resume()` and `pause()` to toggle the pause state
* @since 1.1.0
*/
amr.pauseOrResume();
```
```javascript
/**
* Integrate play() , resume() , and pause()
* @since 1.1.0
*/
amr.playOrPauseOrResume();
```
```javascript
/**
* Jump to the specified position of the audio, it will not change the playback status (if it is stopped, it is equivalent to `play(time)`)
* @since 1.1.0
* @param {Number} time the specified position(in seconds, float number)
*/
amr.setPosition(12.34);
```
```javascript
/**
* Get the current playback position (in seconds)
* @since 1.1.0
* @return {Number} position, in seconds, float number
*/
amr.getCurrentPosition();
```
```javascript
/**
* If AMR was playing
* @return {boolean}
*/
amr.isPlaying();
```
```javascript
/**
* If audio was paused
* @since 1.1.0
* @return {boolean}
*/
amr.isPaused();
```
#### Recording controls
```javascript
/**
* Start record
*/
amr.startRecord();
```
```javascript
/**
* Finish record, and then reformat to AMR
* @return {Promise}
*/
amr.finishRecord();
```
```javascript
/**
* Cancel record
*/
amr.cancelRecord();
```
```javascript
/**
* If it was recording
* @return {boolean}
*/
amr.isRecording();
```
#### Other APIs
```javascript
/**
* Get duration of the AMR (by second)
* @return {Number}
*/
amr.getDuration();
```
```javascript
/**
* Get the Blob object of the AMR file (Use for download)
* @return {Blob}
*/
amr.getBlob();
```
```javascript
/**
* Release AMR data and PCM data, stop recording, remove all event listeners
* @since 1.1.4
*/
amr.destroy();
```
```javascript
/**
* Determine if the browser supports playback
* Note that this is a static method
* @since 1.1.0
* @return {boolean}
*/
BenzAMRRecorder.isPlaySupported();
// NOT `amr.isPlaySupported();`
```
```javascript
/**
* Determine if the browser supports recording
* Note that this is a static method
* @since 1.1.0
* @return {boolean}
*/
BenzAMRRecorder.isRecordSupported();
// NOT `amr.isRecordSupported();`
```
# Todo list
- [x] ~~Encode & decode with WebWorker.~~(v1.0.9)
- [x] ~~Pause playback.~~(v1.1.0)
- [ ] Pause recording.
- [x] ~~Playing progress and jump to a position.~~(v1.1.0)
- [x] ~~Browser compatibility check API ([#9](https://github.com/BenzLeung/benz-amr-recorder/issues/9) [#11](https://github.com/BenzLeung/benz-amr-recorder/issues/11)).~~(v1.1.0)
# License
MIT.