multiple-police-situations/public/cw/player/cmstalk.js

235 lines
8.1 KiB
JavaScript
Raw Normal View History

2024-08-05 16:43:08 +08:00
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 =
"" +
'<div class="waitDialog" style="z-index:99999;width:100%;height:100%;top:0;left:0;position:fixed;background:rgba(0,0,0,0.3);">' +
'<div style="display:flex;height:100%;align-items:center;">' +
'<div style="flex:1;"></div>' +
'<div style="width:240px;background:#fff;padding:15px 20px;border-radius: 10px;">' +
'<div style="padding-bottom:10px;">录音功能需要麦克风权限,请允许;如果未看到任何请求,请点击忽略~</div>' +
'<div style="text-align:center;"><a onclick="waitDialogClick()" style="color:#0B1">忽略</a></div>' +
"</div>" +
'<div style="flex:1;"></div>' +
"</div>" +
"</div>"
}
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("打开失败:权限请求被忽略,<span style='color:#f00'>用户主动点击的弹窗</span>", 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
}