多用户多平台直播教程

对于与其他创作者的协作直播,有一些非常好的解决方案。但如果你也像我一样觉得价格有点小贵,那你肯定也希望它们可以自定义。值得庆幸的是,Agora 就可以帮你创建自己的服务!

要求

由于这个项目很大,因此本文将其分解成几个重要的概念。如果你想要完整的代码,你可以点击以下链接:GitHub仓库地址

应用总述

在切入要点之前,让我们先理清我们的目标以及实现的方法。此应用程序的目标很简单:通过用一个能管理用户和传到流平台内容的主机应用程序,允许多个用户加入并将他们的视频传输到流媒体平台上。

应用程序的流程尽可能简单。从主屏幕开始,输入你尝试加入的频道和自己的姓名。然后你有两个身份选择:主播或是观众:

  • Director: 管理所有用户以及流发送的位置和方式
  • 参与者: 加入通话并有一个用于协作的简易通话界面

在本文中,我们不会具体介绍 Agora 的基础知识及其工作原理。如果对 Agora不是很了解,可点击以下链接做简单了解:

观众视图

live-streaming-to-multiple-platforms-with-multiple-users-agora-2

本教程不会在观众视图上花费太多时间。这里的逻辑应该与其他类型的视频通话非常相似,除了以下四个方面:

  • 当用户第一次加入大厅时,他们的摄像头和音频是关闭的。
  • 当主播让他们上麦时,他们的视频和音频应该打开。
  • 视频和音频可由主播控制。
  • 其他观众不会看到通话中的其他人。

使用该设备的人应该不会发现与常规视频通话之间的明显区别。唯一的区别是他们在加入通话之前看到的大厅屏幕。如果舞台上有人,当前参与者可以看到他们,即使当前参与者尚未在舞台上,他们会查看发送到流媒体平台但没有自定义转码的输出通话。现在,所有复杂的操作都是使用 Agora 的 RTM 消息完成的。

RTM消息

由于这不是一个简单的视频通话应用程序,因此发起者需要某种方式来控制参与者。为此,我们将使用agora_rtm 包。这个包允许频道中的每个人之间发送实时数据。该agora_rtc_engine 软件包建立在agora_rtm 顶端, 不同的是,RTM 允许你发送任何数据,而 RTC 则可以轻松发送视频和音频数据。对于此应用程序,只有发起者可以发送 RTM 消息,参与者只能接收。我们需要给予发起者三种功能:

  • 对音频静音或取消静音。
  • 启用或禁用视频。
  • 发送活动用户列表。

为了使用户静音,发起者以“mute uid”格式发送通道范围的 RTM 消息,其中“uid”被替换为要静音用户的特定uid 。收到此消息后,参与者检查这uid 是否是他们的uid . 如果是,则用户将自己静音。除了使用关键字“unmute uid”、“enable uid”和“disable uid”之外,取消静音、禁用和启用视频的工作方式相同。

稍微棘手的部分是使用户活跃。通常情况下,如果你使用 Agora,就会显示该通话中的所有直播公司。但在这种情况下,其中一些在大厅中,因此不应向观众展示。为了解决这个问题,我们再次使用 RTM 消息发送所有应该 显示的用户。格式为“activeUsers uid,uid,uid”,其中“uid”替换为活动用户的特定uid

到目前为止,从参与者的角度来看,我们几乎涵盖了所有内容。现在让我们讲发起者这部分,这是最神奇的部分。

指挥控制器

此应用程序中控制器有很多功能和要跟踪的东西。为了让事情井井有条,我们将为Flutter使用 流行状态管理解决方案riverpod

如果你从未使用过 Riverpod,这里是一个很好的起点:https://www.youtube.com/watch?v=8qzip8tVmqU

我们在此处定义的DirectorController 会成为一个StateNotifierProvider 。这有助于将我们的业务逻辑与应用程序的 UI 部分分开。

该控制器包含我们可以访问代码的函数,包括joinCall()leaveCall()toggleUserAudio()addUserToLobby()promoteToActiveUser()startStream() 等等。该控制器还将存储我们要在应用程序中跟踪的所有数据。

由于参与者只接收 RTM 消息,所以指挥器只发送 RTM 消息。

为了让指挥控制器发送 RTM 消息,你需要使用 RTM 设置客户端和通道。这与 RTC 引擎在幕后运行的情况非常相似。你需要创建并登陆客户端,然后创建频道并加入频道。完成此操作后,你就可以发送 RTM 消息了。参与者需要做同样的事情才能在onMessageReceived 回调中接收消息。

要发送消息,你需要使用该sendMessage 频道提供的功能。要正确格式化消息,需使用以下命令:

对所有其他消息使用相同的方法,例如“静音 uid”、“启用 uid”、“禁用 uid”和“activeUsers uid,uid,uid”。

所以这些是使我们能够管理用户和流的基础设施细节。让我们详细了解这个应用程序的指挥部分是如何工作的。以下是要介绍的三个主要功能:

  • 静音和禁用其他用户的视频
  • 在舞台和大厅之间移动用户
  • 转码每个视频并将其推送到流媒体平台

静音和禁用视频

现在我们已经设置了所有带有 RTM 消息传递的基础设施,这部分可能听起来微不足道,但实际上有很多部分都需要考虑并做到同步。

  • 对音频静音/取消静音。
  • 禁用/启用用户的视频。
  • 用户音频和视频的当前状态。
  • 用户更改自己的状态时更新。

参与者应用

  • 自己静音/取消静音。
  • 禁用/启用自己的视频。
  • 从指挥器中静音/取消静音。
  • 禁用/启用来自发起者的视频。
  • 音频和视频的当前状态。

要完成所有这些并使其同步,很多部分可以控制音频。解决此问题的最佳方法是查看各种场景:

  • 参与者将自己静音/取消静音。 当参与者决定将自己静音时,他们需要调用 muteLocalAudioStream() 并更新自己的按钮状态以显示他们已静音。在指挥端,触发remoteAudioStateChanged 事件 ,它应该更新该特定用户的当前状态。

  • 参与者禁用/启用视频。 除了调用函数muteLocalVideoStream() 外,过程同上。指挥器事件应该是remoteVideoStateChanged

  • 指挥器将用户静音/取消静音。 Director 需要发送带有“mute uid”或“unmute uid”的 RTM 消息。然后匹配的用户uid 将执行与他们自己静音一样的执行。指挥器应该再次看到remoteAudioStateChanged 事件触发器,他们可以更新本地状态。

  • 指挥器禁用/启用视频。 与静音相同的过程,但流消息将是“启用 uid”或“禁用 uid”。

让我们为此加一点难度。

舞台和大堂

这里并不太复杂,但它有一些需要注意的事情。唯一能同时看到大厅和舞台的人是指挥。在DirectorController 将举行的活跃用户和大堂用户的单独列表。参与者用户的正常流程是加入频道并直接添加到大厅。然后指挥器完全控制,可以随意移动它们进出舞台。

将人移入和移出舞台的流程非常相似。首先,将它们从上一个列表(大厅或活动)中删除,然后将它们添加到另一个列表中。接着更新并使用 RTM 消息activeUsers 向所有人发送新的列表。

效果还不错,但这就是难点。你不希望大厅用户能在舞台上与其他用户交谈,因此他们应该在大厅中被静音。而且由于他们在大厅里,因此也不需要为他们的视频占用额外的带宽。因此,我们需要为音频和视频控制添加更多场景:

  • 参与者首先加入频道。 由于它们是直接添加到大厅中的,因此需要立即将它们静音并禁用其视频。每当参与者加入频道时,他们会自动将自己静音。
  • 参与者走上舞台。 当他们移到主舞台时,需要启用他们的视频和音频,以便观众可以看到他们。这应该遵循与导演取消静音或启用视频相同的逻辑。
  • 参与者移到大厅。 当他们被移动到大厅时,他们的视频和音频需要启用,以便观众可以看到和听到他们。这应该遵循与指挥器静音或禁用视频相同的逻辑。

转码

live-streaming-to-multiple-platforms-with-multiple-users-agora-3

activeUser 列表与应用程序的指挥部分和应用程序的参与者部分同步后,最后一步是将其直播到流媒体平台。为此,我们首先将所有传入的视频转码为所需的布局,然后使用实时消息传递协议 (RTMP) 将我们的流发布和取消发布到所需的平台。

首先,我们需要定义输出视频的布局。在这种情况下,我们最多只能支持 8 人的通话。但是你可以根据需要将相同的概念扩展到任意数量的用户。我们还考虑到我们的流将是 1080p 流,因此我们有 1920×1080 像素可供使用。鉴于这些信息,布局将如下所示:

要发送此信息,我们需要创建一个列表TranscodingUser 并相应地设置每个用户布局。一旦它们在列表中,我们就用列表创建一个LiveTranscoding 对象,并告诉RTCEngine 这是我们理想中的布局。

现在我们已经配置了音视频流的布局,我们需要发送它。使用此应用程序,我们可以将其发送到多个位置。为此,你将需要一个 URL,你的流应该被推送到该 URL。对于 YouTube,这非常简单。你将需要Stream Url + backslash ("/") + Stream Key ,这些都在你的直播仪表板中有所提供。Twitch 有一个类似的概念,你可以点击这里阅读: Twitch指南

现在,你已经拥有全部链接,用transcodingEnabled 调用RTCEngineaddPublishUrl() 到参数集true 。现在你的流应该已经出现在平台上了。

最后,当有人从主舞台添加或删除时,你将需要更新转码,并结束流。要更新,你需要相应地更新转码布局,然后setLiveTranscoding() 再次更新。要删除流,调用removePublishUrl() .

结论

如果这个应用程序看起来有点复杂,可事实就是如此。有些成熟的公司需要几个月的时间来为这样的事情创建建 MVP(最小可行产品)。即使他们可以创建它,他们也无法与 SD-RTN 带来的基础设施和可靠性相提并论。这是一个非常复杂的应用程序,但有了 Agora 就可以实现。

你可以在GitHub仓库找到此应用程序的代码。

原文作者 Tadas Petra
原文链接 https://www.agora.io/en/blog/live-streaming-to-multiple-platforms-with-multiple-users/

推荐阅读
相关专栏
SDK 教程
164 文章
本专栏仅用于分享音视频相关的技术文章,与其他开发者和声网 研发团队交流、分享行业前沿技术、资讯。发帖前,请参考「社区发帖指南」,方便您更好的展示所发表的文章和内容。