6

我正在开发一个iOS 应用程序,它允许下载和HTTP 直播私人视频。视频存储在 Amazon S3 存储桶中(asmp4并分段为m3u8/文ts​​件)。CloudFront也已打开并连接到存储桶。

由于内容是私有的,我需要在通过 CloudFront 连接时对 URL 进行签名。为了对 URL 进行签名,必须使用私钥,因此如果不将私钥存储在包中,就无法在 iOS 应用程序中生成签名 URL。那将是一个坏主意!

所以我决定编写一个简单的 Ruby 服务器,它执行 URL 签名并重定向到生成的签名 CloudFront URL,如下所示:


http://signing.server.local/videos/1.mp4 https://acbdefg123456.cloudfront.net/videos/1.mp4??Expires=XXX&Signature=XXX&Key-Pair-Id=XXX

http://signing.server.local/videos/1.m3u8 https://acbdefg123456.cloudfront.net/videos/1.m3u8??Expires=XXX&Signature=XXX&Key-Pair-Id=XXX


对于视频下载,它运行良好,因为只有一个请求。但是,当我希望内容流式传输并提供MPMoviePlayerController签名服务器的 URL 时,只有第一个请求由服务器签名并重定向到 CloudFront。对于下一个请求,MPMoviePlayerController将第一个签名的 CloudFront URL 作为基础并尝试直接连接而不抛出签名服务器。

m3u8文件中的路径是相对的。

有什么建议如何在无需通过签名服务器发送所有内容的情况下实现此功能?

4

3 回答 3

9

使用 S3/CloudFront 或任何其他存储/CDN 进行私有 HLS的正确方法是使用 HLS 加密。请参阅有关此主题的 Apple 文档

除了存储播放列表和分段视频文件的存储空间之外,您还必须集成一个安全的 HTTPS 服务器来存储顶级播放列表和密钥。这些密钥是在分段期间使用 Apple HLS 工具生成的。

下面是它的工作原理:

  1. 获取指向安全 HTTPS 服务器上MPMoviePlayerController顶级播放列表 ( ) 的 URL 。.m3u8
  2. 在此文件中,有prog_index.m3u8指向存储在 S3/CloudFront 中的变体播放列表 ( ) 的链接,这些链接指向视频文件 ( .ts)。
  3. 此外,变体播放列表包含指向读取视频文件所必需的键的链接。这些密钥也存储在安全的 HTTPS 服务器上。

见下图:

保护 HLS 密钥

摘自带有 HTTP 实时流的移动电影演示文稿(CocoaConf DC,2012 年 6 月)

当然,有可能使基础设施更安全,请参阅链接的 Apple 文档。

我还创建了一个用于分段的 Ruby 脚本,以使用给定的基本 URL 生成输出,这使事情变得更加简单。

于 2014-01-25T10:36:47.497 回答
2

Lukas Kubanek 有正确的答案。但是,您可以通过将顶级播放列表放在“私有”存储桶中,然后将所有其他播放列表和 .ts 文件放在公共存储桶中来获得签名 URL 的效果。这几乎与对所有内容使用签名 URL 一样安全,因为任何想要下载和保存内容的人仍然可以下载和保存内容,但不能仅仅共享他们提供的 URL。他们当然可以打开顶级播放列表,然后共享他们选择的单个流,或者自己托管顶级播放列表,但这至少是一个小的安全级别,可能足以满足您的内容。此外,如果您签署每个片段,您会遇到内容超过您的时间限制的问题,或者用户只是暂停视频直到片段链接过期。

于 2014-02-05T19:23:43.383 回答
0

我认为您需要某种方法来避免为每个视频块向不同服务器发出两个请求。

可能的解决方案:您能否每隔几分钟更改一次 Cloudfront 私钥?如果是,那么只需根据需要进行身份验证(双向握手)并将当前私钥发送给应用程序。如果它过期,或者由于它没有完全按预期过期而出现任何错误,只需重新验证并获取新的私钥。

可能的解决方案:当您想播放视频 X 时与身份验证服务器交谈,并为该视频的每个部分获取签名 URL,或者更好:包含签名 URL 的 m3u8 文件。然后,直接播放那些...

可能的解决方案:通过本地代理运行所有内容(在 iOS 设备上的环回接口上)。然后根据需要修改请求 URL,或使它们重定向。

于 2013-11-01T11:24:43.910 回答