基于amr.jsRecorderJs,最底部有线上demo代码
播放 AMR:

var amr = new BenzAMRRecorder();
amr.initWithUrl('path/to/voice.amr').then(function() {
  amr.play();
});
amr.onEnded(function() {
  alert('播放完毕');
})

播放本地文件:

<input type="file" id="amr-file" accept=".amr">
var amr = new BenzAMRRecorder();
var amrFileObj = document.getElementById('amr-file');
amrFileObj.onchange = function() {
  amr.initWithBlob(this.files[0]).then(function() {
    amr.play();
  });
}

录制 AMR:

var amrRec = new BenzAMRRecorder();
amrRec.initWithRecord().then(function() {
  amrRec.startRecord();
});

下载 AMR:

window.location.href = window.URL.createObjectURL(amr.getBlob());

把 MP3 转换成 AMR (需要浏览器原生支持 MP3):

var amrFromMp3 = new BenzAMRRecorder();
amrFromMp3.initWithUrl('path/to/file.mp3').then(function() {
  // 下载 amr 文件
  window.location.href = window.URL.createObjectURL(amrFromMp3.getBlob());
})

API:

/**
 * 是否已经初始化
 * @return {boolean}
 */
amr.isInit();

/**
 * 使用浮点数据初始化
 * @param {Float32Array} array
 * @return {Promise}
 */
amr.initWithArrayBuffer(array);

/**
 * 使用 Blob 对象初始化( <input type="file">)
 * @param {Blob} blob
 * @return {Promise}
 */
amr.initWithBlob(blob);

/**
 * 使用 url 初始化
 * @param {string} url
 * @return {Promise}
 */
amr.initWithUrl(url);

/**
 * 初始化录音
 * @return {Promise}
 */
amr.initWithRecord();

事件:
注意:事件不会叠加,也就是说,新注册的事件将覆盖掉旧的事件。

/**
 * 播放
 * @param {Function} fn
 */
amr.onPlay(function() {
  console.log('开始播放');
});

/**
 * 停止(包括播放结束)
 * @param {Function} fn
 */
amr.onStop(function() {
  console.log('停止播放');
});

/**
 * 暂停
 * @param {Function} fn
 */
amr.onPause(function() {
  console.log('暂停');
});

/**
 * (暂停状态中)继续播放
 * @param {Function} fn
 */
amr.onResume(function() {
  console.log('继续播放');
});

/**
 * 播放结束
 * @param {Function} fn
 */
amr.onEnded(function() {
  console.log('播放结束');
});

/**
 * 播放到结尾自动结束
 * @param {Function} fn
 */
amr.onAutoEnded(function() {
  console.log('播放自动结束');
});

/**
 * 开始录音
 * @param {Function} fn
 */
amr.onStartRecord(function() {
  console.log('开始录音');
});

/**
 * 结束录音
 * @param {Function} fn
 */
amr.onFinishRecord(function() {
  console.log('结束录音');
});

播放控制

/**
 * 播放(无视暂停状态)
 * @param {number?} startTime 可指定播放开始位置(秒,浮点数,可选)
 */
amr.play();

/**
 * 停止
 */
amr.stop();

/**
 * 暂停
 * @since 1.1.0
 */
amr.pause();

/**
 * 从暂停状态中继续播放
 * @since 1.1.0
 */
amr.resume();

/**
 * 整合 play() 和 resume(),若在暂停状态则继续,否则从头播放
 * @since 1.1.0
 */
amr.playOrResume();

/**
 * 整合 resume() 和 pause(),切换暂停状态
 * @since 1.1.0
 */
amr.pauseOrResume();

/**
 * 整合 play() 和 resume() 和 pause()
 * @since 1.1.0
 */
amr.playOrPauseOrResume();

/**
 * 跳转到音频指定位置,不改变播放状态(若停止状态则等同于 `play(time)`) 
 * @since 1.1.0
 * @param {Number} time 指定位置(秒,浮点数)
 */
amr.setPosition(12.34);

/**
 * 获取当前播放位置(秒) 
 * @since 1.1.0
 * @return {Number} 位置,秒,浮点数
 */
amr.getCurrentPosition();

/**
 * 是否正在播放
 * @return {boolean}
 */
amr.isPlaying();

/**
 * 是否暂停中
 * @since 1.1.0
 * @return {boolean}
 */
amr.isPaused();

录音控制:

/**
 * 开始录音
 */
amr.startRecord();

/**
 * 结束录音,并把录制的音频转换成 AMR
 * @return {Promise}
 */
amr.finishRecord();

/**
 * 放弃录音
 */
amr.cancelRecord();

/**
 * 是否正在录音
 * @return {boolean}
 */
amr.isRecording();

其他

/**
 * 获取音频的时间长度(单位:秒)
 * @return {Number}
 */
amr.getDuration();

/**
 * 获取 AMR 文件的 Blob 对象(用于下载文件)
 * @return {Blob}
 */
amr.getBlob();

/**
 * 判断浏览器是否支持播放
 * 注意这是静态(static)方法
 * @since 1.1.0
 * @return {boolean}
 */
BenzAMRRecorder.isPlaySupported();
// 不是 amr.isPlaySupported();

/**
 * 判断浏览器是否支持录音
 * 注意这是静态(static)方法
 * @since 1.1.0
 * @return {boolean}
 */
BenzAMRRecorder.isRecordSupported();
// 不是 amr.isRecordSupported();

Demo:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width">
    <title>AMR_test</title>
    <style>
        #fixed{
            position: fixed;
            top: 0;
            right: 0;
            bottom: 0;
            left: 0;
            z-index: 9;
            background: rgba(0,0,0,0.8);
            color: #fff;
            font-size: 40px;
            animation: huxi .3s ease infinite alternate;
            transform-origin: top left;
        }
        @keyframes huxi {
            from {
                transform: scale(1);
            }
            to {
                transform: scale(1.02);
            }

        }
    </style>
</head>
<body>
<div id="fixed">加载中,请稍等...</div>
<h1>AMR 录音机 Demo</h1>
<h2>解码、播放</h2>
<div id="player-amr">
    <p>
        加载演示文件:<button id="amr-load">加载、解码</button>
        <a href="./1.amr">下载演示文件:mario.amr</a>
    </p>
    <p>
        加载本地文件:<input type="file" id="amr-file" accept=".amr">(不会上传到任何服务器)
    </p>
    <p>
        <button id="amr-play" disabled>播放</button>
        <button id="amr-stop" disabled>停止</button>
        <input id="amr-progress" type="range" min="0" max="1" step="any" value="0" disabled>
        <label for="amr-progress">
            <span id="amr-cur">0'</span>
            <span>/</span>
            <span id="amr-duration">0'</span>
        </label>
    </p>
</div>
<h2>录音、编码</h2>
<div id="recorder-amr">
    <p>
        <button id="amr-record">开始录音</button>(不会上传到任何服务器)
    </p>
    <p>
        <button id="amr-play-record" disabled>播放录音</button>
        <a href="#" id="amr-down-record"><!--下载录音amr文件--></a>
        <span id="amr-record-duration">0'</span>
    </p>
</div>

<script>
    var _doc=document.getElementsByTagName('head')[0];
    var script=document.createElement('script');
    script.setAttribute('type','text/javascript');
    script.setAttribute('src','./BenzAMRRecorder.min.js');
    _doc.appendChild(script);

    function E(selector) {
        return document.querySelector(selector);
    }

    script.onload = function () {
        
        (function () {
            function E(selector) {
                return document.querySelector(selector);
            }
            E('#fixed').style.display = 'none';
            /**** 解码、播放 ****/
        
            var amr;
        
            var loadDemoBtn = E('#amr-load');
            var loadAmrFile = E('#amr-file');
            var playBtn = E('#amr-play');
            var stopBtn = E('#amr-stop');
            var progressCtrl = E('#amr-progress');
            var isDragging = false;
            var cur = E('#amr-cur');
            var duration = E('#amr-duration');
        
            setInterval(function () {
                if (amr) {
                    cur.innerHTML = amr.getCurrentPosition().toFixed(2) + '\'';
                    if (!isDragging) {
                        progressCtrl.value = amr.getCurrentPosition().toFixed(2);
                    }
                } else {
                    cur.innerHTML = '0\'';
                }
            }, 10);
        
            loadDemoBtn.onclick = function() {
                amr = new BenzAMRRecorder();
                loadDemoBtn.setAttribute('disabled', true);
                loadAmrFile.setAttribute('disabled', true);
                playBtn.setAttribute('disabled', true);
                stopBtn.setAttribute('disabled', true);
                progressCtrl.setAttribute('disabled', true);
                amr.initWithUrl('./1.amr').then(function () {
                    loadDemoBtn.removeAttribute('disabled');
                    loadAmrFile.removeAttribute('disabled');
                    playBtn.removeAttribute('disabled');
                    stopBtn.removeAttribute('disabled');
                    progressCtrl.removeAttribute('disabled');
                    progressCtrl.setAttribute('max', amr.getDuration());
                    duration.innerHTML = amr.getDuration().toFixed(2) + '\'';
                });
            
                // 绑定事件
                amr.onPlay(function () {
                    console.log('Event: play');
                    playBtn.innerHTML = '暂停';
                });
                amr.onStop(function () {
                    console.log('Event: stop');
                    playBtn.innerHTML = '播放';
                });
                amr.onPause(function () {
                    console.log('Event: pause');
                    playBtn.innerHTML = '继续';
                });
                amr.onResume(function () {
                    console.log('Event: resume');
                    playBtn.innerHTML = '暂停';
                });
                amr.onEnded(function () {
                    console.log('Event: ended');
                    playBtn.innerHTML = '播放';
                });
                amr.onAutoEnded(function () {
                    console.log('Event: autoEnded');
                });
                amr.onStartRecord(function () {
                    console.log('Event: startRecord');
                });
                amr.onFinishRecord(function () {
                    console.log('Event: finishRecord');
                });
                amr.onCancelRecord(function () {
                    console.log('Event: cancelRecord');
                });
            };
        
            playBtn.onclick = function () {
                amr.playOrPauseOrResume();
            };
        
            stopBtn.onclick = function () {
                amr.stop();
            };
        
            progressCtrl.onmousedown = function () {
                isDragging = true;
            };
            progressCtrl.onmouseup = function () {
                isDragging = false;
            };
            progressCtrl.onchange = function (e) {
                amr.setPosition(e.target.value);
            };
        
            loadAmrFile.onchange = function() {
                amr = new BenzAMRRecorder();
                loadDemoBtn.setAttribute('disabled', true);
                loadAmrFile.setAttribute('disabled', true);
                playBtn.setAttribute('disabled', true);
                amr.initWithBlob(this.files[0]).then(function () {
                    loadDemoBtn.removeAttribute('disabled');
                    loadAmrFile.removeAttribute('disabled');
                    playBtn.removeAttribute('disabled');
                    duration.innerHTML = amr.getDuration().toFixed(2) + '\'';
                });
            
                // 绑定事件
                amr.onPlay(function () {
                    console.log('Event: play');
                    playBtn.innerHTML = '停止';
                });
                amr.onStop(function () {
                    console.log('Event: stop');
                    playBtn.innerHTML = '播放';
                });
                amr.onEnded(function () {
                    console.log('Event: ended');
                    playBtn.innerHTML = '播放';
                });
                amr.onAutoEnded(function () {
                    console.log('Event: autoEnded');
                });
                amr.onStartRecord(function () {
                    console.log('Event: startRecord');
                });
                amr.onFinishRecord(function () {
                    console.log('Event: finishRecord');
                });
                amr.onCancelRecord(function () {
                    console.log('Event: cancelRecord');
                });
            };
        
            /***** 录音、编码 *****/
        
            var amrForRecorder;
        
            var recordBtn = E('#amr-record');
            var playRecordBtn = E('#amr-play-record');
            var downRecordLink = E('#amr-down-record');
            var recordDuration = E('#amr-record-duration');
        
            recordBtn.onclick = function () {
                navigator.mediaDevices.getUserMedia({ audio: true, video: true })
                  .then(function(stream) {
                      /* 使用这个stream stream */
                  })
                  .catch(function(err) {
                      /* 处理error */
                  });
                if (amrForRecorder && amrForRecorder.isRecording()) {
                    recordBtn.innerHTML = '开始录音';
                    playRecordBtn.removeAttribute('disabled');
                    amrForRecorder.finishRecord().then(() => {
                        downRecordLink.href = window.URL.createObjectURL(amrForRecorder.getBlob());
                        downRecordLink.innerHTML = '下载录音amr文件';
                        recordDuration.innerHTML = amrForRecorder.getDuration().toFixed(2) + '\'';
                    });
                } else {
                    recordBtn.innerHTML = '停止录音';
                    playRecordBtn.setAttribute('disabled', true);
                    amrForRecorder = new BenzAMRRecorder();
                    amrForRecorder.initWithRecord().then(() => {
                        amrForRecorder.startRecord();
                    }).catch(function(e) {
                        alert(e.message || e.name || JSON.stringify(e));
                    });
                
                    // 绑定事件
                    amrForRecorder.onPlay(function () {
                        console.log('Recorder Event: play');
                        playRecordBtn.innerHTML = '停止播放';
                    });
                    amrForRecorder.onStop(function () {
                        console.log('Recorder Event: stop');
                        playRecordBtn.innerHTML = '播放录音';
                    });
                    amrForRecorder.onEnded(function () {
                        console.log('Recorder Event: ended');
                        playRecordBtn.innerHTML = '播放录音';
                    });
                    amrForRecorder.onAutoEnded(function () {
                        console.log('Recorder Event: autoEnded');
                    });
                    amrForRecorder.onStartRecord(function () {
                        console.log('Recorder Event: startRecord');
                        recordBtn.innerHTML = '停止录音';
                    });
                    amrForRecorder.onFinishRecord(function () {
                        console.log('Recorder Event: finishRecord');
                        recordBtn.innerHTML = '开始录音';
                    });
                    amrForRecorder.onCancelRecord(function () {
                        console.log('Recorder Event: cancelRecord');
                        recordBtn.innerHTML = '开始录音';
                    });
                }
            };
        
            playRecordBtn.onclick = function () {
                if (amrForRecorder.isPlaying()) {
                    amrForRecorder.stop();
                } else {
                    amrForRecorder.play();
                }
            };
        })();
    }
</script>
</body>
</html>

戳这里看效果
扫码手机看效果:
在这里插入图片描述

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐