1: ①:需求 : 边说话边翻译成汉字
②:需求效果图(阿里云的示例,无代码) :
2: 实现流程: 点击话筒 初始化webSocket , 调起 麦克风 , 获取语音 实时发送, 拿到返回的 汉字处理成数组遍历展示出来.
3:用到的主要技术: webSocket, js-audio-recorder
4:遇到的问题:
①:本地运行代码, 调不起麦克风, 一直报 getUserMedia 找不到 ! 如图:
原因: 浏览器不支持http开头的路径,认为这个路径不安全,只支持file:,https:,http://localhost
解决办法:浏览器地址栏输入: chrome://flags/#unsafely-treat-insecure-origin-as-secure按下图配置:
②: webSocket 一直会断联 ! 目前我遇到的原因有两个:
a: 刚连上就直接断联, 是因为没有实时语音发送过去
b: 链接一段时间 ,也返回了 语音转换后的汉字, 但 不到 1分钟 又断联了 , 原因是: 语音发送太快,语音文件太大 .
各种试, 自己没解决掉这种问题, 因为js-audio-recorder插件没提供 截取音频 合并音频等方法.
最后是 后端 修改了 js-audio-recorder 的底层 recorder.js文件,然后 用引入的方式 放到本地用
(修改的逻辑就是 : 不把 语音整段(会议开始---->会议结束)发送过去, 看底层代码,可以看出 他是把 每段录制到的语音整合成一个文件发过去的,这样文件会过大,导致webSocket 自己断联, 直接修改掉他整合的代码, 每次都给清空掉, 可自行看代码)
如下: (可以拷去,按需修改)
/*!
*
* js-audio-recorder - js audio recorder plugin
*
* @version v1.0.7
* @homepage https://github.com/2fps/recorder
* @author 2fps (https://www.zhuyuntao.cn)
* @license MIT
*
*/
!function (t, e) {
"object" == typeof exports && "object" == typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define([], e) : "object" == typeof exports ? exports.Recorder = e() : t.Recorder = e()
}
(this, function () {
return function (t) {
var e = {
};
function n(i) {
if (e[i])
return e[i].exports;
var o = e[i] = {
i: i,
l: !1,
exports: {
}
};
return t[i].call(o.exports, o, o.exports, n),
o.l = !0,
o.exports
}
return n.m = t,
n.c = e,
n.d = function (t, e, i) {
n.o(t, e) || Object.defineProperty(t, e, {
enumerable: !0,
get: i
})
},
n.r = function (t) {
"undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(t, Symbol.toStringTag, {
value: "Module"
}),
Object.defineProperty(t, "__esModule", {
value: !0
})
},
n.t = function (t, e) {
if (1 & e && (t = n(t)), 8 & e)
return t;
if (4 & e && "object" == typeof t && t && t.__esModule)
return t;
var i = Object.create(null);
if (n.r(i), Object.defineProperty(i, "default", {
enumerable: !0,
value: t
}), 2 & e && "string" != typeof t)
for (var o in t)
n.d(i, o, function (e) {
return t[e]
}
.bind(null, o));
return i
},
n.n = function (t) {
var e = t && t.__esModule ? function () {
return t.default
}
: function () {
return t
};
return n.d(e, "a", e),
e
},
n.o = function (t, e) {
return Object.prototype.hasOwnProperty.call(t, e)
},
n.p = "",
n(n.s = 1)
}
([function (t, e, n) {
"use strict";
function i(t, e, n) {
for (var i = 0; i < n.length; i++)
t.setUint8(e + i, n.charCodeAt(i))
}
Object.defineProperty(e, "__esModule", {
value: !0
}),
e.compress = function (t, e, n) {
for (var i = e / n, o = Math.max(i, 1), r = t.left, a = t.right, s = Math.floor((r.length + a.length) / i), u = new Float32Array(s), c = 0, l = 0; c < s; ) {
var f = Math.floor(l);
u[c] = r[f],
c++,
a.length && (u[c] = a[f], c++),
l += o
}
return u
},
e.encodePCM = function (t, e, n) {
void 0 === n && (n = !0);
var i = 0,
o = t.length * (e / 8),
r = new ArrayBuffer(o),
a = new DataView(r);
if (8 === e)
for (var s = 0; s < t.length; s++, i++) {
var u = (c = Math.max(-1, Math.min(1, t[s]))) < 0 ? 128 * c : 127 * c;
u = +u + 128,
a.setInt8(i, u)
}
else
for (s = 0; s < t.length; s++, i += 2) {
var c = Math.max(-1, Math.min(1, t[s]));
a.setInt16(i, c < 0 ? 32768 * c : 32767 * c, n)
}
return a
},
e.encodeWAV = function (t, e, n, o, r, a) {
void 0 === a && (a = !0);
var s = n > e ? e : n,
u = r,
c = new ArrayBuffer(44 + t.byteLength),
l = new DataView(c),
f = o,
p = 0;
i(l, p, "RIFF"),
p += 4,
l.setUint32(p, 36 + t.byteLength, a),
i(l, p += 4, "WAVE"),
i(l, p += 4, "fmt "),
p += 4,
l.setUint32(p, 16, a),
p += 4,
l.setUint16(p, 1, a),
p += 2,
l.setUint16(p, f, a),
p += 2,
l.setUint32(p, s, a),
p += 4,
l.setUint32(p, f * s * (u / 8), a),
p += 4,
l.setUint16(p, f * (u / 8), a),
p += 2,
l.setUint16(p, u, a),
i(l, p += 2, "data"),
p += 4,
l.setUint32(p, t.byteLength, a),
p += 4;
for (var d = 0; d < t.byteLength; )
l.setUint8(p, t.getUint8(d)), p++, d++;
return l
}
}, function (t, e, n) {
"use strict";
var i,
o = this && this.__extends || (i = function (t, e) {
return (i = Object.setPrototypeOf || {
__proto__: []
}
instanceof Array