1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
(function (exports) {
//公共方法
var Util = {
//初始化
init: function () {
navigator.getUserMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia;
window.AudioContext = window.AudioContext ||
window.webkitAudioContext;
},
//日志
log: function () {
console.log.apply(console, arguments);
}
};
//构造函数
var Recorder = function (config) {
var _this = this;
config = config || {}; //初始化配置对象
config.sampleRate = config.sampleRate || 44100; //采样频率,默认为44100Hz(标准MP3采样率)
config.bitRate = config.bitRate || 128; //比特率,默认为128kbps(标准MP3质量)
Util.init();
if (navigator.getUserMedia) {
navigator.getUserMedia({
audio: true //配置对象
},
function (stream) { //成功回调
var context = new AudioContext(),
microphone = context.createMediaStreamSource(stream), //媒体流音频源
processor = context.createScriptProcessor(16384, 1, 1), //js音频处理器
successCallback, errorCallback;
config.sampleRate = context.sampleRate;
processor.onaudioprocess = function (event) {
//监听音频录制过程
var array = event.inputBuffer.getChannelData(0);
realTimeWorker.postMessage({cmd: 'encode', buf: array});
};
var realTimeWorker = new Worker('assets/libs/audio-recorder/worker.js'); //开启后台线程
_this.worker = realTimeWorker;
realTimeWorker.onmessage = function (e) { //主线程监听后台线程,实时通信
switch (e.data.cmd) {
case 'init':
Util.log('初始化成功');
if (config.success) {
config.success();
}
break;
case 'end':
if (successCallback) {
var blob = new Blob(e.data.buf, {type: 'audio/mp3'});
successCallback(blob);
Util.log('MP3大小:' + blob.size + '%cB', 'color:#0000EE');
}
break;
case 'error':
Util.log('错误信息:' + e.data.error);
if (errorCallback) {
errorCallback(e.data.error);
}
break;
default:
Util.log('未知信息:' + e.data);
}
};
//接口列表
//开始录音
_this.start = function () {
if (processor && microphone) {
microphone.connect(processor);
processor.connect(context.destination);
Util.log('开始录音');
}
};
//结束录音
_this.stop = function () {
if (processor && microphone) {
microphone.disconnect();
processor.disconnect();
Util.log('录音结束');
}
};
//获取blob格式录音文件
_this.getBlob = function (onSuccess, onError) {
successCallback = onSuccess;
errorCallback = onError;
realTimeWorker.postMessage({cmd: 'finish'});
};
realTimeWorker.postMessage({
cmd: 'init',
config: {
sampleRate: config.sampleRate,
bitRate: config.bitRate
}
});
},
function (error) { //失败回调
var msg;
switch (error.code || error.name) {
case 'PermissionDeniedError':
case 'PERMISSION_DENIED':
case 'NotAllowedError':
msg = '用户拒绝访问麦克风';
break;
case 'NOT_SUPPORTED_ERROR':
case 'NotSupportedError':
msg = '浏览器不支持麦克风';
break;
case 'MANDATORY_UNSATISFIED_ERROR':
case 'MandatoryUnsatisfiedError':
msg = '找不到麦克风设备';
break;
default:
msg = '无法打开麦克风,异常信息:' + (error.code || error.name);
break;
}
Util.log(msg);
if (config.error) {
config.error(msg);
}
});
} else {
Util.log('当前浏览器不支持录音功能');
if (config.fix) {
config.fix('当前浏览器不支持录音功能');
}
}
};
//模块接口
exports.Recorder = Recorder;
})(window);