微服务先等等,我去刷个“虚拟背景”的副本

好久不写了

说起来,从上次更文,到现在,已经有挺长一段时间不更文了。

不是咱忘了,也不是咱摆烂不想更,一是前段时间,老有项目上的事儿拖着,当然现在也有;二是这个微服务的框架我其实已经搭起来一部分了,但是因为涉及到的知识面对我来说还是太多了,而且也不能全部投入的去搞,还要兼顾别的工作和摸鱼,所以进度就很慢,也就一直没东西写。

什么虚拟背景

就是腾讯会议软件的虚拟背景,类似的功能移植到 Web 端。

那有什么好说的

其实确实没什么好说的,web 端实现虚拟背景,相关的技术已经非常成熟,类似的论文,博客,在搜索引擎上一搜有好多,但实际真正落地到产品上的并没有多少,具体原因有很多,其中有一个绕不开的话题就是“性能”。

我想,这应该也是,即便是腾讯云这种级别的服务商也不提供官方支持的主要原因,毕竟把一个随时都可能会“爆炸”的功能点放开给用户,多少有点“晚节不保”的风险。

但实际的生产需求中,我们的确会遇到这个问题(比如,在夜深人静的夜晚,领导找你,告诉你说,我还是想要这个功能,你赶紧安排),那要怎么解决?我就是通过一通 复制粘贴,啊不,深入研究,勉强给出了一个不成熟的办法。

聊点有用的吧

其实,腾讯云的 TRTC SDK 提供了一个美颜接口,这个接口虽然没有实现虚拟背景的功能,但我们却可以通过这个接口,自己实现,或者通过一些插件来实现虚拟背景的功能。

官方有一个推荐的第三方插件👉:https://www.npmjs.com/package/rtc-beauty-plugin

根据指引,通过简单的配置,就可以实现虚拟背景了。

  • 安装

官方给出的安装方式是通过 npm 的形式,但如果想通过 browser 的方式引入,可以直接到这个包的仓库地址下载对应的资源文件,导入到自己的项目里,和平常的方式一样

  • 修改 TRTC 的发布流逻辑

这里,我们的项目是用的 TRTC for Web 的BaseJs模式,所以我这里展示的还是基于 jQuery 的这种传统方式,当然也支持 Vue 这些框架。

关键就在于 join 动作执行的时候,我这里是增加了两个参数来控制是否开启虚拟背景,以及清晰度参数(这个不重要)。

代码太长,我这里就简单罗列关键的部分

class RtcClient {  		constructor(options) {        //...定义一些关键参数        // 把插件引入到这里,类似构造函数的形式        this.rtcBeautyPlugin = new RTCBeautyPlugin();               //...
    }           //mode就是控制分辨率的,我这里在官方给的的120p-4k的预设模板上增加了几个自定义的模式。    //原谅我不成熟的参数命名。。    async join(mode = "normal", isPro = false){      //...原有逻辑      if (mode == "normal") {        this.localStream_.setVideoProfile({ width: 1280, height: 720, frameRate: 10, bitrate: 1500 });      } else if (mode == "virtual") {//虚拟背景专用        this.localStream_.setVideoProfile({ width: 640, height: 360, frameRate: 5, bitrate: 300 });      } else {        //除以上2个自定义的清晰度外,剩余均为官方默认支持的定义        this.localStream_.setVideoProfile(mode)      }            if (isPro)        await this.publishPro();      else        await this.publish();      //...其他逻辑    }      		//含虚拟背景    async publishPro() {        if (!this.isJoined_) {            console.warn('publish() - please join() firstly');            return;        }        if (this.isPublished_) {            console.warn('duplicate RtcClient.publish() observed');            return;        }        try {            await this.rtcBeautyPlugin.loadResources();            let img = document.getElementById('img');            if (img) {                const virtualStream = await this.rtcBeautyPlugin.generateVirtualStream({                    localStream: this.localStream_,                    type: 'virtual',//虚拟背景                    img: img,                                    });                await this.client_.publish(virtualStream);            } else {                const virtualStream = await this.rtcBeautyPlugin.generateVirtualStream({                    localStream: this.localStream_,                    type: 'blur'//虚化                });                await this.client_.publish(virtualStream);            }        } catch (error) {            console.error('failed to publish local stream ' + error);            this.isPublished_ = false;            this.rtcBeautyPlugin.destory();        }
        this.isPublished_ = true;            }        //离开房间    async leave() {        ...原逻辑        //增加销毁插件的方法        this.rtcBeautyPlugin.destroy();    }}

复制代码

修改好以后,再根据业务情况,调整一下界面就 ok 了

看下页面效果

好久不写了

说起来,从上次更文,到现在,已经有挺长一段时间不更文了。

不是咱忘了,也不是咱摆烂不想更,一是前段时间,老有项目上的事儿拖着,当然现在也有;二是这个微服务的框架我其实已经搭起来一部分了,但是因为涉及到的知识面对我来说还是太多了,而且也不能全部投入的去搞,还要兼顾别的工作和摸鱼,所以进度就很慢,也就一直没东西写。

什么虚拟背景

就是腾讯会议软件的虚拟背景,类似的功能移植到 Web 端。

那有什么好说的

其实确实没什么好说的,web 端实现虚拟背景,相关的技术已经非常成熟,类似的论文,博客,在搜索引擎上一搜有好多,但实际真正落地到产品上的并没有多少,具体原因有很多,其中有一个绕不开的话题就是“性能”。

我想,这应该也是,即便是腾讯云这种级别的服务商也不提供官方支持的主要原因,毕竟把一个随时都可能会“爆炸”的功能点放开给用户,多少有点“晚节不保”的风险。

但实际的生产需求中,我们的确会遇到这个问题(比如,在夜深人静的夜晚,领导找你,告诉你说,我还是想要这个功能,你赶紧安排),那要怎么解决?我就是通过一通 复制粘贴,啊不,深入研究,勉强给出了一个不成熟的办法。

聊点有用的吧

其实,腾讯云的 TRTC SDK 提供了一个美颜接口,这个接口虽然没有实现虚拟背景的功能,但我们却可以通过这个接口,自己实现,或者通过一些插件来实现虚拟背景的功能。

官方有一个推荐的第三方插件👉:https://www.npmjs.com/package/rtc-beauty-plugin

根据指引,通过简单的配置,就可以实现虚拟背景了。

  • 安装

官方给出的安装方式是通过 npm 的形式,但如果想通过 browser 的方式引入,可以直接到这个包的仓库地址下载对应的资源文件,导入到自己的项目里,和平常的方式一样

  • 修改 TRTC 的发布流逻辑

这里,我们的项目是用的 TRTC for Web 的BaseJs模式,所以我这里展示的还是基于 jQuery 的这种传统方式,当然也支持 Vue 这些框架。

关键就在于 join 动作执行的时候,我这里是增加了两个参数来控制是否开启虚拟背景,以及清晰度参数(这个不重要)。

代码太长,我这里就简单罗列关键的部分

class RtcClient {  		constructor(options) {        //...定义一些关键参数        // 把插件引入到这里,类似构造函数的形式        this.rtcBeautyPlugin = new RTCBeautyPlugin();               //...
    }           //mode就是控制分辨率的,我这里在官方给的的120p-4k的预设模板上增加了几个自定义的模式。    //原谅我不成熟的参数命名。。    async join(mode = "normal", isPro = false){      //...原有逻辑      if (mode == "normal") {        this.localStream_.setVideoProfile({ width: 1280, height: 720, frameRate: 10, bitrate: 1500 });      } else if (mode == "virtual") {//虚拟背景专用        this.localStream_.setVideoProfile({ width: 640, height: 360, frameRate: 5, bitrate: 300 });      } else {        //除以上2个自定义的清晰度外,剩余均为官方默认支持的定义        this.localStream_.setVideoProfile(mode)      }            if (isPro)        await this.publishPro();      else        await this.publish();      //...其他逻辑    }      		//含虚拟背景    async publishPro() {        if (!this.isJoined_) {            console.warn('publish() - please join() firstly');            return;        }        if (this.isPublished_) {            console.warn('duplicate RtcClient.publish() observed');            return;        }        try {            await this.rtcBeautyPlugin.loadResources();            let img = document.getElementById('img');            if (img) {                const virtualStream = await this.rtcBeautyPlugin.generateVirtualStream({                    localStream: this.localStream_,                    type: 'virtual',//虚拟背景                    img: img,                                    });                await this.client_.publish(virtualStream);            } else {                const virtualStream = await this.rtcBeautyPlugin.generateVirtualStream({                    localStream: this.localStream_,                    type: 'blur'//虚化                });                await this.client_.publish(virtualStream);            }        } catch (error) {            console.error('failed to publish local stream ' + error);            this.isPublished_ = false;            this.rtcBeautyPlugin.destory();        }
        this.isPublished_ = true;            }        //离开房间    async leave() {        ...原逻辑        //增加销毁插件的方法        this.rtcBeautyPlugin.destroy();    }}

复制代码

修改好以后,再根据业务情况,调整一下界面就 ok 了

看下页面效果

最后,还是要嘱咐一句,我这里设定的是,如果用户开启虚拟背景,则会限制 360P 的分辨率,且帧率会拉低到 5fps,码率也会调到 500 以内,基本能看清,但再高就卡顿的很明显了,因为虚拟背景的原理是把你采集到的每一帧画面做先切割在合成等这些阻塞性操作,所以参数必须得往低了调。可即便如此,资源占用率还是会提高很多,性能影响还是肉眼可见的,所以,慎重使用吧!

好了,基本就是这样了,继续边刷副本边修仙~

最后,还是要嘱咐一句,我这里设定的是,如果用户开启虚拟背景,则会限制 360P 的分辨率,且帧率会拉低到 5fps,码率也会调到 500 以内,基本能看清,但再高就卡顿的很明显了,因为虚拟背景的原理是把你采集到的每一帧画面做先切割在合成等这些阻塞性操作,所以参数必须得往低了调。可即便如此,资源占用率还是会提高很多,性能影响还是肉眼可见的,所以,慎重使用吧!

好了,基本就是这样了,继续边刷副本边修仙~

PS.本文已于2022.11.4发布于InfoQ写作社区(原地址:微服务先等等,我去刷个“虚拟背景”的副本_虚拟背景_为自己带盐_InfoQ写作社区),于2022.12.5由作者本人转载至CSDN社区

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

为自己_带盐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值