大多数浏览器和
Developer App 均支持流媒体播放。
-
HLS 低延迟简介
自 2009 年推出以来,HTTP Live Streaming (HLS) 已经在全世界提供了无数实时和点播音视频流媒体。随着全新低延迟模式的推出,现在可以大规模在公共网络上实现延迟不超过两秒,同时仍然向后兼容现有的客户端。了解如何开发和配置您的内容交付系统来利用这项新技术。
资源
- Enabling Low-Latency HTTP Live Streaming (HLS)
- HTTP Live Streaming (HLS) authoring specification for Apple devices
- HTTP Live Streaming Tools
- 演示幻灯片 (PDF)
相关视频
WWDC20
WWDC19
-
下载
(低延迟HTTP现场直播)
嘿!
下午好 大家下午好
我是Roger Pantos 今天关于HLS的演讲我们主要讲 低延迟 首先 当我们提到低延迟时什么是延迟呢?
嗯 在这个情境中 它指的是时间量 从摄像头开始记录视频时 或击中你的产品后台时 以及当用户 在家里在iPad或 Apple TV上观看视频时
缩短延迟的持续时间 保持简短的持续时间 对于某些类型的内容来说至关重要
其中我们很可能最熟悉的一种类型是 体育赛事现场直播 但对于最新消息来说也很重要 比如游戏直播 甚至比如奥斯卡颁奖这样的新闻 实际上 这对于任何有大量人群 同时观看同一个视频时的情况 都很重要 通常它存在社交因素 那么延迟需要有多低才能提供 良好的用户体验呢?
嗯 如今的金标准大约是二到八秒 这是由当前设备情况决定的 电视广播装置、电缆、卫星电视 因此 当我们设计低延迟HLS时 我们就给我们设置了一个目标 在任何合理的往返时间内 比公共互联网上的大规模直播 延迟一到两秒
现在我们不需要牺牲任何东西 就能实现
不需要牺牲任何功能就能让HLS 具备竞争力 因此我们仍采用品质来匹配 用户的网络速度 我们仍允许你保护你的内容 我们仍允许你插入广告 并提供程序边界和其它元数据
我们仍可以让你以经济有效的方式 把你的广播推广给数十万 使用CDN的用户
我们确保这些数据流向后兼容 因此你仍可以看到数据流在较老的 客户端上保持常规的延迟
我们是如何实现这些的?
嗯 要了解这个问题 我们首先要返回到常规的HLS 并了解我们是从哪里开始的
首先 从起初开始 HLS就被设计成一个 简单、强健的协议 那非常棒 事实上 如果你的内容 不在那些范围内 你知道的 我们刚才提到过的内容类型 你应该继续使用常规的HLS 并且那会很适合你 但那种简单是有代价的 当你观看体育赛事时 比如说 那种代价的表现通常是 你在Apple TV上 看到得分之前 你会先通过公寓的墙面听到得分
这是为什么呢? 嗯 要理解这个问题 让我们看一下常规HLS如何 从产品后台获取特定帧 并发送给在家里的用户 我们先看一下帧 我们要做的第一件事就是编码帧 并把它放到一个视频段中 现在我们推荐六秒钟为一段 但那确实意味着 因为我们是实时编码 因此甚至在你有能放在CDN上的 任何内容之前有六秒钟的空白
在我们得到那个视频段之后 客户端必须要发现它的存在 现今HLS使用查询机制 意思是客户端时常检查服务器端 看是否有最新的播放列表 从而了解是否有新内容 在最佳情况下 客户端可能会说 服务器端一向播放列表中 放入最新视频段就开始检查 这很棒 但通常我们不能实现那种 最佳情况 事实上 在某些情况下 甚至在客户端发现有新视频段之前 差不多还存在另一个六秒钟
在客户端发现之后 取回新播放列表 然后客户端必须转向反方向 并做另一个请求 才能实际上获得视频段 请记住 每个请求在网络上 都需要一段往返时间 在某些网络中 特别是蜂窝 这段时间可能在数百毫秒内 并不是无关紧要的
因此无论怎样 在客户端执行所有操作之后 视频段才开始流入客户端 然后一旦客户端获得足够多的视频段 它就开始呈现视频 在这个例子中 我们已经进入12秒区域了 但如果你通过CDN提交内容 我们绝大多数人都是通过CDN 提交内容的 可能延迟的时间更长
原因是 由于常规HLS与 CDN相交互的方式 让我们看一下
想象一下你获得了你的HLS视频流 你将其发布到右侧的视频源中 在特定时间内 它的播放列表有三个视频段 现在第一个客户端想查找最新、 最棒的媒体内容 如果客户端所通讯的 CDN边缘服务器 尚未缓存任何那种媒体内容 它实际上状况良好 因为它会请求播放列表 CDN将从源获取播放列表 获取最新版本并直接发送给客户端 客户端1状况良好 问题出现在一秒或两秒钟之后 当在源上 我们从众多视频段中得到了一个 新视频段并且播放列表也更新了 现在播放列表包含视频段1到4 那之后会发生什么? 当客户端2进入并再次查找时 “好的 有哪些最新内容?” 嗯 客户端2将取回的播放列表 是仅包含视频段1到3的 缓存播放列表 它甚至都不能发现有视频段4 因为CDN为它提供了播放列表的 缓存版本
为什么CDN会这样做呢?
嗯 它就不能给它提供最新版本吗? 嗯 问题是CDN没有办法了解 源上已经更新了播放列表 如果有每次有随机客户端进入 并说“嘿 最新播放列表是什么?” 它就进入并检查源 那会让源变得一团糟 因此CDN需要缓存一段时间 这叫做生存时间 生存时间越长 客户端查看 并看到过时的播放列表版本的 时间越长 并又把现场延迟时间拉长了那么多
所有问题都可以被修复
但在决定如何修复时 我们需要考虑更多因素
第一个是HTTP仍然是 通过因特网向数十万人 同时提交同一媒体内容的最佳方式 因此我们应该坚持用HTTP 但那样做意味着 我们坚持使用HTTP提交模型 那会给客户端分配不连续的视频段 不连续的资源块 如果它需要六秒钟才能产生那个 资源块 那么我们已经错过了我们的最终目标 如果我们能实现比现场 仅延迟一秒钟的最终目标 那么我们通过HTTP所分配的内容 就要缩水 在某些情况下会变得更短
我们要努力克服的下一件事 是现在对于可预见的未来 CDN对于帮助我们扩展到 全球规模的观众来说至关重要
但CDN最终 从本质上来说是HTTP代理缓存 它们会实现缓存要实现的功能 我们必须面对这个问题 而不是逃避它
最后一件事是 当我们延迟的时间非常接近现场时 我们只能提前缓冲非常少量的内容 因为那就是我们所得到的全部内容 因此 如果我们要执行比如切换到 一个不同的比特率 那么我们只能得到比如 在我们失速之前我们没有 十秒钟的时间来执行那个操作 我们可能只有不到一秒钟 因此我们要确保 切换机制要尽可能得高效 因为我们的执行时间很短
因此
我们查看了整个HLS提交模型 彻底查看 并且我们发现了需要做出 五处大的修改 从而实现这个比现场延迟 一到两秒的目标 我们要讲的第一件事 就是我们需要一种能把那个媒体内容 获取到服务器上的方式
时间要小于六秒 我们把它叫做减少发布延迟
我们的实现方式是 我们允许服务器 在主视频段准备好之前 先发布少量主视频段的部分内容 因此我们可以提前提交这些 少量的部分内容 我们要做的第二件事是 优化客户端发现视频段的方式 从而客户端可以迅速发现视频段 我们的实现方式是 修改客户端更新它的播放列表的方式 我们允许客户端在播放列表实际上 存在于服务器上之前 提前请求特定的播放列表更新 然后服务器端将保有那个请求 并关注播放列表 直到它更新了下一个视频段 那时你将立刻把播放列表发送回 客户端
客户端将在小于往返时间的时间内 发现播放列表 在这个模型中 每个单一播放列表更新 实际上都有一个不同的URL 这提供了一秒钟的优势 也就是 它让这些播放列表更新的缓存 变得更有效率了 因为每次更新都有不同的URL 每个更新看起来都像是一个独立的 可缓存的实体 现在发生的是 当客户端1想获得特定更新时 它会发出请求 CDN说“我从没听说过 我要直接去源那儿” 然后源会说“嗯 那是因为我还没有创建它” 因此现在它就离开了 一旦它获得那个更新 它就把更新传给CDN CDN直接传给客户端 下一个客户端进入时 它会说“我想要最新更新” CDN通过使用URL对其进行了 积极的识别 并说“给你吧” 后续的每个请求更新的客户端 都将立即获得CDN缓存 但下一次 此后第一个客户端或任何其它客户端 请求更新时
发送CDN的URL 将是不同的URL 因此CDN立即就知道它的缓存里 没有这个URL 它将不会传输过时的内容 相反它会立即返回到源 源说“嗯 我还没有创建” 然后一旦它创建好 它就把它传回给CDN 然后CDN传给客户端
因此
这些新播放列表更新请求是 固有的缓存破坏 那会让缓存在CDN上更好地运作
我们要做的第三件事是 消除额外的往返 在你发现一个视频段离开 并得到视频段自身之后 我们的实现方式是使用“推送” 当客户端请求下一个播放列表更新时 它会告诉服务器端 “顺便提一下 当你得到我所不知道的 下一个视频段的播放列表更新时 我希望你… 当你给我返回那个播放列表时 我希望你立即把那个视频段推送给我 那样我就不需要转向反方向 并做第二次往返了”
我们要做的第四件事是 我们要一遍又一遍地 设法处理转移播放列表的成本 我们所采用的基本方式是 使用Delta更新 它的运作方式是 客户端首次请求特定媒体播放列表时 它会取回完整的播放列表 然而在此之后 它拥有播放列表的绝大部分 它只对了解末端发生变更的部分 感兴趣 因此 在此之后 下一次它请求播放列表时 它会说 “我想要播放列表更新 这是一次Delta更新” 它所返回的是 非常少的数据块 只包含 在实际数字播放列表中 最新变更的内容 这些更新通常会放在一个数据包中 单一MTU数据 因此这对于后续的每次更新来说 有效率得多得多
现在第五个变更是 因为我们现在知道 这些播放列表更新是最新数据 我们可以用它们携带一些信息 那可以帮助我们把切换到其它 比特率层的速度变得更快一些
换句话说 假如我们在CDN上有两种比特率 客户端正在以第一种比特率播放
当它请求更新时 它会收到1MB播放列表的最新版本 它可以携带其它信息 比如如果它决定它需要切换到 2MB的比特率 它可以直接获取 2MB播放列表的最新版本 这就使切换比特率变得更有效率了
因此这五个变更是
我们减少发布延迟 把我们的媒体内容放在CDN上 优化视频段的发觉 我们消除往返 我们减少转移播放列表的消耗 并且我们使切换层的速度尽可能地快 现在让我们具体看一下
为了让这些新功能运作起来
客户端需要一种方式来告诉服务器端 它想确保这些新功能 比如播放列表Delta更新 或阻止播放列表重新加载
它的实现方式是 使用HLS Origin API
它的运作方式是服务自身 是由服务器端使用一个新标签公布的 即服务器控制标签
当客户端发现服务可用时 它通过给服务器端发送少量指令 来使用它们 这些指令作为查询参数 放在对播放列表的get请求中 看起来是类似这样的东西
现在
这是首次 我们把查询参数 指定为HLS的一部分 因此 我们会继续储备所有查询参数 从播放列表URL上的 核心HLS开始 它用于协议的使用 我们要做的另一件事就是 确保在所有客户端 那些查询参数都以确定性顺序 出现在URL中 从而不会导致CDN缓存 同一请求的多个有效附本 现在让我们更具体地看一下 这五个变更
第一个是处理这个概念… 是减少发布延迟 因此我们向HLS引入了 部分视频段的概念 我们把这些简称为“部分”
因此部分视频段实际上就是 常规视频段的一个子集 包含那个父视频段内 所含媒体内容的一个子集
并且CMAF已经给这种内容 赋予了一个名字 叫作CAMF数据块或FMP4内容 因此在HLS中你可以使用 CMAF数据块作为部分代码段 你还可以使用少量传输流 或任何其它已定义的 HLS视频段格式 作为部分视频段
它们的主要问题在于它们很短 比如它们可以不到一个完整的GOP 那意味着你可以有 半秒钟的部分视频段并仍保持 两秒钟的GOP
每次你创建新的部分视频段时 它都被添加到播放列表中 那意味着如果你已经得到了半秒钟的 部分视频段 比如说 然后你可以在它击中你的产品后台 半秒钟后 把内容发布到你的CDN 它只能减少这么短时间的发布延迟
部分视频段与常规视频段流 同时被添加到播放列表中 但部分视频段不会保留太长时间
那是因为部分视频段主要 当播放非常接近现场时有用 它们可以让客户端尽快发现媒体内容 并且那些部分视频段的详细的 可处理性 允许加入那些视频流的客户端的 延迟时间更短 也许是最大的视频段范围 但在部分视频段偏离现场边界更远 并且它们的父视频段 已经在播放列表中创建好了 客户端实际上 加载父视频段 比加载部分视频段更明智 因此部分视频段 就从播放列表中移除了 这会帮助保持播放列表的紧凑性 它的运作方式是当你生产视频段时 你同时会生产部分视频段 不久之后 随着那些部分视频段距离现场边界 越来越远或足够远 它们就被移除并且替换为 处于现场边界的新的部分视频段 让我们在实际的HLS播放列表中 看一下这是如何运作的
我这里有一些东西 我希望你注意的第一件事是 就像常规播放列表有目标持续时间 表明视频段有多长一样 部分视频段也有同样的东西 叫做部分目标持续时间 它表明了这个播放列表中的 部分视频段 部分视频段最多有十分之一秒的 持续时间 要注意的下一件事是 我们这里有常规视频段 是一个6秒的视频段43
当我们把视频段43 放到播放列表中的半秒后 我们可以放… 我们可以添加视频段44的第一部分 我们使用一个新标签实现 叫做部分标签 因此你可以看到每个部分标签 都有一个URI 因此视频段获得… 部分视频段有自己的URI 视频段44.1是半秒钟 并且它是独立的 那意味着它有自己的URI
在此之后半秒钟 我们可以向播放列表中添加 视频段44的下一部分视频段 如此反复 这是一个6秒的播放列表 因此它将有12个部分视频段 一旦我们到达视频段44的 最后一部分 我们实际上已经拥有整个父视频段了 因此我们可以同时发布 视频段44的最后一部分 和父视频段 然后半秒钟之后 再次重复这种循环 我们就得到了视频段45 然后不久之后 中间的那些部分视频段 就距离播放列表的最前方足够远了 它们就可以被移除了 现在我们已经有了视频段43、 视频段44 以及视频段45的一部分及其以后
这就是我们如何使用部分视频段 来减少发布延迟的 现在让我们看一下 优化发现视频段的方式
我们通过叫做 阻止播放列表重加载的方式来实现 它的运作方式是 服务器端公布它可以 处理阻止播放列表重加载 通过在服务器控制标签中放一个 可以阻止重加载参数来实现 当客户端看到这个参数之后 它就知道它可以 在下一个播放列表更新之前 提前请求下一个播放列表更新 因此我们通过这种方式 来分担请求的消耗
那时服务器端收到请求 意识到还没有客户端请求 播放列表更新 那它就会保有它直到有请求为止
客户端是如何向服务器端指明 它想要哪个更新的呢
它想要一个包含部分视频段的 特定的播放列表更新 嗯 它使用HLS的一个功能 叫做媒体序列号 现在HLS播放列表中的每个视频段 都有唯一序列号 播放列表中第一个视频段的序列号 是你在顶部看到的 那个媒体序列标签的值 在这个例子中是1800 下一个视频段的媒体序列号就是 在它基础上加一 媒体序列号仍遵守上述规则 即使下一个视频段由不连续标签 或键旋转或其它任何东西 被从其它视频段中分离开 序列号会继续向前计数
那意味着如果我们有这个播放列表 然后我们知道下一次它更新时 下一个视频段的序列号是什么
因此为了获得 下一个包含视频段的更新 你知道的 下一个感兴趣的视频段 我们可以告诉服务器端 “嘿 请为我提供播放列表更新 我想要包含 媒体序列号为1803的媒体内容” 看起来就是这样的 因此我们在这里得到了 播放列表的请求 你可以看到它正在请求m3u8 格式的媒体内容 我们有个查询参数 HLS msn=1803 这是客户端告诉服务器端 我想要这个特定播放列表更新的方式 就是那个包含这个媒体序列号的 播放列表更新 在客户端收到播放列表更新之后 一收到播放列表更新 就立即发送下一个1804的 更新请求 那些对于CDN来说看起来是 完全不同的URL 即使只有一个查询参数的一个值不同 对于CDN来说 它是一个完全不同的可缓存的实体 因此那就为我们提供了缓存破坏
这对于部分视频段来说也能起作用 在这个例子中看起来是这样的 我们有第二个例子 第二个例子说 “我想要包含媒体序列号 为1803的视频段的 第一部分的播放列表更新”
现在这里还会执行另一个操作 即这个推送查询参数 那是什么? 嗯 还记得我们想要做的另一件事是 消除获取视频段的这些额外的 往返时间吧 为此我们使用了“推送” 为此我们要使用HTTP/2
因为有些人可能 不怎么熟悉HTTP/2 所以让我快速介绍一下
HTTP/2是我们的老伙伴 HTTP/1的继任者 大概在四年前IATF 对它进行了标准化 自那时起 它就被网络服务器、 客户端和CDN广泛采用
必须采用低延迟HLS 因为它为我们提供一些功能 可以让我们提高协议交换的效率 其中最值得注意的是“推送” 那么推送是如何运作的呢?
嗯 从客户端来说 HTTP/2的 运作方式与HTTP/1相同 当客户端想获得资源时 它会向服务器端发送get请求 HTTP/2中的新功能是 当服务器端看到请求后 它可以对自己说 “哦 我看到你想要这个资源了 我打赌你也想要这个其它资源” 当它给你发送你所请求的资源时 同时它还可以单方面地 开始给你发送那个你并不知道 你是否需要的二级资源 那样如果它猜对了 你就不必再次发出第二次请求了 因为它已经发送给你的路上了
因此我们在延迟HLS中 通过视频段推送利用了这个功能
当客户端请求包含下一个视频段x的 特定播放列表更新时 它可以告诉服务器端 “哦 顺便提一下 当你给我发送播放列表更新时 也开始给我推送视频段x吧”
那就允许我们剔除 请求视频段的额外的往返
那么 让我们看一下这前三种优化 看看相对于常规的HLS 它们是如何影响流程的 让我们把那个放在那儿 让我们看一下新流程 低延迟客户端与低延迟服务器端通讯 首先客户端会提前请求播放列表 请求会在那儿排队 服务器端保留它 同时服务器端也生产第一个 部分视频段 假如在这个例子中 部分视频段时长一秒钟 在它执行编码操作一秒钟后 那时它可以把部分视频段添加到 播放列表中 并解禁那个播放列表请求 同时向客户端推送第一个部分视频段 然后客户端会在收到足够多的视频段 之后尽快开始显示 与此同时 在服务器端上排列起下一个 播放列表请求 从而可以尽快发现 下一个出现的视频段
即使部分视频段的时长有一秒钟 你也可以看到这极大地减少了 指定媒体帧 从服务器端传输到客户端的时间
最后两个修改实际上是 对这个基本流程的优化
第一个是关于一遍一遍地减少 传输播放列表的消耗 减少传输消耗为什么重要呢? 嗯 如果你正在传输的播放列表 包含三小时或甚至是五小时的视频段 并且你正在以每秒传输三到四次的 速度传输它 传输速度就变得非常重要了 即使对于gzip也一样
所以我们添加了 Delta播放列表更新
它的运作方式是 再一次 服务器端宣布客户端可以… 可以提供Delta更新 它通过CAN…SKIP…UNTIL 属性实现 那会告诉客户端 如果你请求Delta更新 它将跳过所有的视频段 直到距离现场边界一定的秒数 如果客户端看到了 它知道它上次更新播放列表的时间 因此它算出 它可以执行Delta更新 而不会错过任何信息 然后它可以当它下一次更新 播放列表时 发起明确请求 请求Delta更新
那个更新 只包含播放列表中的最后几个视频段 就是距离现场边界最近的几个视频段 并且它跳过了较早的播放列表部分 因为客户端已经有了
这里有个例子 在这个例子中 你可以看到客户端 正在请求Delta更新 通过指定underscore HLS underscore skip=YES查询参数实现 当它发起它的… 播放列表get请求时
在返回来的播放列表中 你会看到有一个 CAN-SKIP-UNTIL 它告诉客户端 当客户端请求Delta更新时 Delta更新将跳过一切 一直到距离现场边界前的36秒钟
然后这里的最后一个新标签是 这个跳过标签 你可以把跳过标签看作是 代替1700 xm视频段 可能存在于完整播放列表更新中的 xm视频段标签
那么这就是Delta更新 可以让我们真正最小化 用于不断地刷新播放列表的网络流量 而不会失去HLS播放列表 提供给你的任何普遍性和能力
现在让我们看一下最后一个修改 正是这个修改帮助我们更快地切换 比特率层 它们叫做“演奏报告” 我们的想法是 当你的客户端以特定比特率 加载特定播放列表的最新版本时 那个更新可以深入了解 客户端可能在下一秒或下两秒决定 或有兴趣切换到的其它视频段
特别是 “演奏报告”在它的最后一个 部分视频段序列号中 包含那个纯播放列表中的最后一个 媒体内容的序列号 那就为客户端提供了用于构成URL 以获取最新播放列表所需要的东西 它看起来是这样的
在这个例子中 我们让客户端请求 1MB播放列表的更新 当它请求时 它使用了HLS报告查询参数 请求深入查看 位于同一台服务器上的 2MB播放列表
当它得到播放列表时 播放列表也包含一个 “演奏报告”标签 里面包含关于其他视频段的各种信息
因此如果我们把这些都放在一起
问题是它们可以一起发挥作用吗?
你们想看一个演示吗?
让我们做个演示吧 你知道的 当我们把这些会话放在一起时 我们像是“是的 我们可以做个现场演示 或我们可以做一个 库比蒂诺的现场直播” 但如果我们从距离我们更远的地方 做现场演示 不是更有说明力吗? 也许距离我们7000英里 也许是12000英里 比如澳大利亚悉尼?
但等一下 我们认识悉尼的人吗?
Matt 我们认识Matt 让我们呼叫Matt
好的 让我们看一下 天啊 我希望Matt已经醒了
日安Roger 嘿Matt 你好吗? 我很好 谢谢 太棒了 嘿 告诉你 我现在正在参加WWDC 我想给大家演示一下低延迟HLS 你那个视频流还在运行吗? 当然了 哦 太好了 好的 让我们…让我们打开它 看看我们有什么 我有Apple TV 好的 这就好 好的 嘿 太神奇了 我在Apple TV里 好吧 让我们打开我们的app 这里有悉尼视频流 让我们打开它 看看我们得到了什么
并没有开始播放悉尼视频流 让我们再尝试一下
好的 让我试试库比蒂诺视频流 只是为了看看是否有人… 哦 有Simon Simon在库比蒂诺 所以那是… 我们把Simon关掉
好吧 让我们再试一下这个 我们…
哎呦 来吧 我该怎么搞定这个呢?
Matt 你还在啊 好的 呀 你还在 -是的 我还在这里 你好 -好的 太棒了
但是 嘿 你知道的 你后面是悉尼邮政总局吗? 当然是 哦 伙计 来吧 我们没有…抱歉…我要再试一次
今天我的视频流 并没有像我预期的那样
是的 Simon还在
哦 伙计
然后那是…好的那是… 是的 那是Matt
我要点击播放吗 还是暂停?
嗯 你知道吗 也许我们最后要呼叫Simon 那让我有点失望 因为我其实想给你们演示视频流
让我们看一下 屏住呼吸 好了吗? 你们需要重启视频流吗?
刚才网络断开了 网络断开了? 太棒了
好的 我们有… 让我看一下是否也许 我们是否没插好?
这些现场演示真的要搞死我了
双击这个会…
试着不用这个了 是的 我不知道这是否会帮助我 但让我们抛弃它吧
哦 伙计 好的 我认为我们要 再试一次 然后… 我们就要寻求备选方案了 好吧 抱歉Matt 我们的视频流出问题了 因此让我…
感谢你的出现 我们只能见你这么一小会儿 但我现在要连线库比蒂诺了 好吧 没问题 好的 嗯 这真的令人失望 但无论怎样 让我呼叫Simon吧 我猜这就是为什么需要备份的原因
嘿 Simon 你在吗? 是的 我在Roger 你好吗? 很好 Simon也是澳大利亚人 我意识到那不是…这是一种 于事无补的安慰 但他在那儿 澳大利亚人随处可见
Simon 我想给这里的 家伙们演示低延迟HLS视频流 哦 当然 那么我们为什么不这样做呢 我要让你举起手来 然后人们会听到你说… 如果你在举手的时候说了 他们会通过音频听到你的声音 然后他们才会在视频流上看到你 那会给你…给他们一种关于 视频延迟的概念 -那么为什么不举起你的手呢… -哦 当然
好的 举起你的手
嘿 大家好 -我举起我的手了 -好的 很好 一直举着 并且…哦 你放下了
好的 现在 举起三根手指 三根手指 我们看到了 所以那是个…它们要 你知道的… HLS视频流有不到两秒钟的延迟 Simon非常感谢你 今天对我们的帮助 当然 我希望你们能度过一个 愉快的WWDC 谢谢
好的 那么这就是低延迟HLS 在这点上 有些人很可能在想 我该如何为我提供那些HLS低延迟 媒体内容呢?
那么 首先许多人都是app开发人员 因此让我先讲一下app
好消息是 默认情况下 你们不需要做任何操作 如果你正 使用AV Player播放视频流 并且你支持低延迟视频流的话 你将默认得到低延迟媒体内容
然而我们确实有一些新API
其中一个会告诉你 你当前设置的 时间点距离现场边界有多远 另一个是一个推荐 根据我们所观察到的东西进行推荐 比如往返时间 因此你可以结合使用两个API 来进行配置 比如 如果你看到延迟风险太大了 你可以把它降低一点 也许我们应该在这里实现 第二个是一种让你维持播放头 相对于现场边界的位置的方式 它之所以有意思是因为 今天如果你正在播放现场直播 然后你穿过隧道或其它什么东西 并缓冲10秒钟 当你恢复时 将从你停止的那一时刻开始恢复 意思就是你不会错过任何东西 但每一次你缓冲时 你都落后一小点 因此如果你把距离现场边界的 保留时间偏移自动设置为“是” 然后每一次我们缓冲之后 我们将不能自动向前跳动到 距离现场边界的同一个位置 因此 那会让你保持现场直播 要考虑的下一件事是配置你的CDN
我们真的很想避免
在CDN上放置外来的 针对视频的要求 因为我们希望CDN的重点主要是 成为很棒的CDN 因此我们做到直截了当 你需要使用符合行业标准的 HTTP/2 来提交你的HSL视频段和播放列表 那包含支持“推送” 和标准的优先级控制
你应该在每台服务器上都放一个 完整的层阶梯 你仍然可以有多台冗余的服务器 但每一台应该有完整的阶梯 以便我们可以最小化连接设置时间 并且你需要设置你的CDN 从而聚合重复请求 如果Fred请求特定播放列表 它会进入源并获取它 然后如果Bob请求同样的内容 你不要通过CDN发送同样的请求 你应该把它放在Fred的请求旁边 等待返回来的第一个响应 然后再同时提交给他们 不同的CDN对这个过程 有不同的命名 Apache Traffic Server 把它叫做读写器 其它可能把它叫做提早发布 或类似的名字 重点是找到它并设置好它
这里的主要工作是实施你的源 修改用于发出部分视频段的程序包 并实施源API 为了帮助你们实现这个操作 我们 针对低延迟HLS发布了一个规范 你可以从网站上找到它 在我们的演讲页面也有一个链接 它当前是一个单独的草案 我们计划在今年下半年把规则 放到课程包里 它包含一些新东西即服务器配置分析 那包含服务器提交链的一组属性 需要在客户端采用低延迟模式 客户端会检查这些属性 如果它看到不能满足所有属性的话 它会退回到常规延迟
同时我们还提供了一个引用实施 用于生产和串流低延迟HLS视频流 它叫做低延迟 HLS Beta工具包 它包含一些工具 可以生成一个播放列表 是程序化Bitbop 或从摄像头生成 并把它打包到低延迟视频流中 它包含Apache的一个前端 实施源API 包括阻止播放列表重加载、 Delta更新、演奏报告 你可以使用它在你的app中 试验低延迟 或当你创建它时 把它与后台实施进行对比
那么这就是你作为开发人员 需要了解和实施的操作 让我们谈谈用户 我们意识到低延迟HLS是一个 重大的变更 因此我们允许你花点时间来了解它 并且我们… 支持你对客户端的实施 简而言之 你需要一个低延迟模式的app权利 这允许你通过TestFlight 面向最多10000名测试用户 创建你的app、测试你的视频流 甚至是部署视频流 然后一旦你确认 一切都没问题了 那么测试阶段就结束了 你就可以把app提交到商店中了 因此总而言之 请一定要看规范文档 在测试模式中试着用一下 并开始创建你的后台 以支持低延迟现场直播视频流 为了帮助你们实现这个操作 今天或本周我们有一些 HLS相关的演讲 我和我们团队的一些同事将会参加 我们将非常乐于回答 关于低延迟HLS的任何疑问 以及其它关于HLS的任何疑问 第一场演讲是在 周四下午4点到6点 第二场演讲 我想是在周五的 上午11点到下午1点 非常感谢你们的参与 我希望每个人都有精彩的表现
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。