前言
元宇宙场景在这两年逐步衰亡,成为很多社交、娱乐产品关注的新场景。而且,目前有不少产品曾经落地。本文整顿自声网解决方案架构师管浩森在 RTE 2022 大会的演讲。他是元宇宙方向的专项解决方案负责人。他基于帮助客户落地元宇宙场景的教训,以元宇宙派对为例,分享了该场景的实践经验。
本文内容基于演讲内容进行整顿,为不便浏览略有删改。
大家好!我叫管浩森,是一名开发者也是一名创业者。我在间断守业过程中对 toC 产品和性能,包含架构设计方面积攒了丰盛的教训和认识。2021 年我退出了声网,目前负责元宇宙方向专项解决方案的负责人,目前致力于为客户提供市场上更有劣势整体解决方案。
明天咱们来讲一个比拟轻松的话题,“如何在元宇宙里创立一场派对”。我会以元宇宙派对场景作为根底,介绍从前到后、从里到外整套的解决方案。
咱们先看一下元宇宙场景目前的倒退。首先,咱们看一下近年来社交场景状态的变更。从“在线”到“在场”,消费者的社交状态其实是一直降级的:从 2011 年挪动端及时通信的衰亡,随着智能手机的遍及,手机 QQ 等产品带来挪动文字即时通讯,也就是 IM,包含离线留言的性能,相似于 QQ 空间。过后它的社交形式、社交属性实际上是通过表情包 + 文字的形式进行即时通讯。
工夫来到 2016 年,全屏短视频开始暴发。随着抖音在 2016 年的公布和快手的推广,人们逐步习惯了通过分享和评论去观看 UGC 的内容,也就是用户本人在平台上公布的视频产品。对于此类产品,社交状态次要通过录制的视频 + 录制的声音和用户的评论来交换。
2018 年,直播场景全面暴发。游戏风口当年正热,短视频、直播逐步成熟,直播带货在直播行业中全面衰亡,对于直播而言此时交换形式变成实时的影像 + 实时的声音。
2021 年,Facebook 在年底改名为 Meta,像一个重磅炸弹一样为整个行业炸出了一条路,电影、VR、游戏在这一年全面开花,让元宇宙概念再次炽热起来。在元宇宙元年,人们之间的交换形式曾经由实时的影像 + 实时的声音变成了实时渲染的场景 + 实时的音视频。
对于消费者在元宇宙的理解这一步来看,咱们找到了以下的数据。考察显示,咱们对元宇宙理解水平广泛较高,因为元宇宙一词近年来接连被提及,特地是疫情状况下对于新型社交类型的强需要,Facebook 的改名、微软收买动视暴雪、百度推出了希攘,这一系列的信息让网民对于元宇宙的概念曾经有了一个根本的认知环境。经数据考察,所有受访的网友都听过元宇宙的概念,其中 61.4% 的网友对于元宇宙比拟相熟,15.9% 更是十分理解,对于元宇宙消费者有什么期待呢?
数据展现,网友更多期待元宇宙社交的场景。国内泛娱乐疾速倒退和互联网浪潮双重推动下,国内的网友,特地是 Z 时代年轻人,对于新兴事物接受程度和尝试志愿都十分高。依据数据考察显示,消费者对于元宇宙的期待还优先在泛娱乐场景,特地是虚构社交畛域超过 60% 网友比拟违心尝试元宇宙类型的社交模式。
既然如此,咱们该怎么样搭建进去一个社交元宇宙场景呢?接下来跟着我一起开一个元宇宙的派对。
01 创立元宇宙:万物成长
首先咱们先看创立元宇宙第一块万物成长,所谓万物成长即咱们要在元宇宙整个场景内创立山川河流、世间万物,如何创立这是第一道难题。
首先咱们讲一下对于模型的构建。模型构建当初市场上曾经有了一套成熟的流程,通过一系列的步骤,比如说角色设计、中模、高模、低模、烘焙贴图、骨骼绑定等操作,便能够残缺地建设一套元宇宙场景下的人物模型。当然也有整个场景的虚构,当初还有很多的模型是能够间接购买应用的。
此外能够通过引擎和底层 API,以捏脸的模式做业务层的换装,相似于苹果的 Memoji,在建设规范模型根底上能够提供给真正 C 端用户更个性化人物定制和形象定制,声网行业会逐步完善地推出 MetaLive 产品包,让大家能够用 Native 的开发方式实现换装的性能。
第二块,咱们当初有了一套虚构场景,咱们怎么能力让它动起来?对于动起来最重要的是模型间交互的脚本制作。目前模型交互脚本制作有两个计划能够抉择,一个是应用现成渲染引擎,比方 Unity、Arnold 第三方渲染引擎,也能够通过 OpenGL、Direct3D 底层 API 本人去管制底层的硬件和渲染整个场景。声网在这方面会提供 Metachat 等合产品包,来帮忙大家实现整个场景的渲染局部逻辑,让客户更有精力地关怀业务局部的逻辑。因为咱们晓得不论是元宇宙还是 2D 社交产品,它的派对或者社交实质还是人自身。
02 创立元宇宙:推杯换盏
咱们怎么能力在元宇宙的场景中相互交换,在排队中推杯换盏?上面跟咱们一起走进一个场景内,看看整个元宇宙是如何活起来的。
首先,咱们看一下信令管制,包含所谓场景管制,当初创立了 3D 虚拟世界,咱们该如何进行操作呢?元宇宙内会有大量的信息、信令交互,比如说我的地位坐标、我给谁送的礼物、我的动作什么样,随着房间内人物越来越多,服务端对于这类信息处理的压力也会越来越大,对此,基于给多个客户的打磨,声网有以下的教训和一些举荐的思路,分享给大家。
第一,是将不同的数据分为不同的频次,比方我当初要同步每个人地位信息坐标,地位信息同步很有可能是每秒 10 次甚至每秒 30 次的帧率,如此宏大数据对于服务器存储是无意义的,它只是一个可失落、只须要保序的信令。对这类信令咱们要和低频次的数据进行拆散,比如说我去给谁送礼物,这属于一个低频的数据,不同的数据通过不同的通道进行同步,这样能够无效升高服务器的压力。有一些高频的数据没有必要存储,有些低频的数据包含重要信息是适宜存储的。
第二,将同步数据依照重要类型划分。咱们把它分为了关键帧和非关键帧两类。关键帧个别指事件的同步,比方开闭麦的状态、房间内的属性。就比方我当初在应用电脑,他人没有方法随便把这台电脑给抢走。非关键帧指的什么?相似于我刚刚说对于整个场景内地位信息的变动,包含动作细节的模型、面部结构化数据,整个脸在此刻动的结构化信息,这个结构化信息是没有必要每一帧都残缺传输,它和视频帧是相似的状况。对于此类信息须要保障疾速且保障时序,但不肯定可能保障必须达到。对于此类数据咱们把它划分为关键帧和非关键帧进行传输,关键帧更多须要记录,而非关键帧更多须要保障速度。
第三,是对立的思路,对于音讯风暴的躲避。如果频道内的信息过多很有可能造成服务中整体压力包含客户端的回调压力。对此,个别业内会这样解决操作,比方 A 和 B 两个人,他们之间同步信息不是 A 播送本人所有的信息到频道内,而是 A 独自发给服务器,B 也独自发给服务器,服务器整合了之后通过每秒 10 次或者 20 次的频率对立下发给各个端,这样每个端收到的音讯不再是所有人的信息叠加,而是服务端整顿好整合的信息,这样能够躲避大量的数据仿造。
其中,第二局部咱们须要明确 RTM(Real-Time Messaging)几个功能模块,我简略介绍一下,因为接下来整个场景我会次要以声网 RTM 性能来作为类型的串联,大家能够类比把声网 RTM 替换成大家现有应用的产品。
声网 RTM 次要的功能模块有这么几个:
- 频道信息,是作为播送性质的音讯,经常作为非关键帧的播送。
- 频道属性,频道属性是长期存储的,大家能够以本人业务服务器来代替,频道属性每一次变更后,所有人都会收到频道属性变更信息。
- 用户属性,用户属性是各个用户之间不会默认的订阅,须要订阅某个人之后,某个人的用户属性变更我才会收到变更信息。
接下来,我次要会通过以下三个互动场景作为重点,来给大家介绍一下在元宇宙场景中这些场景的注意事项和实际的形式。
第一就是“你在哪儿”。咱们当初进到了一个场景内,咱们怎么能力挪动?我会以人物挪动为例,解说关键帧和非关键帧的同步策略,此时关键帧和非关键帧同步定义偏差于是否进行存储。
第二就是“打招呼”。我能挪动了之后,我身材各个动作该怎么解决,我见到了共事之后、见到了同学之后,如何能力以一个形式告知让我看到我在和他打招呼。
第三是元宇宙场景内常常被疏忽一个细节,就是“先来后到”,抵触的解决和锁的解决,对于此我会以抢椅子场景为例介绍锁的概念和其利用。
接下来咱们代入一个场景(如下图所述):
对于此计划最次要作为指标地位挪动同步信息,对于坐标地位同步咱们个别分为两大类,一类是通过点击屏幕或者按钮进行操作,相似于下图展现的游戏,大家很多人玩过《梦幻西游》,对于这类游戏大家能够了解为我是点击某个地位之后,人物通过主动选址走到那个地位。
对于这种状况,咱们晓得开始地位信息和完结地位信息。此时,开始地位点和完结坐标地位点作为两个关键帧会传输给各个端,各个端收到了关键帧之后,就不能够通过每个端统一选址策略,来实现每个端走的动作是一样的,这样实现了伪同步。我须要同步的信息量很小,因为不须要同步每一个地位帧,我只须要同步两个关键帧即可。
当然,这个策略也会有一些弊病。我只实用于“通过点击屏幕或按钮操作”,即通过指令开始和完结地位的操作,而通过轮盘或者手柄形式进行自在挪动的场景,则须要思考上面这种策略。
另一类则是通过轮盘或者外设的形式,自在管制角色进行走动,此类形式没有固定的完结地位,无奈通过关键帧的形式进行播送,须要一个信令通道进行非关键帧 (地位坐标) 的同步,在用户挪动时,疾速 (例如每秒 10 次) 向频道内发送音讯,收到播送音讯的用户拿到对方坐标地位后做地位渲染。非关键帧信息能够不被服务器记录。
同时,为了服务器能够定时存储角色以后地位,能够定义例如每 5 秒作为一个关键帧存储在频道属性内 / 服务器内,此时若角色掉线,则重连后能够渲染回到上一次的关键帧地位。
那么这两种在元宇宙中的操作,须要怎么实现呢?上面以 RTM 应用为例,给大家介绍一下整个应用流程。
1. 如果通过指令开始和完结地位须要三步。第一退出 RTM 房间,通过获取到开始和完结后的地位信息,更新 RTM 的房间属性,房间属性变动之后同步播送给房间内所有人,所有人拿到了远端状态信息,能够通过本地解决和选址渲染进去地位变动人的挪动形式,这样每个人就能够看到对方在挪动了。
2. 通过自在挪动地位坐标形式去进行挪动的话该怎么操作呢?左边局部各端退出 RTM 和 RTC 房间内,用户挪动的时候能够通过 RTC 的 data storage 通道或者说 RTC 频道信息通道发送关键帧,此关键帧能够每秒 10 次或者每秒 25 次,和帧率保持一致状况,向频道内发送我本人以后的地位音讯。远端的客户收到了我的频道音讯,我的非关键帧之后,通过本人的渲染,渲染进去我以后每一帧的地位信息,而后就能够渲染进去我的坐标了。此外,咱们还须要定义一个定时器,比如说 5 秒一次,把以后状态同步到房间属性或者服务器外面做存储,这样为了欠缺元宇宙内离线重连业务层服务体验的问题。
那么接下来,咱们要解决如何在元宇宙场景中 Say Hi 的问题。
大家能够晓得我心愿和他打招呼,为什么此时我动不了?因为打招呼实质是信令的登程。我作为 A,我的舍友作为 B,A 和 B 打招呼,信令是 A 把打招呼动作指令发送给 B,同时 A 和 B 同时渲染打招呼的动作,此时 A 和 B 能够同时看到我和他在招手。咱们对这些指令有一些定义,比如说咱们心愿被某些人看到,这样就能够通过刚刚说用户属性变更,大家还记得用户属性和频道属性之间区别是什么吗?用户属性是默认不被所有人订阅的,只有订阅本人的人才能看到本人的变动,我打招呼只有想看我的人,或者离我足够近的人才能够渲染进去我打招呼的动作,离的远的人不必渲染此动作了,这样就会极大缩小客户端的渲染压力。
或者说我心愿只让局部人能够看到打招呼的信息,此时我就能够通过点对点的音讯,例如 IM 或者服务器的 socket,让局部人被动渲染进去我打招呼的信息。
此时有一个比拟重要的点,我打招呼并不是我被动渲染之后他人就能够看到,而是我通过信令让他人晓得了之后,各个端渲染远端人打招呼信息,这样才是一个正确的形式。当然也能够通过业务层的限度,我给所有人去播送,然而某些人是不会去渲染的,这样就须要业务层服务器去做权限的管制或者数组的定义。
流程大家能够看一下左边,各端先退出 RTM 房间,角色 A 触发了打招呼的动作,触发是让我本人看到我本人在和对方打招呼。我打招呼的同时通过属性的变更或者频道的音讯,播送给房间内的其他人,其他人收到了之后大家也渲染进去我和其他人招收的动作,此时就实现了打招呼的动作,包含之后一系列的碰杯、拥抱、送花都是通过此类形式能够去执行。
对于此类信息咱们有一个先来后到的概念,如何解决抵触实际上是元宇宙场景内一个比拟容易疏忽,然而十分重要的一环。
这样的抵触声网将椅子的占有权定义为一把“锁”,这把“锁”的占有权是只能属于一个人。我如何能力解决整个抵触的过程呢?比方我是 A 角色,另外一个兄弟是 B 角色,咱们两个同时想坐在椅子上,须要先尝试获取此“锁”的占有权,RTM 服务端会依照达到的程序去判断,或者咱们在业务服务器一层去解决优先权,比方我是 VIP,我必定要比对方先占有此座,除去这个以外是论工夫达到先后。RTM 会主动解决分布式的抵触,谁先达到了之后,会返回一个“申请锁胜利”的回调,对方会反馈一个失败的回调,收到此回调之后,咱们才会解决坐下动作脚本。坐下动作脚本和打招呼动作脚本实现原理是统一的。
这一点其中比拟重要的是,我须要去获取“锁”胜利的回调事件之后才会触发动画脚本,而不是我点击坐下按钮之后就会触发,这样就会呈现我在方才场景里形容,咱们两个同时都坐在了椅子上,并且串模了。这样 B 角色收到本人无比坐下或者获取锁失败的操作之后,B 就会通过客户端弹窗告知此座位曾经有人了,你无奈坐下了。同时,声网把椅子占有状态作为房间属性贮存在服务端或者贮存在房间信息内,这样每当其他人凑近椅子的时候,会感知到这个椅子上曾经有人了,这样就不会再呈现坐下的按钮去反复进行“锁”的获取。
整个流程大家能够看左边局部,第一块就是退出 RTM 房间内,角色 A 去申请椅子占有“锁”,如果返回失败的话进行弹窗提醒没有此类信息,如果返回胜利的话会触发坐下椅子的操作。
坐下椅子同时回到打招呼整个流程内,我坐下的动作触发了之后,会通过一个频道音讯发送给各个端,各个端也会渲染坐下的指令,这样大家都能够看到我坐在这把椅子上。角色 A 站起来了之后,会通过 release 的办法开释对椅子锁的占用,这样其他人在进来的时候就能够再次坐在这把椅子上了,这个就是一个抵触的解决。
我该怎么在元宇宙场景里像真实世界一样交换,声音它都去哪儿了?咱们来进入第三个章节,创立元宇宙的空气和水。
03 创立元宇宙:空气和水
实时音视频的引入会使得元宇宙的社交场景更具备沉迷感。角色间语音的交换,场景内背景音乐的播放、和好友一起边看电视边聊天、甚至通过空间音频判断对方的地位或者间隔,这都会让元宇宙体验更上一个台阶,实时音视频在元宇宙场景中就如同空气和水一样,大家留神到它,但它却是无处不在。
我会次要把实时音视频划分三个模块进行派对内场景的剖析:
- 第一块会以一起看电视为例介绍如何在元宇宙房间内实现一起看、一起听或者说 BGM 播放同步性能。
- 第二块我会以一个游戏的形式,我闭着眼捉迷藏,如何通过声音的方向去判断其他人的地位,空间音频的引入其实就能够像真实世界一样,带给元宇宙更深层次的沉迷感。
- 第三我会以悄悄话或者心里话为主,介绍如何通过声网最新 SDK 多频道形式进行不同场景交融和交换私密性的保障。
接下来咱们进入场景内,一起看或者一起听实际上为的就是保障每个人看到工夫点是同步的概念,这样大家能够保障同时感触到雷同的氛围,甚至能够实现独唱的场景。
如何能力通过声网 RTC 性能同步一起看或者一起听的工夫进度?声网给出了以下三种计划:
1、通过【播放者】MPK 本地播放后推流到频道内
第一是通过播放者的概念,把某一个客户端播放的视频推到频道内。声网为一起看一起听推出了适配 MPK(Media Player Kit)媒体播放器。MPK 媒体播放器不仅能够播放音频视频文件,包含 CDN 媒体流,甚至能够将本地播放的视频以 RTC 视频流的模式推到声网频道内。此时大家通过 RTC 强同步进行工夫的同步,而不须要去思考工夫戳的对齐,这样是较好的形式。然而此计划须要有一个具备推流权限的客户端作为发起者,本人播放的视频将会推到频道内,具体流程大家能够看下图。
业务端首先发动我要播放的申请,业务端服务器告知你能够播放之后,客户端 APP 去播放此视频,并且把播放的视频流推到声网大网内,声网再通过转发,转发给各个不同播放端进行视频独特播放,这是第一种形式。
2、通过【发起者】同步进度,各端本人播放
第二种形式能够通过发起者的同步进度,各个端本人通过 RTM 形式播放此。计划就不须要通过 RTC 作为强同步的规范,而是通过声网提供 data stream 通道。你能够用这个通道将某一个发起者作为工夫戳的主体,将发起者以后播放工夫进度同步到频道内,各个端基于播放者或者发起者角色工夫播放进度来拉齐本人以后的进度。
与第一种形式的不同,各端拿到进度之后进行本人播放器工夫戳对齐。这种会有一个问题。每一次传输的物理提早是不一样的,第一次发送 data stream,我和 A 和 B 物理提早就是链路提早是 50 毫秒,下一次是 70 毫秒,这样相差 20 毫秒对于自身工夫戳进度感知不强,但如果对齐会有卡顿的感觉。所以要引入预值缓冲区的概念。如果大于预值缓冲区的预值(如 100 毫秒),比如说这一次 50 毫秒,下一次 70 毫秒,下一次变成 40 毫秒,都在预值稳定内,这样大家能够通过在播放内,不必对齐。超过了此进度的话,比方以后在 4 分 10 秒,我刚进来的人是 0 分 0 秒,4 分 10 秒减 0 分 0 秒必定大于 100 毫秒,这样才能够进行对齐,把 0 分 0 秒那个人进度拉齐到 4 分 10 秒。具体情况大家能够看上图。其实和第一种计划是统一的,只不过每个端本人去播放,通过 MPK 去播放视频。
3、通过 CloudPlayer 播放后推流到频道内
前两种计划大家能够发现一个弊病,都须要通过发起者的概念去保护整个进度或者整个视频,如果发起者的网络条件不太好或者性能达不到的话,会影响整个房间内所有人的视频播放体验。
对于此声网提出了 cloud player 的概念,业务端能够通过 RESTful API 调用,服务端无需退出某个频道内,就能够去开启一个 worker,把须要播放的数据推到声网的大网。声网大网通过视频流的模式,保障同步,并推到各个播放客户端。此计划就能够躲避掉房主或者发起者的概念,所有人能够任意进出此房间,然而我在房间内屏幕上播放是始终进行的。
以上三种计划都能够解决一起看的性能。
对于此,声网引入了一个空间音频的概念,空间音频概念能够让沉迷感更进一步。通过 RTC 音频、声音分别出用户的方位,能够为元宇宙场景提供更好的体验。声网提供空间音频能够让用户通过音频感知到谈话人的方向、地位高下、间隔远近的变动,同时还模仿了空气的衰减,音障,比方我和你隔了一道墙,你谈话和没有隔一道墙谈话是不统一的一个体验。对此,其实能够丰盛实在环境的变动,包含带给元宇宙场景内的用户更实在的体验和更丰盛的玩法。
声网目前空间音频还是关注 RTC 音视频自身的变动,比方人谈话的声音,而对于场景内自身的脚步声、关门声、环境声效须要业务层在渲染引擎层面、脚本层面本人去解决。
对于空间音频的流程如下:
1. 退出 RTC 频道【频道场景为直播,身份为主播】
2.muteAllRemoteAudioStreams(true)【默认不收流】
3. 创立并初始化空间音频对象并设置空间音效的参数
4. 先后调用 updateSelfPosition 和 updateRemotePosition 来设置远端和本人的地位
5.clearRemotePositions 勾销空间音频成果,destroy 销毁 AgoraLocalSpatialAudioKit 对象
首先须要退出 RTC 频道,同时把所有人远端的人敞开收流,相当于把开关音频权限交由空间音频解决。
第三块是创立空间音频的对象,并且设置空间音频的参数。这时候咱们能够调用本人在整个世界坐标内的地位坐标和设置远端的地位坐标,在本地渲染进去我和他的间隔、我和他的绝对方向、我和他的高下,这样就能够在本地去渲染进去每个人的地位坐标和空间音频的成果。
声网提供此计划不会影响远端传输,所以每个客户端都能够自在定义每个音频的具体位置。
对于在元宇宙中说悄悄话,或者说小范畴交换的场景需要,咱们引入了多频道的概念。声网新版的 SDK 容许用户通过自在操作多个频道来实现多频道的推流和拉流。比方在以后场景内,咱们能够通过三个频道来实现整个元宇宙派对的概念,首先乐队演奏能够拎进去独自做一个频道,所有人都能够订阅,然而所有人在此频道内不发流,只有乐队能够发流。这样大家能够同时听到同一首背景音乐,有共情的感觉。如果大家心愿也能够把乐队当做空间音频去解决。
第二个频道就是在大厅场景内,所有人都能够听到嘈杂空间音频的声音,比如说离我 10 米间隔某个小兄弟谈话声音会比拟小,离我比拟近的人谈话声音比拟大,让场景更贴近事实。
第三块是方才说通过卡座或者小分队的概念,能够作为独自频道,此频道只容许某些用户能够被退出,如果此频道内的用户谈话不会被大厅内其余用户听到,这样既能够爱护到隐衷也能够同时听到整个大厅内的音频发送,既能够体验到整个场景自由度也能够爱护本人的隐衷,就相似于频道的卡座,甚至看球的时候 VIP 专座一样。
除此之外,用户甚至能够将频道与一起看等联合,在某个频道内独自去观看某个内容,这样都交由开发者本人去解决。
以上就是咱们搭建一个元宇宙派对场景的实现过程与原理。如果大家感兴趣,心愿查看元宇宙相干的声网解决方案,请点击此链接。