@da-web/js-audio-recorder
Version:
js audio recorder plugin
148 lines (124 loc) • 3.62 kB
text/typescript
import { throwError } from '../exception/exception'
declare let window: any;
let source: any = null;
let playTime: number = 0; // 相对时间,记录暂停位置
let playStamp: number = 0; // 开始或暂停后开始的时间戳(绝对)
let context: any = null;
let analyser: any = null;
let audioData: any = null;
// let hasInit: boolean = false; // 是否已经初始化了
let isPaused: boolean = false;
let totalTime: number = 0;
let endplayFn: any = function() {};
/**
* 初始化
*/
function init(): void {
context = new (window.AudioContext || window.webkitAudioContext)();
analyser = context.createAnalyser();
analyser.fftSize = 2048; // 表示存储频域的大小
}
/**
* play
* @returns {Promise<{}>}
*/
function playAudio(): Promise<{}> {
isPaused = false;
return context.decodeAudioData(audioData.slice(0), buffer => {
source = context.createBufferSource();
// 播放结束的事件绑定
source.onended = () => {
if (!isPaused) { // 暂停的时候也会触发该事件
// 计算音频总时长
totalTime = context.currentTime - playStamp + playTime;
endplayFn();
}
}
// 设置数据
source.buffer = buffer;
// connect到分析器,还是用录音的,因为播放时不能录音的
source.connect(analyser);
analyser.connect(context.destination);
source.start(0, playTime);
// 记录当前的时间戳,以备暂停时使用
playStamp = context.currentTime;
}, function(e) {
throwError(e);
});
}
// 销毁source, 由于 decodeAudioData 产生的source每次停止后就不能使用,所以暂停也意味着销毁,下次需重新启动。
function destroySource() {
if (source) {
source.stop();
source = null;
}
}
export default class Player {
/**
* play record
* @static
* @param {ArrayBuffer} arraybuffer
* @memberof Player
*/
static play(arraybuffer): Promise<{}> {
if (!context) {
// 第一次播放要初始化
init();
}
this.stopPlay();
// 缓存播放数据
audioData = arraybuffer;
totalTime = 0;
return playAudio();
}
/**
* 暂停播放录音
* @memberof Player
*/
static pausePlay(): void {
destroySource();
// 多次暂停需要累加
playTime += context.currentTime - playStamp;
isPaused = true;
}
/**
* 恢复播放录音
* @memberof Player
*/
static resumePlay(): Promise<{}> {
return playAudio();
}
/**
* 停止播放
* @memberof Player
*/
static stopPlay() {
playTime = 0;
audioData = null;
destroySource();
}
static destroyPlay() {
this.stopPlay();
}
static getAnalyseData() {
let dataArray = new Uint8Array(analyser.frequencyBinCount);
// 将数据拷贝到dataArray中。
analyser.getByteTimeDomainData(dataArray);
return dataArray;
}
/**
* 增加录音播放完成的事件绑定
*
* @static
* @param {*} [fn=function() {}]
* @memberof Player
*/
static addPlayEnd(fn: any = function() {}) {
endplayFn = fn;
}
// 获取已经播放的时长
static getPlayTime(): number {
let pTime = isPaused ? playTime : context.currentTime - playStamp + playTime;
return totalTime || pTime;
}
}