我要给网页端同学完整的WebRTC环境

一、背景

为了节约开发成本,有时也为了可以和小程序开发同步,移动端的一些业务常常交给网页端的同学去做,原生则负责为网页端同学提供一个稳定,可靠的WebView环境,必要时,还要给网页端同学提供一些接口,用于调用原生能力。

相信大家对于这种混合开发的场景都十分常见。

现如今,随着实时音视频通信的流行,WebRTC技术也会常常被用到。有时我们希望直接在H5页面中使用WebRTC(使用自部署的stun/turn服务),往往会遇到哪些挑战?

  1. 系统WebView内核在不同的机器上表现不一致,常常带来适配噩梦,甚至无法支持
  2. 权限问题坑较多

二、抹平设备差异

TBS内核方案

即便不是为了解决WebRTC环境问题,我们也应该考虑为H5同学去尽量抹平WebView内核带来的差异。如果我们有WebView sdk团队,可以使用自研的WebView内核。但除了大厂以外,很难有这方面的资源。

所以目前我们只能借助一些免费的第三方sdk,如腾讯TBS(以前叫X5内核)

TBS免费版内核是基于chromium m89版本的,且在多年前的623xx版本就实现了对WebRTC的支持,这有助于我们隔离不同设备的系统WebView内核差异。

但是,我要说但是了,免费版还是有免费版的问题。

无法稳定下发的动态部署

image.png

TBS的内核是动态部署的,内核文件由腾讯的服务器下发。既然是动态下发的,那就有千千万万种可能会下发失败。如果下发失败,TBS会降级到系统内核。虽然系统内核也是可以继续用的,但就无法达到抹平设备差异的目的了。

最常见的内核下载错误是-134等,官方文档给出的解释是“命中流控”。按照我们监控的线上数据,普通时段失败率在3%左右,而且到了周末会激增,因为周五周六(18:00-21:00)属于服务器维护期,不支持下载。

尽管动态部署的稳定性不可控,但TBS官方也并不提供免费的静态部署的方案。当然,可能存在某些手段绕过官方下发,但不在本文讨论范畴。

还记得大明湖畔的 bugly OTA 功能吗?

去年bugly就有过关停了免费OTA业务的先例,而今年TBS也开始推商业版了。虽然TBS已经免费了多年,但还是不排除什么时候TBS也会关停免费版,毕竟腾讯的产品,不氪金你能变强吗?

以下仍然基于TBS方案来完成实现

尽管以上有这么多的风险预警,因为没有找到更为可靠的平替方案,所以以下实现仍然抛砖引玉的基于TBS方案。

如果大家有更好的方案也可以在评论区说下哦~

三、权限控制

权限动态申请

众所周知,Android 6.0后推出了权限的动态申请。WebRTC作为一种需要用到相机和麦克风的技术,自然逃不过权限申请。

对于系统WebView内核,来自H5的权限申请一般在WebChromeClient中回调。

webview.setWebChromeClient(new WebChromeClient(){ 
    // Need to accept permissions to use the camera 
    @Override public void onPermissionRequest(final PermissionRequest request) { 
        request.grant(request.getResources()); }
    }
);

但TBS拦截了原始的WebChromeClient中onPermissionRequest回调,而是通过IX5WebChromeClientExtension的onPermissionRequest来重新封装了来自H5的权限申请回调

webview.setWebChromeClientExtension(new IX5WebChromeClientExtension() { 
    // ....... 省略其他方法实现 
    @Override public boolean onPermissionRequest(String s, long l, MediaAccessPermissionsCallback mediaAccessPermissionsCallback) { 
        long allowed = 0; 
        allowed = allowed | MediaAccessPermissionsCallback.ALLOW_AUDIO_CAPTURE; 
        boolean retain = true; 
        mediaAccessPermissionsCallback.invoke(s, allowed, retain); 
        return true; 
    } 
});

其中,对于MediaAccessPermissionsCallback.invoke()

/**
* @params origin 请求权限的网页地址
* @params resouorces 请求的权限类型,位操作识别
* @params retain 是否缓存结果,缓存后,同一个origin申请同一权限都返回此结果而不会再次回调
*/
public void invoke(String origin, long allow, boolean retain);

扩展实现

当然,出于安全合规考虑,回调中还可以做一些扩展实现:

  • 对origin进行鉴权,对于不在白名单的网址,一律直接拒绝权限
  • 动态申请权限时,弹窗告知用户申请权限的具体用途,避免合规风险

权限静态申请

处理完动态申请的权限后,发现在一些设备上,H5端与音频相关的初始化仍然会失败,最终发现是以下权限需要静态添加到AndroidManifest

<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

三、WebRTC功能测试

完成了配置,就需要测试下以上措施是否奏效,以下提供了两个快速验证的线上工具:

ZEGO webrtc测试

地址: zegodev.gitee.io/zego-expres…

测试方法很简单,点击“开始测试”即可,测试完后,页面会告知每一项的测试结果。

image.png

Janus WebRTC Server VideoCall

地址:janus.conf.meetecho.com/videocallte…

可通过这个demo验证网页端的WebRTC视频通话

image.png

总结

本文介绍了基于TBS为网页端同学提供一个完整的WebRTC支持的实践方案,并在实际业务中落地。诚然TBS为这个方案提供了支撑,也成为了这个方案中最大的风险,但苦于没有好的平替方案,又希望能为用户提供更可靠的服务,最终我们选择了默默充钱氪金[doge]。

如果本文对你有帮助,记得点个赞哦~

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYoEe13B' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片