Skip to content

Commit

Permalink
Android WebView中按住录音存在权限请求打断touch事件的问题的解决方案
Browse files Browse the repository at this point in the history
  • Loading branch information
xiangyuecn committed Sep 5, 2019
1 parent f7c5058 commit 8b91ce7
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 5 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,8 @@ IOS其他浏览器||

*2019-07-22*[#34](https://github.com/xiangyuecn/Recorder/issues/34)反馈研究后发现,问题一:macOS、IOS的Safari对连续调用录音(中途未调用close)是有问题的,但只要调用close后再重复录音就没有问题。问题二:IOS上如果录音之前先播放了任何Audio,录音过程将会变得很诡异,但如果先录音,就不存在此问题。chrome、firefox正常的很。目测这两个问题是非我等屌丝能够解决的,于是报告给苹果家程序员看看,因此发了个[帖子](https://forums.developer.apple.com/message/373108),顺手在`Feedback Assistant`提交了`bug report`,但好几天过去了没有任何回应(顺带给微软一个好评)。

*2019-09-05* 已知 [#46](https://github.com/xiangyuecn/Recorder/issues/46) `Android WebView`内调用getUserMedia方法发起授权请求时会打断touch事件,表现为触发了`touchcancel`事件,`touchend`事件始终不会触发,在做按住录音功能时应留意此问题。虽然`open`后一直不调用`close`可以规避此问题,但不建议这样做,每次录音后调用`close`兼容性更好,也更加友好;可以在每次`按住录音按钮`被按之前都重新进行一次`open`调用;或者Android Hybrid App中用RecordApp开启Native原生录音来避免此问题,因为App可以做到请求到权限后,后续录音不会再去进行权限请求。




Expand Down Expand Up @@ -247,7 +249,7 @@ set={
**注意:set内是数字的明确传数字**,不要传字符串之类的导致不可预测的异常,其他有配置的地方也是一样(感谢`[email protected]`19-01-10发的反馈邮件)。

### 【方法】rec.open(success,fail)
请求打开录音资源,如果浏览器不支持录音或用户拒绝麦克风权限将会调用`fail`打开后需要调用`close`
请求打开录音资源,如果浏览器不支持录音或用户拒绝麦克风权限将会调用`fail`打开后需要调用`close`来关闭,因为浏览器或设备的系统可能会显示正在录音

注意:此方法回调是可能是同步的(异常、或者已持有资源时)也可能是异步的(浏览器弹出权限请求时);一般使用时打开,用完立即关闭;可重复调用,可用来测试是否能录音。

Expand All @@ -261,7 +263,7 @@ set={


### 【方法】rec.close(success)
关闭释放录音资源,释放完成后会调用`success()`回调
关闭释放录音资源,浏览器或设备的系统将停止正在录音的提示,释放完成后会调用`success()`回调

### 【方法】rec.start()
开始录音,需先调用`open`;如果不支持、错误,不会有任何提示,因为stop时自然能得到错误。
Expand Down
7 changes: 6 additions & 1 deletion app-support-sample/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,18 +162,23 @@ IOS其他浏览器||
- `IOS-Weixin`使用的`微信JsSDK`单次调用录音最长为60秒,底层已屏蔽了这个限制,超时后会立即重启接续录音,因此当在IOS微信上录音时,超过60秒还未停止,将重启录音,中间可能会导致短暂的停顿感觉。
- `demo_ios`中swift代码使用的`AVAudioRecorder`来录音,由于录音数据是通过这个对象写入文件来获取的,可能是因为存在文件写入缓存的原因,数据并非实时的flush到文件的,因此实时发送给js的数据存在300ms左右的滞后;`AudioQueue``AudioUnit`之类的更强大的工具文章又少,代码又多,本质上是因为不会用,所以就成这样了。
- `Android WebView`本身是支持录音的(古董版本就算啦),仅需处理网页授权即可,但Android里面使用网页的录音权限问题可能比原生的权限机制要复杂,为了简化js端的复杂性(出问题了好甩锅),不管是Android还是IOS都实现一下可能会简单很多;另外Android和IOS的音频编码并非易事,且不易更新,使用js编码引擎大大简化App的逻辑;因此就有了Android版的Hybrid App Demo。
- 已知 [#46](https://github.com/xiangyuecn/Recorder/issues/46) `Android WebView`内发起授权请求时(如:H5的getUserMedia方法调用、App的权限请求)会打断touch事件,表现为触发了`touchcancel`事件,`touchend`事件始终不会触发,在做按住录音功能时应留意此问题。如果你要使用按住录音功能,解决办法:在每次`按住录音按钮`被按之前都重新进行一次`RequestPermission`调用;或者Android Hybrid App中用RecordApp开启Native原生录音来避免此问题,因为App可以做到请求到权限后,后续录音不会再去进行权限请求。



# :open_book:方法文档

## 【静态方法】RecordApp.RequestPermission(success,fail)
请求录音权限,如果当前环境不支持录音或用户拒绝将调用错误回调;调用`RecordApp.Start`前需先至少调用一次此方法;请求权限后如果不使用了,至少要调用一次`Stop`来清理资源。
请求录音权限,如果当前环境不支持录音或用户拒绝将调用错误回调;调用`RecordApp.Start`前需先至少调用一次此方法,用于准备好必要的环境;请求权限后如果不使用了,不管有没有调用`Start`,至少要调用一次`Stop`来清理可能持有的资源。

主要用于在`Start`前让用户授予权限,因为未获得权限时可能会弹出授权弹框让用户好去处理;App和大部分浏览器只需授权一次,后续就不会再弹框了;因为`Start`中已隐式包含了授权请求逻辑,对于少部分每次都会弹授权请求的浏览器,不调用本方法也能获得权限。

`success`: `fn()` 有权限时回调

`fail`: `fn(errMsg,isUserNotAllow)` 没有权限或者不能录音时回调,如果是用户主动拒绝的录音权限,除了有错误消息外,`isUserNotAllow=true`,方便程序中做不同的提示,提升用户主动授权概率

注:如果需要使用按住录音这种功能,参考上面的功能限制部分,请求权限可能会导致touch事件被打断,解决办法也参考上面。


## 【静态方法】RecordApp.Start(set,success,fail)
开始录音,需先调用`RecordApp.RequestPermission`
Expand Down
13 changes: 11 additions & 2 deletions assets/zdemo.index.webrtc.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ var realTimeSendTryStop=function(recSet){


//按住发语音
var rtcVoiceStart,rtcVoiceDownEvent,rtcVoiceDownHit;
var rtcVoiceStart,rtcVoiceDownEvent,rtcVoiceDownHit,rtcVoiceTipsV;
$("body").bind("mousedown touchstart",function(e){
var elem=$(".webrtcVoiceBtn");
if(e.target!=elem[0]){
Expand All @@ -185,6 +185,11 @@ $("body").bind("mousedown touchstart",function(e){
rtcVoiceDownHit=setTimeout(function(){
rtcVoiceStart=true;

if(!rtcVoiceTipsV){
rtcVoiceTipsV=1;
reclog('<span style="color:#f60">已知`Android WebView`内发起授权请求时(如:H5的getUserMedia方法调用、App的权限请求)会打断touch事件,表现为触发了`touchcancel`事件,`touchend`事件始终不会触发,在做按住录音功能时应留意此问题。如果你要使用按住录音功能,解决办法:在每次`按住录音按钮`被按之前都重新进行一次权限请求方法的调用;或者Android Hybrid App中用RecordApp开启Native原生录音来避免此问题,因为App可以做到请求到权限后,后续录音不会再去进行权限请求。</span>');
};

//开始录音
recstart(function(err){
if(err){
Expand All @@ -198,7 +203,7 @@ $("body").bind("mousedown touchstart",function(e){
};
});
},300);
}).bind("mouseup touchend",function(e){
}).bind("mouseup touchend touchcancel",function(e){
if(rtcVoiceDownHit || rtcVoiceStart){
$("body").css("user-select","");
clearTimeout(rtcVoiceDownHit);
Expand All @@ -210,6 +215,10 @@ $("body").bind("mousedown touchstart",function(e){

//结束录音
recstop(function(err,data){
if(e.type=="touchcancel"){
rtcMsgView("[中断]touch事件被中断",false);
return;
};
if(err){
rtcMsgView("[错误]"+err,false);
return;
Expand Down

0 comments on commit 8b91ce7

Please sign in to comment.