匯出 (0) 列印
全部展開

使用 PlayReady 和靜態加密保護 Smooth 和 MPEG DASH

更新日期: 2014年8月

如果想要使用 PlayReady 保護內容,可以選擇使用動態加密 (建議選項) 或靜態加密。下列部落格討論這兩個選項:<動態加密與靜態加密>(英文)。如果您決定使用動態加密,請參閱<使用 PlayReady 動態加密和授權傳遞服務>。

執行靜態加密時,您通常會執行下列步驟。如果您是使用自動調整位元速率 Smooth Streaming 檔案來開始,請跳至步驟 4。

  1. 上傳輸入檔案 (稱為夾層檔)。例如,H.264、MP4 或 WMV (如需支援格式的清單,請參閱 Media Services 編碼程式支援的格式)。

  2. 將您的夾層檔編碼為一組可調位元速率 MP4。

  3. 將自動調整位元速率 MP4 集封裝為 Smooth Streaming。

  4. 加密 Smooth Streaming。

  5. 建立連結至伺服器資產的隨選 Locator。接著,建立完整的 URL。如果是 Smooth Streaming:{media services account name}.origin.mediaservices.net/{locator ID}/{filename}.ism/Manifest。如果是 MPEG DASH:{media services account name}.origin.mediaservices.net/{locator ID}/{filename}.ism/Manifest(format=mpd-time-csf) .

本主題中的範例將夾層檔 (本例中為 MP4) 編碼為自動調整位元速率 MP4 檔案。接著會將 MP4 封裝為 Smooth Streaming,並使用 PlayReady 加密 Smooth Streaming。因此,您可以串流 Smooth Streaming 或 MPEG DASH。

媒體服務現在提供一項服務來傳遞 Microsoft PlayReady 授權。本文中的範例顯示如何設定媒體服務 PlayReady 授權傳遞服務 (請參閱下列程式碼中定義的 ConfigureLicenseDeliveryService 方法)。如需媒體服務 PlayReady 授權傳遞服務的詳細資訊,請參閱<使用 PlayReady 動態加密和授權傳遞服務>。

note附註
若要傳遞使用 PlayReady 所加密的 MPEG DASH,請一定要使用 CENC 選項,方法是將 useSencBox 和 adjustSubSamples 屬性 (如<Azure Media Encryptor 工作預設值>主題所述) 設定為 true。

您可以從下列網址下載「PlayReady 靜態加密」專案:https://github.com/Azure/azure-media-services-samples

以下主題會顯示如可設定 Media Services 開發。

  1. Setup for Development on the Media Services SDK for .NET

    請注意本主題中的程式碼是使用 Azure Media Services .NET SDK 延伸模組。 The Media Services .NET SDK 延伸模組是一組延伸模組方法及 Helper 函數,會簡化您的程式碼並讓其能更容易地以 Media Services 開發。

  2. 使用 Media Services SDK 連接到 Media Services

  1. 以出現在範例一節中的程式碼覆寫您 Program.cs 檔案中的程式碼。

    確定更新下列程式碼到您輸入 MP4 檔案所在位置的資料夾。

    以及 MediaPackager_MP4ToSmooth.xml 和 MediaEncryptor_PlayReadyProtection.xml 檔案的所在位置。MediaPackager_MP4ToSmooth.xml 在<Azure Media Packager 工作預設值>中定義,而 MediaEncryptor_PlayReadyProtection.xml 在<Azure Media Encryptor 工作預設值>主題中定義。

    note附註
    要串流以 PlayReady 加密的 MPEG DASH,請確定設定MediaEncryptor_PlayReadyProtection.xml 設定的 useSencBoxadjustSubSamples 屬性為 true

    private static readonly string _mediaFiles =
    Path.GetFullPath(@"../..\Media");
    
    private static readonly string _singleMP4File =
         Path.Combine(_mediaFiles, @"SingleMP4\BigBuckBunny.mp4");
    
    // XML Configruation files path.
    private static readonly string _configurationXMLFiles = @"../..\Configurations\";
    
    
  2. 建立並執行您的程式。

下列範例將進行:

  1. 內嵌單一 MP4 檔案。

  2. 使用"H264 Adaptive Bitrate MP4 Set 720p",編碼預設編碼 MP4 為多位元 MP4接著,封裝多位元 MP4 為 Smooth Stream。MediaPackager_MP4ToSmooth.xmlMediaPackager_SmoothToHLS.xml 設定用於這些封裝工作。

  3. 使用 PlayReady 加密 Smooth Streaming。MediaEncryptor_PlayReadyProtection.xml 設定已用於此工作。

    note附註
    此範例定義您用來動態更新 MediaEncryptor_PlayReadyProtection.xml 檔案的 UpdatePlayReadyConfigurationXMLFile 方法。如有可用的金鑰種子,即可使用 GeneratePlayReadyContentKey 方法來產生以 keySeedValue 和 KeyId 直為基礎的內容金鑰。

  4. 建立 OnDemand Locator 並取得串流 URL。

    GetSmoothStreamingUri 和 GetMpegDashUri 延伸模組方法會傳回下列形式的串流 URL:{media services account name}.origin.mediaservices.net/{locator ID}/{filename}.ism/Manifest 適用於 Smooth Streaming 而 {media services account name}.origin.mediaservices.net/{locator ID}/{filename}.ism/Manifest(format=mpd-time-csf)  適用於 MPEG DASH。

    您可以使用 http://smf.cloudapp.net/healthmonitor 播放器測試 Smooth Streaming。您可以使用 dashif.org 來測試 DASH 資料流 (選取最新版本的播放器)。

如需詳細資訊,請參閱程式碼註解。

using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.WindowsAzure.MediaServices.Client;
using System.Xml.Linq;
using Microsoft.WindowsAzure.MediaServices.Client.ContentKeyAuthorization;
using Microsoft.WindowsAzure.MediaServices.Client.DynamicEncryption;

namespace PlayReadyStaticEncryptAndKeyDeliverySvc
{
    class Program
    {
       
        private static readonly string _mediaFiles =
            Path.GetFullPath(@"../..\Media");

        private static readonly string _singleMP4File =
            Path.Combine(_mediaFiles, @"BigBuckBunny.mp4");

        // XML Configruation files path.
        private static readonly string _configurationXMLFiles = @"../..\Configurations\";


        private static MediaServicesCredentials _cachedCredentials = null;
        private static CloudMediaContext _context = null;

        // Media Services account information.
        private static readonly string _mediaServicesAccountName =
            ConfigurationManager.AppSettings["MediaServiceAccountName"];
        private static readonly string _mediaServicesAccountKey =
            ConfigurationManager.AppSettings["MediaServiceAccountKey"];

        static void Main(string[] args)
        {
            // Create and cache the Media Services credentials in a static class variable.
            _cachedCredentials = new MediaServicesCredentials(
                            _mediaServicesAccountName,
                            _mediaServicesAccountKey);
            // Use the cached credentials to create CloudMediaContext.
            _context = new CloudMediaContext(_cachedCredentials);

            // Encoding and encrypting assets //////////////////////
            // Load a single MP4 file.
            IAsset asset = IngestSingleMP4File(_singleMP4File, AssetCreationOptions.None);

            // Encode an MP4 file to a set of multibitrate MP4s.
            // Then, package a set of MP4s to clear Smooth Streaming.
            IAsset clearSmoothStreamAsset =
                ConvertMP4ToMultibitrateMP4sToSmoothStreaming(asset);

            // Create a common encryption content key that is used 
            // a) to set the key values in the MediaEncryptor_PlayReadyProtection.xml file
            //    that is used for encryption.
            // b) to configure the license delivery service and 
            //
            Guid keyId;
            byte[] contentKey;

            IContentKey key = CreateCommonEncryptionKey(out keyId, out contentKey);

            // The content key authorization policy must be configured by you 
            // and met by the client in order for the PlayReady license
            // to be delivered to the client. 
            // In this example the Media Services PlayReady license delivery service is used.
            ConfigureLicenseDeliveryService(key);

            // Get the Media Services PlayReady license delivery URL.
            // This URL will be assigned to the licenseAcquisitionUrl property 
            // of the MediaEncryptor_PlayReadyProtection.xml file.
            Uri acquisitionUrl = key.GetKeyDeliveryUrl(ContentKeyDeliveryType.PlayReadyLicense);

            // Update the MediaEncryptor_PlayReadyProtection.xml file with the key and URL info.
            UpdatePlayReadyConfigurationXMLFile(keyId, contentKey, acquisitionUrl);


            // Encrypt your clear Smooth Streaming to Smooth Streaming with PlayReady.
            IAsset outputAsset = CreateSmoothStreamEncryptedWithPlayReady(clearSmoothStreamAsset);


            // You can use the http://smf.cloudapp.net/healthmonitor player 
            // to test the smoothStreamURL URL.
            string smoothStreamURL = outputAsset.GetSmoothStreamingUri().ToString();
            Console.WriteLine("Smooth Streaming URL:");
            Console.WriteLine(smoothStreamURL);

            // You can use the http://dashif.org/reference/players/javascript/ player 
            // to test the dashURL URL.
            string dashURL = outputAsset.GetMpegDashUri().ToString();
            Console.WriteLine("MPEG DASH URL:");
            Console.WriteLine(dashURL);
        }

        /// <summary>
        /// Creates a job with 2 tasks: 
        /// 1 task - encodes a single MP4 to multibitrate MP4s,
        /// 2 task - packages MP4s to Smooth Streaming.
        /// </summary>
        /// <returns>The output asset.</returns>
        public static IAsset ConvertMP4ToMultibitrateMP4sToSmoothStreaming(IAsset asset)
        {
            // Create a new job.
            IJob job = _context.Jobs.Create("Convert MP4 to Smooth Streaming.");

            // Add task 1 - Encode single MP4 into multibitrate MP4s.
            IAsset MP4sAsset = EncodeMP4IntoMultibitrateMP4sTask(job, asset);
            // Add task 2 - Package a multibitrate MP4 set to Clear Smooth Stream.
            IAsset packagedAsset = PackageMP4ToSmoothStreamingTask(job, MP4sAsset);

            // Submit the job and wait until it is completed.
            job.Submit();
            job = job.StartExecutionProgressTask(
                j =>
                {
                    Console.WriteLine("Job state: {0}", j.State);
                    Console.WriteLine("Job progress: {0:0.##}%", j.GetOverallProgress());
                },
                CancellationToken.None).Result;

            // Get the output asset that contains the Smooth Streaming asset.
            return job.OutputMediaAssets[1];
        }

        /// <summary>
        /// Encrypts Smooth Stream with PlayReady.
        /// Then creates a Smooth Streaming Url.
        /// </summary>
        /// <param name="clearSmoothAsset">Asset that contains clear Smooth Streaming.</param>
        /// <returns>The output asset.</returns>
        public static IAsset CreateSmoothStreamEncryptedWithPlayReady(IAsset clearSmoothStreamAsset)
        {
            // Create a job.
            IJob job = _context.Jobs.Create("Encrypt to PlayReady Smooth Streaming.");

            // Add task 1 - Encrypt Smooth Streaming with PlayReady 
            IAsset encryptedSmoothAsset =
                EncryptSmoothStreamWithPlayReadyTask(job, clearSmoothStreamAsset);

            // Submit the job and wait until it is completed.
            job.Submit();
            job = job.StartExecutionProgressTask(
                j =>
                {
                    Console.WriteLine("Job state: {0}", j.State);
                    Console.WriteLine("Job progress: {0:0.##}%", j.GetOverallProgress());
                },
                CancellationToken.None).Result;

            // The OutputMediaAssets[0] contains the desired asset.
            _context.Locators.Create(
                LocatorType.OnDemandOrigin,
                job.OutputMediaAssets[0],
                AccessPermissions.Read,
                TimeSpan.FromDays(30));

            return job.OutputMediaAssets[0];
        }

        /// <summary>
        /// Create a common encryption content key that is used 
        /// to set the key values in the MediaEncryptor_PlayReadyProtection.xml file
        /// that is used for encryption.
        /// </summary>
        /// <param name="keyId"></param>
        /// <param name="contentKey"></param>
        /// <returns></returns>
        public static IContentKey CreateCommonEncryptionKey(out Guid keyId, out byte[] contentKey)
        {
            keyId = Guid.NewGuid();
            contentKey = GetRandomBuffer(16);

            IContentKey key = _context.ContentKeys.Create(
                                    keyId,
                                    contentKey,
                                    "ContentKey",
                                    ContentKeyType.CommonEncryption);

            return key;
        }

        /// <summary>
        /// Update your configuration .xml file dynamically.
        /// </summary>
        public static void UpdatePlayReadyConfigurationXMLFile(Guid keyId, byte[] keyValue, Uri licenseAcquisitionUrl)
        {
            string xmlFileName = Path.Combine(_configurationXMLFiles,
                                        @"MediaEncryptor_PlayReadyProtection.xml");

            XNamespace xmlns = "http://schemas.microsoft.com/iis/media/v4/TM/TaskDefinition#";

            // Prepare the encryption task template
            XDocument doc = XDocument.Load(xmlFileName);

            var licenseAcquisitionUrlEl = doc
                    .Descendants(xmlns + "property")
                    .Where(p => p.Attribute("name").Value == "licenseAcquisitionUrl")
                    .FirstOrDefault();
            var contentKeyEl = doc
                    .Descendants(xmlns + "property")
                    .Where(p => p.Attribute("name").Value == "contentKey")
                    .FirstOrDefault();
            var keyIdEl = doc
                    .Descendants(xmlns + "property")
                    .Where(p => p.Attribute("name").Value == "keyId")
                    .FirstOrDefault();

            // Update the "value" property.
            if (licenseAcquisitionUrlEl != null)
                licenseAcquisitionUrlEl.Attribute("value").SetValue(licenseAcquisitionUrl.ToString());

            if (contentKeyEl != null)
                contentKeyEl.Attribute("value").SetValue(Convert.ToBase64String(keyValue));

            if (keyIdEl != null)
                keyIdEl.Attribute("value").SetValue(keyId);

            doc.Save(xmlFileName);
        }

        /// <summary>
        /// Uploads a single file.
        /// </summary>
        /// <param name="fileDir">The location of the files.</param>
        /// <param name="assetCreationOptions">
        ///  You can specify the following encryption options for the AssetCreationOptions.
        ///      None:  no encryption.  
        ///      StorageEncrypted: storage encryption. Encrypts a clear input file 
        ///        before it is uploaded to Azure storage. 
        ///      CommonEncryptionProtected: for Common Encryption Protected (CENC) files. 
        ///        For example, a set of files that are already PlayReady encrypted. 
        ///      EnvelopeEncryptionProtected: for HLS with AES encryption files.
        ///        NOTE: The files must have been encoded and encrypted by Transform Manager. 
        ///     </param>
        /// <returns>Returns an asset that contains a single file.</returns>
        /// </summary>
        /// <returns></returns>
        private static IAsset IngestSingleMP4File(string fileDir, AssetCreationOptions assetCreationOptions)
        {
            // Use the SDK extension method to create a new asset by 
            // uploading a mezzanine file from a local path.
            IAsset asset = _context.Assets.CreateFromFile(
                fileDir,
                assetCreationOptions,
                (af, p) =>
                {
                    Console.WriteLine("Uploading '{0}' - Progress: {1:0.##}%", af.Name, p.Progress);
                });

            return asset;
        }

        /// <summary>
        /// Creates a task to encode to Adaptive Bitrate. 
        /// Adds the new task to a job.
        /// </summary>
        /// <param name="job">The job to which to add the new task.</param>
        /// <param name="asset">The input asset.</param>
        /// <returns>The output asset.</returns>
        private static IAsset EncodeMP4IntoMultibitrateMP4sTask(IJob job, IAsset asset)
        {
            // Get the SDK extension method to  get a reference to the Azure Media Encoder.
            IMediaProcessor encoder = _context.MediaProcessors.GetLatestMediaProcessorByName(
                MediaProcessorNames.WindowsAzureMediaEncoder);

            ITask adpativeBitrateTask = job.Tasks.AddNew("MP4 to Adaptive Bitrate Task",
               encoder,
               "H264 Adaptive Bitrate MP4 Set 720p",
               TaskOptions.None);

            // Specify the input Asset
            adpativeBitrateTask.InputAssets.Add(asset);

            // Add an output asset to contain the results of the job. 
            // This output is specified as AssetCreationOptions.None, which 
            // means the output asset is in the clear (unencrypted).
            IAsset abrAsset = adpativeBitrateTask.OutputAssets.AddNew("Multibitrate MP4s",
                                    AssetCreationOptions.None);

            return abrAsset;
        }

        /// <summary>
        /// Creates a task to convert the MP4 file(s) to a Smooth Streaming asset.
        /// Adds the new task to a job.
        /// </summary>
        /// <param name="job">The job to which to add the new task.</param>
        /// <param name="asset">The input asset.</param>
        /// <returns>The output asset.</returns>
        private static IAsset PackageMP4ToSmoothStreamingTask(IJob job, IAsset asset)
        {
            // Get the SDK extension method to  get a reference to the Azure Media Packager.
            IMediaProcessor packager = _context.MediaProcessors.GetLatestMediaProcessorByName(
                MediaProcessorNames.WindowsAzureMediaPackager);

            // Azure Media Packager does not accept string presets, so load xml configuration
            string smoothConfig = File.ReadAllText(Path.Combine(
                        _configurationXMLFiles,
                        "MediaPackager_MP4toSmooth.xml"));

            // Create a new Task to convert adaptive bitrate to Smooth Streaming.
            ITask smoothStreamingTask = job.Tasks.AddNew("MP4 to Smooth Task",
               packager,
               smoothConfig,
               TaskOptions.None);

            // Specify the input Asset, which is the output Asset from the first task
            smoothStreamingTask.InputAssets.Add(asset);

            // Add an output asset to contain the results of the job. 
            // This output is specified as AssetCreationOptions.None, which 
            // means the output asset is in the clear (unencrypted).
            IAsset smoothOutputAsset =
                smoothStreamingTask.OutputAssets.AddNew("Clear Smooth Stream",
                    AssetCreationOptions.None);

            return smoothOutputAsset;
        }


        /// <summary>
        /// Creates a task to encrypt Smooth Streaming with PlayReady.
        /// Note: To deliver DASH, make sure to set the useSencBox and adjustSubSamples 
        /// configuration properties to true. 
        /// In this example, MediaEncryptor_PlayReadyProtection.xml contains configuration.
        /// </summary>
        /// <param name="job">The job to which to add the new task.</param>
        /// <param name="asset">The input asset.</param>
        /// <returns>The output asset.</returns>
        private static IAsset EncryptSmoothStreamWithPlayReadyTask(IJob job, IAsset asset)
        {
            // Get the SDK extension method to  get a reference to the Azure Media Encryptor.
            IMediaProcessor playreadyProcessor = _context.MediaProcessors.GetLatestMediaProcessorByName(
                MediaProcessorNames.WindowsAzureMediaEncryptor);

            // Read the configuration XML.
            //
            // Note that the configuration defined in MediaEncryptor_PlayReadyProtection.xml
            // is using keySeedValue. It is recommended that you do this only for testing 
            // and not in production. For more information, see 
            // http://msdn.microsoft.com/en-us/library/windowsazure/dn189154.aspx.
            //
            string configPlayReady = File.ReadAllText(Path.Combine(_configurationXMLFiles,
                                        @"MediaEncryptor_PlayReadyProtection.xml"));

            ITask playreadyTask = job.Tasks.AddNew("My PlayReady Task",
               playreadyProcessor,
               configPlayReady,
               TaskOptions.ProtectedConfiguration);

            playreadyTask.InputAssets.Add(asset);

            // Add an output asset to contain the results of the job. 
            // This output is specified as AssetCreationOptions.CommonEncryptionProtected.
            IAsset playreadyAsset = playreadyTask.OutputAssets.AddNew(
                                            "PlayReady Smooth Streaming",
                                            AssetCreationOptions.CommonEncryptionProtected);

            return playreadyAsset;
        }

        /// <summary>
        /// Configures authorization policy for the content key. 
        /// </summary>
        /// <param name="contentKey">The content key.</param>
        static public void ConfigureLicenseDeliveryService(IContentKey contentKey)
        {
            // Create ContentKeyAuthorizationPolicy with Open restrictions 
            // and create authorization policy          

            List<ContentKeyAuthorizationPolicyRestriction> restrictions = new List<ContentKeyAuthorizationPolicyRestriction>
            {
                new ContentKeyAuthorizationPolicyRestriction 
                { 
                    Name = "Open", 
                    KeyRestrictionType = (int)ContentKeyRestrictionType.Open, 
                    Requirements = null
                }
            };

            // Configure PlayReady license template.
            string newLicenseTemplate = ConfigurePlayReadyLicenseTemplate();

            IContentKeyAuthorizationPolicyOption policyOption =
                _context.ContentKeyAuthorizationPolicyOptions.Create("",
                    ContentKeyDeliveryType.PlayReadyLicense,
                        restrictions, newLicenseTemplate);

            IContentKeyAuthorizationPolicy contentKeyAuthorizationPolicy = _context.
                        ContentKeyAuthorizationPolicies.
                        CreateAsync("Deliver Common Content Key with no restrictions").
                        Result;


            contentKeyAuthorizationPolicy.Options.Add(policyOption);

            // Associate the content key authorization policy with the content key.
            contentKey.AuthorizationPolicyId = contentKeyAuthorizationPolicy.Id;
            contentKey = contentKey.UpdateAsync().Result;
        }

        static private string ConfigurePlayReadyLicenseTemplate()
        {
            // The following code configures PlayReady License Template using .NET classes
            // and returns the XML string.

            PlayReadyLicenseResponseTemplate responseTemplate = new PlayReadyLicenseResponseTemplate();
            PlayReadyLicenseTemplate licenseTemplate = new PlayReadyLicenseTemplate();

            responseTemplate.LicenseTemplates.Add(licenseTemplate);

            return MediaServicesLicenseTemplateSerializer.Serialize(responseTemplate);
        }

        static private byte[] GetRandomBuffer(int length)
        {
            var returnValue = new byte[length];

            using (var rng =
                new System.Security.Cryptography.RNGCryptoServiceProvider())
            {
                rng.GetBytes(returnValue);
            }

            return returnValue;
        }
    }
}

另請參閱

Microsoft 正展開一份線上問卷調查,了解您對於 MSDN 網站的看法。 如果您選擇參加,您離開 MSDN 網站時即會顯示線上問卷調查。

您是否想要參加?
顯示:
© 2015 Microsoft