Microsoft Azure

Microsoft Azure 媒体服务

Gregory Prentice

下载代码示例

多年来,Microsoft 一直在帮助设计和支持大规模的、实时传送视频流的传输。 一个最好的例证是 2014 年索契冬季奥运会。 这需要大量的技术资源,包括硬件服务器、源视频流、编码、服务器冗余(双数据中心)、输出自适应视频流、内容传送网络 (CDN)、合作伙伴公司,当然还有 Microsoft 员工。

需要动用所有这些资源以及客户软件开发来确保端到端实时视频事件顺利执行,而无(或很少)意外状况发生。 协调这些资源的成本反映了实时传送视频流事件的规模。 购买所需服务器、转换器和相关技术需要大量资金。 这将导致存在显著风险以及以下问题:

  • 所购买的用于处理实时事件规模的硬件是刚好足够还是过多?
  • 在下一个事件开始之前您如何处置所述硬件?
  • 所获得技术的使用价值还能持续多久?
  • 是否与正确的技术伙伴合作,以确保事件的协调策划完美无误?

考虑到 Microsoft 在实时视频事件上的投入、知识和取得的成功,Microsoft Azure 媒体服务团队开发了实时传送视频流来减轻这些风险。 基于 Microsoft Azure 媒体服务,团队成功地流式传输了 2014 年索契冬季奥运会的全球实时视频源。 因为那是一个极其大型的活动,Microsoft Azure 提供按需型硬件来处理稳定性问题。

根据实时视频活动的大小,一次对 Azure 媒体服务的请求可能会创建一个(小型、中型或大型)向数以十万计或几百个观众提供实时流式视频的规模单位。 定价允许通过“即付即用”模型来购买、使用和推出实时传送视频流服务,费用在活动之前公布。 硬件和基础结构不断升级和刷新。 Microsoft 还维护与传输实时传送视频流解决方案相关的策略关系。

在本文中,我将集中讨论的示例方案将使用来自 Microsoft Azure 媒体服务团队的新型实时传送视频流(当前为个人预览版本),处理上述风险,并讨论实时传送视频流供应与现有点播视频 (VOD) 服务的关系。

概念和术语

务必了解关于 Azure 媒体服务的通用概念和术语。 术语“渠道”指开发人员对实时视频流通过 Azure 媒体服务所采用的完整端到端路径的看法。 一个渠道可以有多种状态,最重要的两个是“停止”和“运行”。渠道包括以下通过系统协调视频流的组件:

  • 插入 URI:代表渠道在此接收一个或多个视频比特率流以便进行传输的一个入口点。
  • 预览 URI:代表被渠道接收的实时流的出口点,只可用于监控目的。
  • 程序:与渠道相关联,且代表作为资产保存在 Blob 存储中的实时流的一部分。 至少应有一个程序在渠道上创建,并处于运行状态以启用实时视频流。 程序在运行状态下将积极捕捉视频。
  • 资产:与一个程序相关联,代表存储于 Blob 存储中的数据。 一个资产可能包含一个或多个文件,包括视频、音频、图像、缩略图集和清单。 程序被删除之后,资产仍可继续存在。
  • 定位器:与资产和来源相关联。 定位器提供用作实时程序流出口点的 URI。
  • 来源:与定位器关联,代表视频流从一个资产定位器 URI 以多种比特率 (MBR) 格式(如 Smooth、HTTP 实时流 (HLS) 和通过 HTTP 传输的动态自适应流)进行传输的可扩展的出口点。

Azure 媒体服务确保创建合适的冗余,并可用于大规模的可信赖视频传输。 传输可能涉及多个使用不同流格式(如 Smooth、HLS 和 DASH)的设备。 图 1 显示了渠道的组成部分。

传输渠道是实时视频流的完整端到端路径
图 1 传输渠道是实时视频流的完整端到端路径

务必了解渠道和在其中创建的一个或多个程序之间的关系。 在图 2 中,一个实时视频活动已映射到一个渠道代表上, 该渠道从下午 5 点到凌晨 2 点处于运行状态。 务必了解渠道从停止状态到运行状态的过渡需要 10 到 20 分钟。 间隔标记 Concert1、Vip1、Act1、Act2 和 Vip2 代表程序及其计划的启动和停止时间。 最后,名称为“Transition”的间隔标记代表当前程序和下一个程序之间的时间,其中一个程序已停止,另一个程序已开始。

一个映射到下午 5 点启动、 凌晨 2 点结束的实时视频活动
图 2 一个映射到下午 5 点启动、 凌晨 2 点结束的实时视频活动

此示例展示了日程表如何通过程序映射到渠道。 如在图 2 中定义,有一个程序跨越了整个活动。

Concert1 将在下午 5:15 到凌晨 2 点处于运行状态,并有一个 10 分钟的滑动视频缓冲。 缓冲让用户在使用媒体播放器查看时可以后退。 Concert1 程序提供整个活动最主要的实时视频流。 在活动开始之前会为 CDN 提供 URI 以进行映射。

剩余程序 Vip1、Act1、Act2 和 Vip2 在定义的启动和停止时间(时间上应将过渡时间考虑在内而进行相应变化)之间应处于运行状态。 程序不会立即启动或停止。 在计划实时活动时您需要考虑到过渡状态。 您可以使多个程序同时处于运行状态,共同捕捉视频。 Concert1 和另一程序将在活动期间启动和停止。 为向您展示如何使用过渡,您可以在下午 6:45 发出一个 Vip2 的程序启动请求,然后在下午 7 点发出一个 Vip1 的程序停止请求,提供一段 15 分钟的过渡时间。 因此,在这 15 分钟的过渡期间,可有三个程序处于运行状态。

我已对基本概念和术语做了说明,接下来我将集中讨论对活动日程表的使用(如图 2 所示),该日程表映射到用户方案中,以利用 Azure 媒体服务 API 开发编码示例。

主题:Contoso’s Blues Bar

Contoso’s Blues Bar 是美国 著名的新秀音乐家演出场地,它在紧迫的期限内需要为一个名为“Contoso and the Shock Wallets”的大型欧洲乐队协调一个即将上演的现场演唱会。 该乐队在欧洲有大批乐迷。 在 Contoso’s 的表演将是他们在美国 的首次演出。 因此,演出经纪人需要流式传输实时演唱会视频,以便欧洲的乐迷可以在电脑和移动设备上观看表演。

Contoso’s Blues Bar 的 CIO 召开会议并要求他的技术团队研究并提出一个满足以下要求的解决方案:

  • 必须易于实施。
  • 必须可将视频流式传输到大量不同的设备配置。
  • 必须满足未知的扩展需求。
  • 成本基于活动期间使用的资源,即付即用。

冲刺 (sprint) 一

Contoso’s Blues Bar 的活动策划团队将接下来的几天用于定义他们的用户案例。 这些用户案例将是传输现场演唱会视频流的冲刺规划的基础。 会议期间,团队解释了一些将在冲刺一阶段导致一系列阻碍(或需解决的问题)的知识缺口。 团队还定义了大型用户案例的列表,通常称为“综述”,标准格式为“作为一个… 我想… 这样…”:

作为一个 Contoso and the Shock Wallets 的乐迷,我想在我的设备上观看尽可能高质量的实时演唱会现场视频,这样我就能欣赏到他们在美国 的首次演出。

作为一个 Contoso and the Shock Wallets 的乐迷,我想在之后的某个日期和时间在我的设备上观看尽可能高质量的演唱会现场视频,这样我就能在闲暇时间观看该演出。

作为 Contoso’s Blues Bar 的代理人,我想现场直播我们的演唱会并减少从我们的演出场地传输实时流式视频的费用,这样我们能在吸引更多的音乐家和顾客的同时节省资金。

用户案例和相关的问题调查包括:

用户案例 1.1:作为活动制作方工作人员,我想要一台或多台摄像机,这样我们就能拍摄到现场演唱会的视频。

问题 1.1.1:使用哪种类型的摄像机以及输出哪种视频流?

制作方工作人员了解到他们可以购买高质量的二手视频摄像机,并通过串行数字接口 (SDI) 输出高清 (HD) 视频/音频流。

用户案例 1.2:作为活动制作方的工作人员,我想将实时视频流式传输到 Internet,这样乐迷们就可以观看这场演唱会。

问题 1.2.1:摄像机拍摄的视频如何传输到制作站点?

制作方工作人员了解到 Contoso Switch Company 生产将 HD SDI 转换为光纤信号的视频转换器。 他们可以将此转换器与多达四台摄像机配合使用。

问题 1.2.2:视频源如何传输到 IT 部门?

制作方工作人员了解到光纤视频转换器将输出 HD SDI 视频/音频流,他们可以将其连接到一个音频/视频转换器。 他们即可以控制哪台摄像机信号在播放窗格中处于活动状态。 实时视频源最终将通过 HD SDI 连接从播放窗格发送。

用户案例 1.3:作为一名 IT 工作人员,我想将视频流传输到 Windows、iOS 和 Android 设备,这样演唱会视频就有最大程度的设备支持。

问题 1.3.1:我正接收何种类型的视频源,以将视频传输到 Internet?

HD SDI 视频源将发送至 IT 部门。

问题 1.3.2:目标设备需要何种类型的视频源?

IT 工作人员发现他们可以使用以下自适应视频协议来向各种目标设备传输视频:

  • 平滑流式处理:Windows 8 和 Windows Phone 8
  • HLS:iOS 和 Android
  • DASH:Windows 8.1、Windows Phone 8 和 Xbox One

问题 1.3.3:我如何以可扩展方式将视频传输到 Internet?

IT 工作人员了解到 Microsoft 发布了一个专门处理通过 Internet 流式传输实时视频的 Azure 新功能。 通过一些研究,团队发现 Azure 媒体服务可以提供演出场地和目标设备之间的中间层服务。 最重要的是,他们了解了关于 Azure 媒体服务的以下详细信息:

  • 一旦您注册了一个 Azure 帐户并添加一个媒体帐户,您 就可以创建一个实时传送视频流渠道。 实时渠道与电视渠道同义。 所有分配的服务器资源将用于该渠道以传输您的程序。 一个渠道可能有多个程序。 程序是一个时间段及其关联资产的定义。 资产是流式视频在 Azure 媒体服务中的存储位置。
  • 服务器的配置确保无单一故障点的视频路径中的冗余。
  • 一个实时视频流可由 Azure 媒体服务通过插入 URI 以 RTMP 或 MPEG 的格式接收。
  • 设备可请求在本地受支持的视频流。 Microsoft Azure 媒体服务将确保根据指定设备的 URI 将视频以合适的格式封装。
  • 实时传送视频流原始服务器支持 CDN 提供商(如 Akamai Technologies)的安全访问。

问题 1.3.1 和 1.3.2 的附加结果:IT 工作人员选择了一个编码器,该编码器可以接收 HD SDI 视频/音频流。 此编码器可以使用 HD SDI 流动态生成多个比特率流,以传输至 Azure 媒体服务,从而提供一个插入 URI,以接收作为输入格式的 RTMP 或 MPEG。

冲刺 (Sprint) 二

在例行的晨间咖啡时间之后,开发人员开始编写促进实时传送视频流事件的代码。

用户案例 1.4.1:作为一名开发人员,我想创建合适的 Azure 帐户,这样我就能开始编写流式传输视频的代码。

前往 Azure 网站 (azure.microsoft.com),单击“免费试用”按钮并执行以下步骤: 了解有关设置帐户的更多信息,请参阅 bit.ly/1mfacft。 在注册过程期间,您可以创建一个用作管理员凭据的 Windows 帐户。 若要创建 Azure 媒体服务帐户,您必须首先创建一个 Azure 存储帐户,因为实时活动的视频资产将存储在 Blob 存储中。 Azure 媒体服务文档还建议您在购买 Azure 媒体服务帐户的数据中心上创建存储帐户。 例如,在 US-WEST 数据中心中创建一个存储帐户和媒体帐户。

用户案例 1.4.2:作为一名开发人员,我想编写代码来管理渠道,这样我就能传输一个实时传送视频流事件。

使用 Visual Studio 2012 创建基础项目。 下一步,安装 Azure 媒体服务的 NuGet 包。 创建名为“CreateContosLiveEvent”并以 CloudMediaContext 对象开始的函数,该函数总是用于管理您的实时流:

private void CreateContosLiveEvent()
{
  string liveAccount = "yourAzureMediaAccount";
  string liveKey = "yourAzureMediaAccountKey";
  CloudMediaContext LiveServices = new CloudMediaContext(
    liveAccount,  //  之前创建的
    liveKey );    //  帐户名称

编写代码以确保原始服务运行。 原始服务会把实时流传输至 CDN 提供商,如图 3 所示。

图 3 原始服务将实时视频流传输至内容传送网络提供商

string originName = "abcdefg";
IOrigin origin = LiveServices.FindOrigin(originName);
if (origin == null)
{
  Task<IOrigin> originTask = 
    LiveServices.Origins.CreateAsync(originName, 2);
  originTask.Wait();
  origin = originTask.Result;
}
if (origin.State == OriginState.Stopped)
{
  origin.StartAsync().Wait();
}

然后您需要编写代码以创建一个渠道(如图 4 所示)。 渠道需要配置安全性以允许对传入视频流源进行身份验证。 源通常是配置了 IP 的编码器,该编码器将 HDI SDI 信号转化为所需的 MBR 视频流。

图 4 为您的视频源创建一个渠道

string channelName = "ContsoBluesChannel";
IChannel channel = LiveServices.FindChannel(channelName);
if (channel != null)
{
  Debug.WriteLine("Channel already exists!");
  return;
}
ChannelSettings settings = new ChannelSettings();
Ipv4 ipv4 = new Ipv4();
// 当前将 IP 设置为 0.0.0.0/0 将允许所有连接 
// 请勿为制作事件执行此项 
ipv4.IP = "0.0.0.0/0";
ipv4.Name = "Allow all connections";
// Protect the ingest URI
settings.Ingest = new IngestEndpointSettings();
settings.Ingest.Security = new SecuritySettings();
settings.Ingest.Security.IPv4AllowList = new List<Ipv4>();
settings.Ingest.Security.IPv4AllowList.Add(ipv4);
// 保护预览 URI
settings.Preview = new PreviewEndpointSettings();
settings.Preview.Security = new SecuritySettings();
settings.Preview.Security.IPv4AllowList = new List<Ipv4>();
settings.Preview.Security.IPv4AllowList.Add(ipv4);
// 创建 渠道 
Task<IChannel> taskChannel = LiveServices.Channels.CreateAsync(
  channelName, "video streaming", ChannelSize.Large, settings);
taskChannel.Wait();
channel = taskChannel. Result;

示例代码为插入和预览 URI 配置一个设置为“0.0.0.0/0”的无类别域际路由选择 (CIDR) 格式的 IP 地址。这使得所有的 IP 地址均可访问插入和预览 URI。 对于制作渠道,建议您通过使用已知值(如您的编码器的 IP 地址或身份验证令牌的 IP 地址)限制访问。 使用唯一的渠道名称。 如果已存在相同名称的渠道则会发生异常。

编写创建程序、关联资产和定位器的代码,如图 5 所示。 用于名称和日程表的值与图 2 中显示的值有关。 一切项目(Concert1 除外)的程序创建期间,enableArchive 标志设置为 true。 值为 true 表示在程序运行期间一个实时视频流被捕捉,并保存在关联的资产中以便后期作为 VOD 使用。 访问策略为 30 天的定位器创建至资产的清单文件。 这向流式视频提供了一个 URI。

图 5 创建在您供应视频期间运行的程序

// 定义程序名称、DVR 窗口和预估的时长(以分钟为单位).
// 注意:当服务 
// 到了公共预览阶段,DVR 窗口值很可能被删除。
Tuple<string, int, int>[] programSettings = new Tuple<string, int, int>[]
{
  new Tuple<string,int,int>( "Concert1", 60, 60 ),
  new Tuple<string,int,int>( "Vip1", 75, 75 ),
  new Tuple<string,int,int>( "Act1", 90, 90 ),
  new Tuple<string,int,int>( "Act2", 165, 165 ),
  new Tuple<string,int,int>( "Vip2", 120, 120 ),
};
foreach (Tuple<string, int, int> programSetting in programSettings)
{
  IAsset asset = null;
  // 为了保留点播视频 (VOD) 特定程序的资产,此
  // 代码测试 DVR 窗口和事件持续时间的长度是否相等。
  // 如为 true,会将启用存档标志设为 true,这将告知 
  // 系统某个程序的资产不应自动删除.
  bool enableArchive = programSetting.Item2 == programSetting.Item3;
  try
  {
    // 创建的资产用于保留在程序运行和 VOD 时流式传输 
    // 的视频。
    asset = LiveServices.Assets.Create(programSetting.Item1 + "_asset",
      AssetCreationOptions.None);
    Task<IProgram> taskProgram = channel.Programs.CreateAsync(
      programSetting.Item1,
      "program description",
      // 现在启用存档笔记强制为 true true, // enableArchive,
    // 注意:DVR 窗口值很可能会被删除
    // 这是未使用的
    TimeSpan.FromMinutes(programSetting.Item2),
    // 预计持续时间
    TimeSpan.FromMinutes(programSetting.Item3),
      asset.Id);
    taskProgram.Wait();
    LiveServices.CreateLocators(asset, TimeSpan.FromDays(30));
  }
  catch (Exception exp)
  {
    Debug.WriteLine(exp.Message);
  }
}

您可以从定位器获得原始 URI,这与 Azure 媒体服务 VOD 资产一样。 然后您将其提供给选择的 CDN 提供商。 因为 enableArchive 标志已设置,一旦程序停止,您就可以使用同一个原始 URI 将实时流作为 VOD 资产传输。

剩下的任务就是编写代码以在需要的时候启用渠道和程序。 启用渠道的请求发出信号使 Azure 媒体服务开始为传人服务、冗余和加载平衡配置资源。 渠道启用时,启动状态和运行状态之间的过渡会花费 10 到 20 分钟。

活动开始前,您应提前足够长的时间启用渠道,而不至于影响查看实时视频流的能力。 还有一点务必注意的是,一旦您的渠道被启用即开始计费。 如果您没有运行全天候实时渠道的计划,您应该在不使用的时候停用渠道和关联程序。 启动渠道所需的实际代码非常简单:

// 启动渠道
Task start = channel.StartAsync();
start.Wait();

启动程序所需的代码也非常简单明了:

start = program.StartAsync();
start.Wait();

活动的一个基本要求是控制渠道和每个程序开始和停止的时间。 因此,下一个需开发的项目是一个简单的 UI,该 UI 将通过调用 CreateContosLiveEvent 方法创建作为一个整体的活动。 这将允许根据需要启用和停止渠道和每个相应的程序。

结束此方案,因为您已使用 Azure 媒体服务开发了应用程序,其他团队成员一直忙于设置摄影机、布置电缆、安装视频编码器以及配置 CDN。 最后,工作人员执行一系列的测试以确保端到端的方案可行。

一旦真正的演唱会即将开始,一个实时视频流开始输出,不同的用户设备、台式电脑和平板电脑连接至 Azure 媒体服务以观看实时视频流。 总会出现一些测试期间未考虑到的问题,但是工作人员将其一一解决,所有的艰苦工作均及时完成以输出演唱会的实时视频流。

艰巨的任务变得更加容易

举办大规模的实时视频活动会是一项艰巨的任务。 在 Azure 媒体服务这样的解决方案出现之前,传输实时流式视频通常需要基础设施方面的大量资本开销。 其他关键决策包括支持大小和规模不同的活动所需的系统数。 这方面的购买通常不是配置得过多就是配置得过少。 Microsoft Azure 媒体服务解决此复杂性和成本。 Live 服务在 Azure 媒体服务 VOD 功能集上构建,它能提供一个简单、统一的平台和 API 以向行业输出大规模的实时内容和 VOD 内容。


Gregory Prentice 是一位富有经验的软件架构师,具有 25 年为多家新创公司设计和创建应用程序的经验。他开始为 Microsoft 工作以来开发了以下项目:Locadio、Microsoft Hohm 和 Microsoft Utility Rates Service。最近,他帮助 Microsoft Azure 媒体服务和 Delta Tre 团队传输了 2014 年索契冬季奥运会的实时视频流。他目前是 Microsoft 开发人员平台推广小组的推广专家。您可以通过以下网址阅读他的博客:blogs.msdn.com/b/greg-prentice

衷心感谢以下 Microsoft 技术专家对本文的审阅:Steven Goulet,Live 服务的主要项目经理:以及 Jason Suess,上届奥运会的 Live 服务