function CmsTalk() {
this.wasmLoaded = false;
this.logger = new Logger("CmsTalk");
this.urlBufferBuffer = null
this.audioCache = null
this.localAudioStream = null
this.ws = null
this.mediaRecorder = null
this.audioBuffer = null
this.rec = null
// this.recBlob = null;
/**调用open打开录音请求好录音权限**/
this.RecorderOpen()
}
CmsTalk.prototype.RecorderOpen = function () {
//recOpen我们可以选择性的弹一个对话框:为了防止移动端浏览器存在第三种情况:用户忽略,并且(或者国产系统UC系)浏览器没有任何回调
var showDialog = function () {
if (!/mobile/i.test(navigator.userAgent)) {
return //只在移动端开启没有权限请求的检测
}
dialogCancel()
//显示弹框,应该使用自己的弹框方式
var div = document.createElement("div")
document.body.appendChild(div)
div.innerHTML =
"" +
'
' +
'
' +
'
' +
'
' +
'
录音功能需要麦克风权限,请允许;如果未看到任何请求,请点击忽略~
' +
'
' +
"
" +
'
' +
"
" +
"
"
}
var createDelayDialog = function () {
dialogInt = setTimeout(function () {
//定时8秒后打开弹窗,用于监测浏览器没有发起权限请求的情况,在open前放置定时器利于收到了回调能及时取消(不管open是同步还是异步回调的)
showDialog()
}, 8000)
}
var dialogInt
var dialogCancel = function () {
clearTimeout(dialogInt)
//关闭弹框,应该使用自己的弹框方式
var elems = document.querySelectorAll(".waitDialog")
for (var i = 0; i < elems.length; i++) {
elems[i].parentNode.removeChild(elems[i])
}
}
//recOpen弹框End
var formatMs = function (ms, all) {
var f = Math.floor(ms / 60000),
m = Math.floor(ms / 1000) % 60
var s =
(all || f > 0 ? (f < 10 ? "0" : "") + f + ":" : "") +
(all || f > 0 || m > 0 ? ("0" + m).substr(-2) + "″" : "") +
("00" + (ms % 1000)).substr(-3)
return s
}
// var recOpen = function () {//一般在显示出录音按钮或相关的录音界面时进行此方法调用,后面用户点击开始录音时就能畅通无阻了
this.newRec = Recorder({
type: "pcm", sampleRate: 8000, bitRate: 16 //mp3格式,指定采样率hz、比特率kbps,其他参数使用默认配置;注意:是数字的参数必须提供数字,不要用字符串;需要使用的type类型,需提前把格式支持文件加载进来,比如使用wav格式需要提前加载wav.js编码引擎
, onProcess: function (buffers, powerLevel, bufferDuration, bufferSampleRate, newBufferIdx, asyncEnd) {
newBufferIdx = 0
var newChunkInfo = Recorder.SampleData(buffers, 48000, 8000, this.prevChunkInfo);
this.sendAudioData(newChunkInfo.data)
this.prevChunkInfo = newChunkInfo
for (let index = buffers.length - 1; index >= 0; index--) {
buffers[index] = null;
}
}.bind(this)
});
// createDelayDialog(); //我们可以选择性的弹一个对话框:为了防止移动端浏览器存在第三种情况:用户忽略,并且(或者国产系统UC系)浏览器没有任何回调,此处demo省略了弹窗的代码
window.waitDialogClick = function () {
dialogCancel();
console.log("打开失败:权限请求被忽略,用户主动点击的弹窗", 1);
};
// };
}
//打开麦克风授权获得相关资源
CmsTalk.prototype.open = function (callback) {
// dialogCancel(); //如果开启了弹框,此处需要取消
if (this.rec){
console.log("已打开录音设备,可以点击录制开始录音了", 2);
callback(null)
return
}
this.newRec.open(function () {
this.rec = this.newRec;
console.log("已打开录音设备,可以点击录制开始录音了", 2);
callback()
}.bind(this), function (msg, isUserNotAllow) {
//用户拒绝未授权或不支持
// dialogCancel(); //如果开启了弹框,此处需要取消
var log = (isUserNotAllow ? "UserNotAllow," : "") + "打开录音失败:" + msg;
console.log(log);
callback(log)
})
}
/**关闭录音,释放资源**/
CmsTalk.prototype.recClose = function () {
if (this.rec) {
this.rec.close();
this.rec = null
console.log("已关闭");
} else {
console.log("未打开录音", 1);
};
};
/**开始录音**/
CmsTalk.prototype.recStart = function () {//打开了录音后才能进行start、stop调用
this.prevChunkInfo = null
if (this.rec && Recorder.IsOpen()) {
// this.recBlob = null;
this.rec.start();
console.log("已开始录音...");
} else {
console.log("未打开录音", 1);
};
};
/**暂停录音**/
CmsTalk.prototype.recPause = function () {
if (this.rec && Recorder.IsOpen()) {
this.rec.pause();
} else {
console.log("未打开录音", 1);
};
};
/**恢复录音**/
CmsTalk.prototype.recResume = function () {
if (this.rec && Recorder.IsOpen()) {
this.rec.resume();
} else {
console.log("未打开录音", 1);
};
};
/**结束录音,得到音频文件**/
CmsTalk.prototype.recStop = function () {
if (!(this.rec && Recorder.IsOpen())) {
console.log("未打开录音", 1);
return;
};
this.rec.stop(null, null);
};
CmsTalk.prototype.startTalk = function (url, callback) {
this.open((err) => {
if (err) {
callback(err)
} else {
if (url.indexOf("http") != -1) {
//方式1,可手动修改talk-server对应的地址
this.ws = new WebSocket("ws://192.168.0.215:3000");
this.ws.onmessage = function (msg) {
console.log(msg);
};
this.ws.onopen = (ev) => {
console.log("open")
this.ws.send(url)
this.recStart()
if (callback)
callback(null)
}
}
else {
//方式2
this.ws = new WebSocket(url);
this.ws.onmessage = function (msg) {
console.log(msg);
};
this.ws.onopen = (ev) => {
console.log("open")
this.recStart()
if (callback)
callback(null)
}
}
}
})
}
CmsTalk.prototype.stopTalk = function () {
if (this.ws) {
this.ws.close();
this.ws = null
}
if (this.audioBuffer) {
delete this.audioBuffer
this.audioBuffer = null
}
this.recStop()
// this.recClose()
}
CmsTalk.prototype.sendAudioData = function (samples) {
var u8Data = alawmulaw.alaw.encode(samples);
if (!this.audioBuffer)
this.audioBuffer = new Uint8Array([])
var tmpBuffer = new Uint8Array(this.audioBuffer.byteLength + u8Data.byteLength)
tmpBuffer.set(this.audioBuffer, 0)
tmpBuffer.set(u8Data, this.audioBuffer.byteLength)
while (tmpBuffer.byteLength >= 480) {
var d480 = tmpBuffer.subarray(0, 480);
tmpBuffer = tmpBuffer.subarray(480);
console.log("reserve ", tmpBuffer.length)
if (this.ws)
this.ws.send(d480)
}
this.audioBuffer = tmpBuffer
}