微信JSSDK录音的一些bug

时间:2025-03-23 08:06:13

UPDATE: 这篇博文已经过期, 新的BUG总结请看微信JSSDK与录音相关的坑

微信JSSDK有不少坑, 最近做一个webapp, 用到了其中的录音功能, 发现不少问题, 总结一下:


当你调用startRecordstopRecord的时间间隔过于短时, stopRecord调用会失败, 但是不会触发success, failcomplete中的任何一个Handler, 导致UI卡住.

我的解决方法是: startRecord调用成功后500ms才可以调用stopRecord, 如果在500ms之内就执行了endRecord, 则判定为过早的endRecord, 执行failHandler, 随后每隔300ms调用一次endRecord, 直至endRecord调用成功.

function delayedStopRecord(options) {
stopRecord(options);
setTimeout(function () {
if (!self.canStartRecord) {
delayedStopRecord(options);
}
}, 300);
} self.startRecord = function (options) {
if (!self.canStartRecord) return;
options.success = options.success || $.noop;
options.fail = options.fail || $.noop;
options.complete = options.complete || $.noop;
self.canStartRecord = false;
self.canStopRecord = false;
var s1 = options.success;
options.success = function () {
s1();
setTimeout(function () {
self.canStopRecord = true;
}, 500);
}
var fail = options.fail;
options.fail = function (res) {
fail();
self.canStartRecord = true;
}
var s2 = options.success;
options.success = function () {
s2();
wx.onVoiceRecordEnd({
complete: options.onRecordTimeout
});
}
wx.startRecord(options);
} self.endRecord = function (options) {
options.success = options.success || $.noop;
options.fail = options.fail || $.noop;
options.complete = options.complete || $.noop;
var complete = options.complete;
options.complete = function () {
complete();
self.canStartRecord = true;
}
if (!self.canStopRecord) {
// Fix for too short stop record call failure.
// Can only stop record after 500 ms. Before 500ms, it's a premature endRecord call.
// For a premature endRecord call, try stop record every 300ms.
options.fail({ errMsg: 'stopRecord:tooshort' }); // Manually call failHandler.
options.abort = true;
delayedStopRecord(options);
} else {
stopRecord(options);
}
} function init() {
// Initialize flags.
self.canStartRecord = true; // True if this is the first call or the last stopRecord succeeded.
self.canStopRecord = false;
}

其中stopRecord函数封装了wx.stopRecordwx.uploadVoice, init是viewModel的初始化函数.


的确感受到了写作的好处, 在这里这段代码的过程中我还调整了代码的位置让代码的逻辑更加清晰了. 继续加油!


其他发现的一些bug, 暂时还没解决.

iPhone:

录音中按home返回主菜单, 录音中断, 回到微信, 此时endRecord会失败因为并没有在录音, 需要调用startRecord.

Android:

录音中按home返回主菜单, 录音继续, 回到微信可以正常endRecord

iPhone:

录音中关闭webapp, 录音结束, 回到webapp可以正常启动录音.

Android:

录音中关闭webapp, 录音继续, 回到webapp调用startRecord会失败提示recording.

iPhone:

录音中刷新webapp, 无法调用startRecord.

Android:

没有刷新按钮所以没这个问题.