适用于 iOS 的脱机 FairPlay StreamingOffline FairPlay Streaming for iOS

媒体服务徽标media services logo


备注

Google Widevine 内容保护服务目前在 Azure 中国区域不可用。Google Widevine content protection services are currently unavailable in the Azure China regions.

备注

不会向媒体服务 v2 添加任何新特性或新功能。No new features or functionality are being added to Media Services v2.
查看最新版本:媒体服务 v3Check out the latest version, Media Services v3. 另请参阅从 v2 到 v3 的迁移指南Also, see migration guidance from v2 to v3

Azure 媒体服务提供一套设计良好的内容保护服务,包括:Azure Media Services provides a set of well-designed content protection services, that cover:

  • Microsoft PlayReadyMicrosoft PlayReady
  • Apple FairPlayApple FairPlay
  • AES-128 加密AES-128 encryption

数字版权管理 (DRM)/高级加密标准 (AES) 基于各种流式处理协议的请求,动态执行内容的 DRM/AES 加密。Digital rights management (DRM)/Advanced Encryption Standard (AES) encryption of content is performed dynamically upon request for various streaming protocols. 媒体服务还提供 DRM 许可证/AES 解密密钥传送服务。DRM license/AES decryption key delivery services also are provided by Media Services.

除通过各种流式处理协议对联机流式处理的内容提供保护外,通常还要求提供受保护内容的脱机模式功能。Besides protecting content for online streaming over various streaming protocols, offline mode for protected content is also an often-requested feature. 以下情况需要脱机模式支持:Offline-mode support is needed for the following scenarios:

  • 在 Internet 连接不可用(如旅行期间)时播放。Playback when internet connection isn't available, such as during travel.
  • 某些内容提供程序可能不允许在某个国家/地区的边界之外进行 DRM 许可证传送。Some content providers might disallow DRM license delivery beyond a country/region's border. 如果用户想在该国家/地区外旅行期间查看内容,需要脱机下载。If users want to watch content while traveling outside of the country/region, offline download is needed.
  • 在某些国家/地区,Internet 可用性和/或宽带仍然受到限制。In some countries/regions, internet availability and/or bandwidth is still limited. 为获得满意的观看体验,用户可能选择首先下载以便能够观看高分辨率的内容。Users might choose to download first to be able to watch content in a resolution that is high enough for a satisfactory viewing experience. 在此情况下,通常问题不在于网络可用性,而在于受限的网络宽带。In this case, the issue typically isn't network availability but limited network bandwidth. 此时,Over-the-Top (OTT)/联机视频平台 (OVP) 提供商会请求脱机模式支持。Over-the-top (OTT)/online video platform (OVP) providers request offline-mode support.

本文介绍 FairPlay Streaming (FPS) 脱机模式支持,适用于运行 iOS 10 或更高版本的设备。This article covers FairPlay Streaming (FPS) offline-mode support that targets devices running iOS 10 or later. 此功能不支持其他 Apple 平台,例如 watchOS、tvOS 或 macOS 上的 Safari。This feature isn't supported for other Apple platforms, such as watchOS, tvOS, or Safari on macOS.

预备步骤Preliminary steps

在 iOS 10+ 设备上为 FairPlay 实现 脱机 DRM 之前:Before you implement offline DRM for FairPlay on an iOS 10+ device:

媒体服务中的配置Configuration in Media Services

对于通过媒体服务 .NET SDK 的 FPS 脱机模式配置,需要使用媒体服务 .NET SDK 4.0.0.4 或更高版本提供必要的 API 来配置 FPS 脱机模式。For FPS offline-mode configuration via the Media Services .NET SDK, use the Media Services .NET SDK version 4.0.0.4 or later, which provides the necessary API to configure FPS offline mode. 此外,还需要提供有效的代码来配置联机模式 FPS 内容保护。You also need the working code to configure online-mode FPS content protection. 获取用于配置联机模式 FPS 内容保护的代码后,只需进行以下两项更改。After you obtain the code to configure online-mode content protection for FPS, you need only the following two changes.

FairPlay 配置中的代码更改Code change in the FairPlay configuration

第一项更改是定义名为 objDRMSettings.EnableOfflineMode 的“启用脱机模式”布尔,使其在启用脱机 DRM 方案时,布尔值为 true。The first change is to define an "enable offline mode" Boolean, called objDRMSettings.EnableOfflineMode, that is true when it enables the offline DRM scenario. 根据该指示器,对 FairPlay 配置做出以下更改:Depending on this indicator, make the following change to the FairPlay configuration:

if (objDRMSettings.EnableOfflineMode)
    {
        FairPlayConfiguration = Microsoft.WindowsAzure.MediaServices.Client.FairPlay.FairPlayConfiguration.CreateSerializedFairPlayOptionConfiguration(
            objX509Certificate2,
            pfxPassword,
            pfxPasswordId,
            askId,
            iv, 
            RentalAndLeaseKeyType.PersistentUnlimited,
            0x9999);
    }
    else
    {
        FairPlayConfiguration = Microsoft.WindowsAzure.MediaServices.Client.FairPlay.FairPlayConfiguration.CreateSerializedFairPlayOptionConfiguration(
            objX509Certificate2,
            pfxPassword,
            pfxPasswordId,
            askId,
            iv);
    }

资产传送策略配置中的代码更改Code change in the asset delivery policy configuration

第二项更改是将第三个密钥添加到 Dictionary<AssetDeliveryPolicyConfigurationKey, string>。The second change is to add the third key into Dictionary<AssetDeliveryPolicyConfigurationKey, string>. 按如下所示添加 AssetDeliveryPolicyConfigurationKey:Add AssetDeliveryPolicyConfigurationKey as shown here:

// FPS offline mode
    if (drmSettings.EnableOfflineMode)
    {
        objDictionary_AssetDeliveryPolicyConfigurationKey.Add(AssetDeliveryPolicyConfigurationKey.AllowPersistentLicense, "true");
        Console.WriteLine("FPS OFFLINE MODE: AssetDeliveryPolicyConfigurationKey.AllowPersistentLicense added into asset delivery policy configuration.");
    }

    // for IAssetDelivery for FPS
    IAssetDeliveryPolicy objIAssetDeliveryPolicy = objCloudMediaContext.AssetDeliveryPolicies.Create(
            drmSettings.AssetDeliveryPolicyName,
            AssetDeliveryPolicyType.DynamicCommonEncryptionCbcs,
            AssetDeliveryProtocol.HLS,
            objDictionary_AssetDeliveryPolicyConfigurationKey);

完成此步骤后,FPS 资产传送策略中的 <Dictionary_AssetDeliveryPolicyConfigurationKey> 字符串将包含以下三项:After this step, the <Dictionary_AssetDeliveryPolicyConfigurationKey> string in the FPS asset delivery policy contains the following three entries:

  • AssetDeliveryPolicyConfigurationKey.FairPlayBaseLicenseAcquisitionUrl 或 AssetDeliveryPolicyConfigurationKey.FairPlayLicenseAcquisitionUrl,具体取决于一些因素,如使用的 FPS KSM/密钥以及是否希望跨多个资产重用相同的资产传送策略AssetDeliveryPolicyConfigurationKey.FairPlayBaseLicenseAcquisitionUrl or AssetDeliveryPolicyConfigurationKey.FairPlayLicenseAcquisitionUrl, depending on factors such as the FPS KSM/key server used and whether you reuse the same asset delivery policy across multiple assets
  • AssetDeliveryPolicyConfigurationKey.CommonEncryptionIVForCbcsAssetDeliveryPolicyConfigurationKey.CommonEncryptionIVForCbcs
  • AssetDeliveryPolicyConfigurationKey.AllowPersistentLicenseAssetDeliveryPolicyConfigurationKey.AllowPersistentLicense

现在,媒体服务帐户已配置为传送脱机 FairPlay 许可证。Now your Media Services account is configured to deliver offline FairPlay licenses.

示例 iOS 播放器Sample iOS Player

FPS 脱机模式支持仅适用于 iOS 10 及更高版本。FPS offline-mode support is available only on iOS 10 and later. FPS Server SDK(3.0 或更高版本)包含 FPS 脱机模式文档和示例。The FPS Server SDK (version 3.0 or later) contains the document and sample for FPS offline mode. 具体而言,FPS Server SDK(3.0 或更高版本)包含以下与脱机模式相关的两项:Specifically, FPS Server SDK (version 3.0 or later) contains the following two items related to offline mode:

  • 文档:“使用 FairPlay Streaming 和 HTTP Live Streaming 的脱机播放”。Document: "Offline Playback with FairPlay Streaming and HTTP Live Streaming." 2016 年 9 月 14 日由 Apple 提供。Apple, September 14, 2016. 在 FPS Server SDK 版本 4.0 中,此文档已合并到主要 FPS 文档。In FPS Server SDK version 4.0, this document is merged into the main FPS document.

  • 示例代码:\FairPlay Streaming Server SDK version 3.1\Development\Client\HLSCatalog_With_FPS\HLSCatalog\ 中的 FPS 脱机模式的 HLSCatalog 示例。Sample code: HLSCatalog sample for FPS offline mode in the \FairPlay Streaming Server SDK version 3.1\Development\Client\HLSCatalog_With_FPS\HLSCatalog. 在 HLSCatalog 示例应用中,以下代码文件用于实现脱机模式功能:In the HLSCatalog sample app, the following code files are used to implement offline-mode features:

    • AssetPersistenceManager.swift 代码文件:AssetPersistenceManager 是此示例中的主类,演示如何:AssetPersistenceManager.swift code file: AssetPersistenceManager is the main class in this sample that demonstrates how to:

      • 管理下载 HLS 流,例如用于开始和取消下载的 API 以及用于删除用户设备中现有资产的 API。Manage downloading HLS streams, such as the APIs used to start and cancel downloads and to delete existing assets off devices.
      • 监视下载进度。Monitor the download progress.
    • AssetListTableViewController.swift 和 AssetListTableViewCell.swift 代码文件:AssetListTableViewController 是此示例的主接口。AssetListTableViewController.swift and AssetListTableViewCell.swift code files: AssetListTableViewController is the main interface of this sample. 它提供示例可以用来播放、下载、删除或取消下载的资产列表。It provides a list of assets the sample can use to play, download, delete, or cancel a download.

以下步骤说明如何设置正在运行的 iOS 播放器。These steps show how to set up a running iOS player. 假设从 FPS Server SDK 版本 4.0.1 的 HLSCatalog 示例开始。需要对代码进行以下更改:Assuming you start from the HLSCatalog sample in FPS Server SDK version 4.0.1, make the following code changes:

在 HLSCatalog\Shared\Managers\ContentKeyDelegate.swift 中,使用以下代码实现方法 requestContentKeyFromKeySecurityModule(spcData: Data, assetID: String)In HLSCatalog\Shared\Managers\ContentKeyDelegate.swift, implement the method requestContentKeyFromKeySecurityModule(spcData: Data, assetID: String) by using the following code. 使“drmUr”成为分配到 HLS URL 的变量。Let "drmUr" be a variable assigned to the HLS URL.

    var ckcData: Data? = nil
    
    let semaphore = DispatchSemaphore(value: 0)
    let postString = "spc=\(spcData.base64EncodedString())&assetId=\(assetIDString)"
    
    if let postData = postString.data(using: .ascii, allowLossyConversion: true), let drmServerUrl = URL(string: self.drmUrl) {
        var request = URLRequest(url: drmServerUrl)
        request.httpMethod = "POST"
        request.setValue(String(postData.count), forHTTPHeaderField: "Content-Length")
        request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
        request.httpBody = postData
        
        URLSession.shared.dataTask(with: request) { (data, _, error) in
            if let data = data, var responseString = String(data: data, encoding: .utf8) {
                responseString = responseString.replacingOccurrences(of: "<ckc>", with: "").replacingOccurrences(of: "</ckc>", with: "")
                ckcData = Data(base64Encoded: responseString)
            } else {
                print("Error encountered while fetching FairPlay license for URL: \(self.drmUrl), \(error?.localizedDescription ?? "Unknown error")")
            }
            
            semaphore.signal()
            }.resume()
    } else {
        fatalError("Invalid post data")
    }
    
    semaphore.wait()
    return ckcData

在 HLSCatalog\Shared\Managers\ContentKeyDelegate.swift 中,实现方法 requestApplicationCertificate()In HLSCatalog\Shared\Managers\ContentKeyDelegate.swift, implement the method requestApplicationCertificate(). 此实现取决于是将证书(仅公钥)嵌入设备还是将证书托管在 Web 上。This implementation depends on whether you embed the certificate (public key only) with the device or host the certificate on the web. 下面是使用测试示例中使用的托管应用程序证书的实现。The following implementation uses the hosted application certificate used in the test samples. 使 certUrl 成为一个包含应用程序证书 URL 的变量。Let "certUrl" be a variable that contains the URL of the application certificate.

func requestApplicationCertificate() throws -> Data {

        var applicationCertificate: Data? = nil
        do {
            applicationCertificate = try Data(contentsOf: URL(string: certUrl)!)
        } catch {
            print("Error loading FairPlay application certificate: \(error)")
        }
        
        return applicationCertificate
    }

对于最终集成测试,“集成测试”部分将提供视频 URL 和应用程序证书 URL 两者。For the final integrated test, both the video URL and the application certificate URL are provided in the section "Integrated Test."

在 HLSCatalog\Shared\Resources\Streams.plist 中添加测试视频 URL。In HLSCatalog\Shared\Resources\Streams.plist, add your test video URL. 对于内容密钥 ID,只需使用带有 SKD 协议的 FairPlay 许可证获取 URL 作为唯一值。For the content key ID, use the FairPlay license acquisition URL with the skd protocol as the unique value.

脱机 FairPlay iOS 应用流

如果已设置,可以使用自己的测试视频 URL、FairPlay 许可证获取 URL 和应用程序证书 URL。Use your own test video URL, FairPlay license acquisition URL, and application certificate URL, if you have them set up. 或者,可以继续查看包含测试示例的下一部分。Or you can continue to the next section, which contains test samples.

集成测试Integrated test

媒体服务中的三个测试示例包含以下三种方案:Three test samples in Media Services cover the following three scenarios:

  • FPS 受到保护,包括视频、音频和备用音频曲目FPS protected, with video, audio, and alternate audio track
  • FPS 受到保护,包括视频、音频,但不包括备用音频曲目FPS protected, with video and audio, but no alternate audio track
  • FPS 受到保护,仅包括视频,不包括音频FPS protected, with video only and no audio

可在此演示站点上找到这些示例,相应的应用程序证书托管在 Azure Web 应用中。You can find these samples at this demo site, with the corresponding application certificate hosted in an Azure web app. 使用 FPS Server SDK 的版本 3 或版本 4 示例时,如果在脱机模式期间主播放列表包含备用的音频,则只播放音频。With either the version 3 or version 4 sample of the FPS Server SDK, if a master playlist contains alternate audio, during offline mode it plays audio only. 因此,需要删除备用音频。Therefore, you need to strip the alternate audio. 换言之,前面所列的第二和第三个示例在联机和脱机模式下都可正常运行。In other words, the second and third samples listed previously work in online and offline mode. 所列的第一个示例在脱机模式期间只播放音频,联机流式处理可正常运行。The sample listed first plays audio only during offline mode, while online streaming works properly.

常见问题FAQ

以下常见问题解答提供故障排除帮助:The following frequently asked questions provide assistance with troubleshooting:

  • 为什么在脱机模式期间只播放音频而不播放视频?Why does only audio play but not video during offline mode? 此行为似乎是示例应用专门设计的。This behavior seems to be by design of the sample app. 存在备用音频曲目时(这适用于 HLS),在脱机模式期间,iOS 10 和 iOS 11 都默认播放备用音频曲目。为了补偿 FPS 脱机模式的此行为,需要从流删除备用音频曲目。When an alternate audio track is present (which is the case for HLS) during offline mode, both iOS 10 and iOS 11 default to the alternate audio track. To compensate this behavior for FPS offline mode, remove the alternate audio track from the stream. 若要在媒体服务中完成此操作,请添加动态清单筛选器“audio-only=false”。To do this on Media Services, add the dynamic manifest filter "audio-only=false." 换言之,HLS URL 将以 .ism/manifest(format=m3u8-aapl,audio-only=false) 结尾。In other words, an HLS URL ends with .ism/manifest(format=m3u8-aapl,audio-only=false).

  • 除 iOS 10 之外,iOS 11 是否也支持 FPS 脱机模式?Is FPS offline mode also supported on iOS 11 in addition to iOS 10? 是的。Yes. iOS 10 和 iOS 11 支持 FPS 脱机模式。FPS offline mode is supported for iOS 10 and iOS 11.

  • 为什么在 FPS Server SDK 中,无法使用 FairPlay Streaming 和 HTTP Live Streaming 找到文档“脱机播放”?Why can't I find the document "Offline Playback with FairPlay Streaming and HTTP Live Streaming" in the FPS Server SDK? 从 FPS Server SDK 版本 4 开始,此文档已合并到“FairPlay Streaming 编程指南”。Since FPS Server SDK version 4, this document was merged into the "FairPlay Streaming Programming Guide."

  • FPS 脱机模式的以下 API 中最后一个参数代表什么? Microsoft.WindowsAzure.MediaServices.Client.FairPlay.FairPlayConfiguration.CreateSerializedFairPlayOptionConfiguration(objX509Certificate2, pfxPassword, pfxPasswordId, askId, iv, RentalAndLeaseKeyType.PersistentUnlimited, 0x9999);What does the last parameter stand for in the following API for FPS offline mode? Microsoft.WindowsAzure.MediaServices.Client.FairPlay.FairPlayConfiguration.CreateSerializedFairPlayOptionConfiguration(objX509Certificate2, pfxPassword, pfxPasswordId, askId, iv, RentalAndLeaseKeyType.PersistentUnlimited, 0x9999);

    有关此 API 的文档,请参阅 FairPlayConfiguration.CreateSerializedFairPlayOptionConfiguration 方法For the documentation for this API, see FairPlayConfiguration.CreateSerializedFairPlayOptionConfiguration Method. 该参数代表脱机租赁的持续时间(秒)。The parameter represents the duration of the offline rental, with second as the unit.

  • iOS 设备上的已下载/脱机文件结构是什么?What is the downloaded/offline file structure on iOS devices? iOS 设备上的已下载文件结构如下屏幕截图所示。The downloaded file structure on an iOS device looks like the following screenshot. _keys 文件夹存储已下载的 FPS 许可证,每个许可证服务主机一个存储文件。The _keys folder stores downloaded FPS licenses, with one store file for each license service host. .movpkg 文件夹存储音频和视频内容。The .movpkg folder stores audio and video content. 第一个文件夹(文件名以破折号加数字结尾)包含视频内容。The first folder with a name that ends with a dash followed by a numeric contains video content. 数值是“PeakBandwidth”视频呈现形式。The numeric value is the PeakBandwidth of the video renditions. 第二个文件夹(文件名以破折号加 0 结尾)包含音频内容。The second folder with a name that ends with a dash followed by 0 contains audio content. 第三个文件夹(文件名为“Data”)包含 FPS 内容的主播放列表。The third folder named "Data" contains the master playlist of the FPS content. 最后,boot.xml 提供 .movpkg 文件夹内容的完整说明。Finally, boot.xml provides a complete description of the .movpkg folder content.

脱机 FairPlay iOS 示例应用文件结构

示例 boot.xml 文件:A sample boot.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<HLSMoviePackage xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="http://apple.com/IMG/Schemas/HLSMoviePackage" xsi:schemaLocation="http://apple.com/IMG/Schemas/HLSMoviePackage /System/Library/Schemas/HLSMoviePackage.xsd">
  <Version>1.0</Version>
  <HLSMoviePackageType>PersistedStore</HLSMoviePackageType>
  <Streams>
    <Stream ID="1-4DTFY3A3VDRCNZ53YZ3RJ2NPG2AJHNBD-0" Path="1-4DTFY3A3VDRCNZ53YZ3RJ2NPG2AJHNBD-0" NetworkURL="https://willzhanmswest.streaming.mediaservices.chinacloudapi.cn/e7c76dbb-8e38-44b3-be8c-5c78890c4bb4/MicrosoftElite01.ism/QualityLevels(127000)/Manifest(aac_eng_2_127,format=m3u8-aapl)">
      <Complete>YES</Complete>
    </Stream>
    <Stream ID="0-HC6H5GWC5IU62P4VHE7NWNGO2SZGPKUJ-310656" Path="0-HC6H5GWC5IU62P4VHE7NWNGO2SZGPKUJ-310656" NetworkURL="https://willzhanmswest.streaming.mediaservices.chinacloudapi.cn/e7c76dbb-8e38-44b3-be8c-5c78890c4bb4/MicrosoftElite01.ism/QualityLevels(161000)/Manifest(video,format=m3u8-aapl)">
      <Complete>YES</Complete>
    </Stream>
  </Streams>
  <MasterPlaylist>
    <NetworkURL>https://willzhanmswest.streaming.mediaservices.chinacloudapi.cn/e7c76dbb-8e38-44b3-be8c-5c78890c4bb4/MicrosoftElite01.ism/manifest(format=m3u8-aapl,audio-only=false)</NetworkURL>
  </MasterPlaylist>
  <DataItems Directory="Data">
    <DataItem>
      <ID>CB50F631-8227-477A-BCEC-365BBF12BCC0</ID>
      <Category>Playlist</Category>
      <Name>master.m3u8</Name>
      <DataPath>Playlist-master.m3u8-CB50F631-8227-477A-BCEC-365BBF12BCC0.data</DataPath>
      <Role>Master</Role>
    </DataItem>
  </DataItems>
</HLSMoviePackage>

摘要Summary

本文档包含以下步骤,并提供了可用于实现 FPS 脱机模式的信息:This document includes the following steps and information you can use to implement FPS offline mode:

  • 通过媒体服务 .NET API 的媒体服务内容保护配置在媒体服务中配置动态 FairPlay 加密和 FairPlay 许可证传送。Media Services content protection configuration via the Media Services .NET API configures dynamic FairPlay encryption and FairPlay license delivery in Media Services.
  • 基于 FPS Server SDK 中的示例的 iOS 播放器设置可以在联机流式处理模式或脱机模式中播放 FPS 内容的 iOS 播放器。An iOS player based on the sample from the FPS Server SDK sets up an iOS player that can play FPS content either in online streaming mode or offline mode.
  • 用于测试脱机模式和联机流式处理的示例 FPS 视频。Sample FPS videos are used to test offline mode and online streaming.
  • 有关 FPS 脱机模式的常见问题解答。A FAQ answers questions about FPS offline mode.

后续步骤Next steps

媒体服务 v3(最新版本)Media Services v3 (latest)

查看最新版本的 Azure 媒体服务!Check out the latest version of Azure Media Services!

媒体服务 v2(旧版)Media Services v2 (legacy)