网易首页 > 网易号 > 正文 申请入驻

技术实战 —— 快速实现语聊房搭建

0
分享至

语音相比文字图片更丰富,比视频又更简便,是天然的社交工具。以95后为代表的Z世代用户,在微信、QQ、微博等主流社交工具以外,更愿意尝试基于不同兴趣相对小众的社交工具。ZEGO 即构科技推出语聊房解决方案,帮助客户快速搭建语聊房。本次分享,由 即构科技交付解决方案专家 JIN ,向我们分享线上社交以及语聊房的发展、玩法,并详细解析如何快速搭建语聊房,提供稳定、低延时,高品质的线上互动体验。

文 | JIN 整理 | LiveVideoStack

今天将从三个方面为大家讲述,包括语聊房的衍生玩法及发展,ZEGO语聊房解决方案,以及语聊房搭建实战。

语聊房的衍生与玩法

首先进入第一部分。

科技改变生活,在零几年诺基亚盛行的时候,大家可以通过QQ发送文字消息进行聊天,随着智能手机的兴起,即时通讯、短视频、视频直播、语聊等逐渐火热。而今晚的主题就是语聊。

近几年语聊发展的相当火爆,尤其是年前的Clubhouse火了很长一段时间,具体火到什么程度,可以看这个图。这是2014-2019年中国语聊房行业用户付费率及付费 ARPPU 值的统计图,付费率指的是100人中,有多少人愿意付费,ARPPU 值指的是付费的人中平均付费多少钱。在2014年,100人中只有3-4人愿意付费,而这3-4人平均愿意付费64.8元,到了2019年已经涨到了161.5元,付费意愿人数比例也从之前的3-4人,提升到15人。

上图数据是2021年8-10月Z世代用户在语聊行业APP活跃度,左边刻度单位为“万人”。Soul是在语聊行业中比较火的APP,紫色代表的是十月份的活跃度,大概有1993万人在线,而8月有2375万人在线,人数相当多,这只是一家APP的数据。

上图展示的是今年8-10月Z世代用户在语聊行业APP在线时长,数据来源于即构的后台统计,Soul8月总计在线时长达到了1017336分钟。从以上三组数据可以看出语聊房是非常火爆的,它为泛娱乐行业APP带来了很大的收益,同时也增加了用户粘性及在线时长。

语聊房比较常见的形式是1V1聊天房,在一些相亲类的APP里,比较常见的是提供1V1的语聊服务,不过这些服务都是要付费的。

第二种形式是多人语聊房,这种玩法就比较多了,首先是多人纯语聊,在线会议是比较常见场景,第二种是游戏开黑,第三种是赛事直播,一起观看赛事直播发表评论,第四种也是比较常见的一起看电影,第五种pia戏,就是多人根据剧本台词,进行实时的配音扮演,如右图所示。

第三种形式是语音电台,可以理解为主播直播,用户可以对他进行打赏。

第四种类型是KTV玩法,在语聊房技术上加上K歌,可以一边唱歌一边聊天进行打赏。

ZEGO语聊房解决方案

第二部分是即构提出的语聊房解决方案。

主要分为三大模块。

第一模块多人语音聊天,我们在里面做了四种适配,第一种是对接一线网络运营商,节点资源丰富,无上限扩大容量。第二种是针对回声消除进行的算法优化。第三种是降低端到端延迟,让语聊更快。第四种是适应多种复杂网络,同时兼容5000+安卓机型。

第二个模块是音乐播放,单纯语音聊天比较单调,通过播放背景音乐或者气氛音效提升活跃度。我们支持播放MP3、MP4格式的背景音乐文件,支持播放器将播放的音频混入推流中,同时支持音效播放器的音频文件。

第三个模块是支持APP后台保持,切换到游戏实现语音开黑。

以上就是即构解决方案的三大模块,接下来介绍一下我们的优势,首先是多人上麦语音聊天以及上下麦平滑切换,其次是支持实时变声、立体声、气氛音效、混响等多种音频效果,第三是支持弹幕、点赞、送礼等多种消息类型,第四是先进的不连续发射(DTX)和语音活动检测(VAD)技术,这两个技术会检测当前用户是否在说话,如果正在说话,我们将他的声音录制下来推出去,如果不说话的话,我们会发空白帧,减少用户的流量。

除此之外,还有各种配套的功能支持,这里有音效播放器、媒体播放器、混音、混响、声浪与音频频谱、媒体次要信息以及房间信令。声浪与音频频谱用来展示当前谁在说话与频域分量信息,媒体次要信息属于H.264中的一个类型,用来发用户的自定义消息。

语聊房搭建实战

第三部分进入我们的语聊房搭建实战环节。

首先,介绍一下我们语聊房的技术架构。

语聊房把用户分为两种,一种是麦上用户,一种是麦下观众。对于麦上用户来说,A连麦者需要推出自己了流A同时再去拉B的流,B连麦者也是一样的,在上麦时将自己的流推出去,推到服务器,同时将A的流拉过来,这时A和B就可以进行语音互动。麦下的用户只需要拉A和B的流收听即可,麦下的观众可以有很多个。最右边的混流服务可以根据业务需求自行选择,有需要的可以用,没有需要就可以不用,混流可以将A和B的流混成一条流,转推到CDN,观众再从CDN拉流过来,这也是节省成本的一种方式。

接下来我们讲一下语聊房的集成(代码部分)。

由于本人是iOS开发,接下来会给各位展示下用OC实现语聊房集成。可以参考Zego音视频集成文档。 (https://doc-zh.zego.im/article/196)


- (void)createEngine{//创建引擎ZegoEngineProfile *profile = [[ZegoEngineProfile alloc] init];profile.appID = kKTVAppID;profile.appSign = kKTVSign;profile.scenario = ZegoScenarioGeneral;self.engine = [ZegoExpressEngine createEngineWithProfile:profile eventHandler:self];//设置音频编码配置ZegoAudioConfig *config = [[ZegoAudioConfig alloc] initWithPreset:ZegoAudioConfigPresetStandardQuality];config.channel = ZegoAudioChannelMono;config.codecID = ZegoAudioCodecIDLow3;[self.engine setAudioConfig:config channel:ZegoPublishChannelMain];
//设置监听声浪回调[self.engine startSoundLevelMonitor];

首先需要创建引擎,创建引擎的时候需要设置一个配置,配置是ZegoEngineProfile对象,ZegoEngineProfile对象需要设置三个参数:appid、appsign、scenario。appid和appsign可以到zego官网申请获得。

这里需要重点讲解下scenario这个参数。


/// Application scenario.typedef NS_ENUM(NSUInteger, ZegoScenario) {/// General scenarioZegoScenarioGeneral = 0,/// Communication scenarioZegoScenarioCommunication = 1,/// Live scenarioZegoScenarioLive = 2

scenario这个参数是个枚举值,通过SDK接口可以看到有三个值。第一个General适用在对音质要求高的场景,例如在线KTV。设置这个参数后SDK内部会关闭系统的回声消除,我们也称这个配置为媒体音量模式。第二个和第三个枚举值设置后SDK内部会开启系统回声消除,我们称为通话音量模式,通话音量的效果就跟使用手机的电话通话时候的效果一样。因为是使用回声消除算法会对音质有损伤。一般使用在语聊场景,在线教育场景。语聊房场景下使用Communication即可。

接下来咱们设置下音频编码配置,先初始化一个ZegoAudioConfig对象,然后咱们设置下音频码率为48k,使用默认参数即可。然后设置下声道数为Mono,在语聊场景下人声使用双声道有点浪费带宽,也不需双声道的效果。音频编码格式为Low3,可以降低端到端延迟,提高用户体验。最后设置下音频配置。

在语聊房中咱们通常会需要在麦位上展示声浪,这里需要打开声浪的开关。声浪分为本端声浪和远端声浪。这里有两个回调可以处理声浪。这两个回调接口中都带有soundLevel参数,这个表示音量的大小,可以根据音量大小去决定是否展示声浪。


//本端声浪- (void)onCapturedSoundLevelUpdate:(NSNumber *)soundLevel {if ([self.delegate respondsToSelector:@selector(onCapturedSoundLevelUpdate:)]) {[self.delegate onCapturedSoundLevelUpdate:soundLevel];//拉流声浪- (void)onRemoteSoundLevelUpdate:(NSDictionary *)soundLevels{if ([self.delegate respondsToSelector:@selector(onRemoteSoundLevelUpdate:)]) {[self.delegate onRemoteSoundLevelUpdate:soundLevels];

接下来咱们需要登录房间。登录的时候需要设置用户信息,用户信息包括用户ID和用户昵称,以及房间号。


- (void)joinRoomWithRoomID:(NSString *)roomID userID:(NSString *)userID userName:(NSString *)userName{ZegoUser *user = [ZegoUser userWithUserID:userID userName:userName];ZegoRoomConfig *config = [ZegoRoomConfig defaultConfig];self.roomID = roomID;[[ZegoExpressEngine sharedEngine] loginRoom:roomID user:user config:config];

登录房间后怎么判断登录成功了?咱们需要在房间的回调中进行处理,这个回调是onRoomStateUpdate。这个回调中有个房间状态枚举值,对应有三种状态。

/// Room state.typedef NS_ENUM(NSUInteger, ZegoRoomState) {/// Unconnected state, enter this state before logging in and after exiting the room. If there is a steady state abnormality in the process of logging in to the room, such as AppID and AppSign are incorrect, or if the same user name is logged in elsewhere and the local end is KickOut, it will enter this state.ZegoRoomStateDisconnected = 0,/// The state that the connection is being requested. It will enter this state after successful execution login room function. The display of the UI is usually performed using this state. If the connection is interrupted due to poor network quality, the SDK will perform an internal retry and will return to the requesting connection status.ZegoRoomStateConnecting = 1,/// The status that is successfully connected. Entering this status indicates that the login to the room has been successful. The user can receive the callback notification of the user and the stream information in the room.ZegoRoomStateConnected = 2

咱们首先需要判断状态是否为ZegoRoomStateConnected,然后在判断errorCode是否为0。这个时候就是登录房间成功。如果状态为ZegoRoomStateConnected但是errorCode不为0,表示当前情况为掉线重连成功,errorCode会显示对应的错误码。退出房间也是一样的道理。

- (void)onRoomStateUpdate:(ZegoRoomState)state errorCode:(int)errorCode extendedData:(nullable NSDictionary *)extendedData roomID:(NSString *)roomID {if (state == ZegoRoomStateConnected && errorCode == 0) {if ([self.delegate respondsToSelector:@selector(onLoginRoom)]) {[self.delegate onLoginRoom];

登录房间成功后需要拉流。一般情况下,在语聊房中除了房主其他用户登录房间后都不会马上推流,需要上麦后才推流。房主登录房间后可以在onRoomStateUpdate回调中推流,推流接口为:

- (void)startPublishingStream:(NSString *)streamID channel:(ZegoPublishChannel)channel;

拉流接口为:

- (void)startPlayingStream:(NSString *)streamID canvas:(nullable ZegoCanvas *)canvas;

这里需要说明下,ZegoSDK是按照流去设计接口。其他市面上的厂商的SDK设计理念不一样,他们是按照角色和场景SDK内部就实现了推拉流。使用ZegoSDK需要手动去推拉流。推流时机一般是在登录成功后或者上麦成功后。拉流时机为登录房间后且在流变更回调中去拉流。

流变更回调为onRoomStreamUpdate。

这个回调用有ZegoUpdateType枚举值,对应的是流新增和流删除。当某个用户推流成功后房间内其他人会触发流新增回调,当某个用户停止推流后房间内其他人会收到流删除回调。所以在这里实现拉流的操作即可。


- (void)onRoomStreamUpdate:(ZegoUpdateType)updateType streamList:(NSArray *)streamList extendedData:(nullable NSDictionary *)extendedData roomID:(NSString *)roomID {if (updateType == ZegoUpdateTypeAdd) {for (ZegoStream *stream in streamList) {[self.playStreams addObject:stream.streamID];[self.engine startPlayingStream:stream.streamID canvas:nil];if ([self.delegate respondsToSelector:@selector(onUserJoinedWithStreamdID:)]) {[self.delegate onUserJoinedWithStreamdID:stream.streamID];}else if(updateType == ZegoUpdateTypeDelete){for (ZegoStream *stream in streamList) {[self.playStreams removeObject:stream.streamID];[self.engine stopPlayingStream:stream.streamID];if ([self.delegate respondsToSelector:@selector(onUserLeavedWithStreamdID:)]) {[self.delegate onUserLeavedWithStreamdID:stream.streamID];

以上的功能实现集合在一起就可以搭建一个简单的语聊房。

如果需要播放音乐可以使用媒体播放,接下来咱们创建个媒体播放器。


self.mediaPlayer = [[ZegoExpressEngine sharedEngine] createMediaPlayer];

播放之前需要先加载资源,使用loadResource接口,然后调用start播放即可。

以上就是集成语聊房需要用到的基本接口,其他接口可以参考文档集成。

常见问题——幽灵麦

接下来咱们聊一聊语聊房场景的问题。

比较常见的坑就是幽灵麦的问题,用户已经不在麦上了,但还能听到他的声音。

针对幽灵麦问题,我们提出了三种解决方案:


  1. 使用Token鉴权:即用户在登入房间时,对其身份进行校验,如果校验不成功,则不允许其进入房间。

  2. 流ID不和用户ID绑定:我们常遇到的场景是会将流ID和用户ID进行绑定,使用用户的ID当做流ID进行推拉流。比如一个用户登录房间A进行聊天,此时直接关闭APP,立即重新登录房间B,并上麦推拉流。由于流ID和用户ID是一样的,我们很难发现用户是什么时候掉线的,并且在用户掉线时,会自动尝试重连,重连有90s的时间,如果在这个时间内产生了上述操作,那么,在之前房间A拉的流没有停止,所以还是能听到他的声音。如果使用流ID不和用户ID绑定的方案,每次登录房间后推流的ID不一样,即使上一次的流链接还存在,但是没有数据,也就不会出现幽灵麦的问题。

  3. 麦位管理配合流变更通知:常用的麦位管理会建议用户使用第三方麦位管理,同时为避免不稳定,可以配合流新增的回调做处理。如果我们这里流触发新增了,再更新UI显示在麦上,如果流没有新增,即使第三方麦位管理显示已经成功上麦,说话也不成功,删除下麦也是同理。


以上是本次分享的全部内容,谢谢大家。

Q&A

01 在多人通话连接或聊天当中,环境不同造成的大量回声和噪声嘈杂,有哪些处理保证通话质量?

我们会在创建引擎时,会选择Communication场景模式,在此模式下,使用系统回声消除会把回声消除掉以及压制噪音。这就像我们平时用手机系统打电话时的效果,已经把它消得特别干净了。如果你一定要使用General场景的话,我们也提供额外的软件AEC进行处理,同时对噪声也有个ANS,可以将它们打开。

02 是用WebRTC吗?

目前没有使用WebRTC,用的是原生语言开发的,底层是C++。

04 语聊房目前的应用场景多吗?和实际应用的状况怎么样?

语聊房目前应用场景是挺多的,之前也提到过1V1聊天房、多人语聊房、语音电台、KTV语聊房,目前用的比较多的是多人语聊房,它在不同的APP都有非常多衍生玩法。

04 本次演讲没有提到录音功能,有很多人希望聊天能够被记录下来,后期剪辑变成更适合输出和保存的内容,想问下有没有类似的功能?

语聊房是有录制功能的,可以在本地保留数据,再进行本地录制,也可以在远端进行录制,主要看实际的场景需求。具体可以在即构官网开发者中心下的文档中心中搜索,会有详细的介绍。开发者文档中心链接:https://doc-zh.zego.im

(视频回放地址:

https://sh2022.livevideostack.cn/live/4963)

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
心内科主任含泪忠告:宁可打牌,也别在夏天做这6件要命的事

心内科主任含泪忠告:宁可打牌,也别在夏天做这6件要命的事

岐黄传人孙大夫
2026-07-16 12:16:51
没完没了?央媒表态后,韩红又迎“噩耗”,谢霆锋、李荣浩被牵连

没完没了?央媒表态后,韩红又迎“噩耗”,谢霆锋、李荣浩被牵连

阿讯说天下
2026-07-15 11:47:43
满屏荷尔蒙!这一脱,又是9分新剧

满屏荷尔蒙!这一脱,又是9分新剧

i书与房
2026-07-14 07:23:57
WTA250雅典站郑钦文下轮比赛对手已确定 比赛时间已基本确定

WTA250雅典站郑钦文下轮比赛对手已确定 比赛时间已基本确定

宝哥精彩赛事
2026-07-16 14:29:13
郑钦文翻身!时隔13个月又进8强:连续2轮送油条,排名提升14位!

郑钦文翻身!时隔13个月又进8强:连续2轮送油条,排名提升14位!

刘姚尧的文字城堡
2026-07-16 08:23:56
一家瑞典二手车商分析了近万辆特斯拉电池数据,发现更便宜的电池版本反而更耐用

一家瑞典二手车商分析了近万辆特斯拉电池数据,发现更便宜的电池版本反而更耐用

灰度测试中
2026-07-16 01:18:16
杨振宁去世5个月后,49岁翁帆现状:剪了头发染了色,仍独居国内

杨振宁去世5个月后,49岁翁帆现状:剪了头发染了色,仍独居国内

照见古今
2026-03-26 19:06:28
当今社会环境,已经卷到没边了

当今社会环境,已经卷到没边了

细说职场
2026-07-10 14:30:23
世界杯封神!1 亿巨星拒绝曼城铁心加盟阿森纳,完美接班梅里诺

世界杯封神!1 亿巨星拒绝曼城铁心加盟阿森纳,完美接班梅里诺

澜归序
2026-07-16 02:49:35
瓜迪奥拉:39岁的梅西仍在统治足球,英格兰面对的是历史最强大脑

瓜迪奥拉:39岁的梅西仍在统治足球,英格兰面对的是历史最强大脑

体育闲话说
2026-07-16 07:22:19
26岁小哥扮NPC飙英文火了!网友:以为是本地龟,原来是海归

26岁小哥扮NPC飙英文火了!网友:以为是本地龟,原来是海归

韩小娱
2026-07-16 10:28:19
万斯:我对美国人失望

万斯:我对美国人失望

极目新闻
2026-07-16 11:40:08
雷军详解澎程 N90 七座布局:前两排做客厅,第三排多坐一人

雷军详解澎程 N90 七座布局:前两排做客厅,第三排多坐一人

爱范儿
2026-07-15 17:50:18
多家NFC果汁生产车间被曝没有水果,全靠水+浓缩汁勾兑

多家NFC果汁生产车间被曝没有水果,全靠水+浓缩汁勾兑

21世纪经济报道
2026-07-16 16:41:03
发现中国有一个奇怪社会现象:父母不在人世间了, 什么舅舅姑姑表兄弟, 还有一些八竿子打不着的亲属, 基本上就形同陌路,不再相互往来

发现中国有一个奇怪社会现象:父母不在人世间了, 什么舅舅姑姑表兄弟, 还有一些八竿子打不着的亲属, 基本上就形同陌路,不再相互往来

背包旅行
2026-07-13 15:12:59
好人真有报?张雪前脚捐500万救灾,后脚自家机车“无人驾驶”冲上热搜

好人真有报?张雪前脚捐500万救灾,后脚自家机车“无人驾驶”冲上热搜

糖逗在娱乐
2026-07-16 15:26:50
医生发现:过了67岁,血糖若能保持在这个范围,或许可以放宽心了

医生发现:过了67岁,血糖若能保持在这个范围,或许可以放宽心了

路医生健康科普
2026-07-14 16:30:07
2万亿损失打水漂?中国这招太狠,吃光全球存量,日本有钱没处买

2万亿损失打水漂?中国这招太狠,吃光全球存量,日本有钱没处买

坠入二次元的海洋
2026-07-15 12:11:17
两名高中生早恋被叫家长,双方父母碰面没指责,反倒越聊越合拍

两名高中生早恋被叫家长,双方父母碰面没指责,反倒越聊越合拍

爱下厨的阿椅
2026-07-15 19:22:26
上海直飞乌鲁木齐机票价格低至50元?购票平台:能够购买到就可以使用

上海直飞乌鲁木齐机票价格低至50元?购票平台:能够购买到就可以使用

金融界
2026-07-16 17:20:46
2026-07-16 19:04:49
即构科技ZEGO
即构科技ZEGO
一站式的实时音视频通讯云服务
644文章数 60关注度
往期回顾 全部

科技要闻

苹果AI终于要来了:还能追上华为豆包们吗

头条要闻

女童溺水6分5秒后死亡:叔叔玩手机 无证救生员未发现

头条要闻

女童溺水6分5秒后死亡:叔叔玩手机 无证救生员未发现

体育要闻

逆天6后卫神阵,图赫尔活活坑死英格兰

娱乐要闻

天下无不散宴席!白鹿官宣告别欢娱

财经要闻

韩国股市暴涨暴跌 借钱炒股的散户快疯了

汽车要闻

ADS 4全系无缝升级5.0 华为乾崑发布乾崑智驾ADS 5与鸿蒙座舱OTA计划

态度原创

旅游
数码
家居
本地
公开课

旅游要闻

泰国签证新政获批:看似“收紧”,实则“疏导”

数码要闻

小米米家中央空调风管机巨省电Pro 3匹/ 4匹上架预售

家居要闻

2026建博会(广州) 公装联探展交流活动

本地新闻

人生必去清单:那达慕大会开嗨!

公开课

李玫瑾:为什么性格比能力更重要?

无障碍浏览 进入关怀版