匯出 (0) 列印
全部展開
本主題尚未接受評分 - 為這個主題評分

開始使用 Media Services SDK for .NET

更新日期: 2014年2月

本主題是針對 Windows Azure Media Services 新開發人員的逐步解說。文中會介紹基本 Media Services 工作流程和最常用的程式設計物件,以及 Media Services 開發的必要工作。如果想要對 Media Services 開發程序與程式設計物件模型有基本的認識,請參閱Windows Media Services 簡介

包含本教學課程使用之程式碼的 C# Visual Studio 專案位於這中:下載

在逐步解說中,您會學到下列 Media Services 程式設計工作。

  • 取得 Media Services 伺服器內容

  • 建立資產

  • 將與資產相關的檔案上傳到 Media Services

  • 將資產編碼

  • 下載輸出資產

您完成教學課程之後,將能夠播放自己上傳、編碼及下載的範例媒體檔案。或者可以瀏覽至編碼資產,並在伺服器上播放。

對於逐步解說和使用 Windows Azure Media Services SDK 為基礎的開發而言,需要下列必要條件。

  • 新增或現有的 Windows Azure 訂閱的 Media Services 帳戶。請參閱「如何建立 Media Services 帳戶」主題。

  • 作業系統:Windows 7、Windows 2008 R2 或 Windows 8。

  • .NET Framework 4.5 或 .NET Framework 4。

  • Visual Studio 2012 或 Visual Studio 2010 SP1 (Professional、Premium、Ultimate 或 Express)。

  • 使用 windowsazure.mediaservices Nuget 封裝安裝 Windows Azure SDK for .NET.Windows Azure Media Services SDK for .NETWCF Data Services 5.0 for OData V3 程式庫,並新增您專案的參考。下一節示範如何安裝及新增這些參考。

  1. 在 Visual Studio 2012 或 Visual Studio 2010 SP1 中建立新的 C# 主控台應用程式。輸入 [名稱]、[位置] 及 [方案名稱],然後按一下 [確定]。

  2. 新增參考至 System.Configuration 組件。

    若要使用 [管理參考] 對話方塊新增參考,請執行下列步驟。在 [方案總管] 中的 [參考] 節點上按一下滑鼠右鍵,然後選取 [新增參考…]。在 [管理參考] 對話方塊中,選取適當的組件 (在此例中為 System.Configuration)。

  3. 如果還沒有新增參考,請使用 windowsazure.mediaservices Nuget 封裝新增參考至 Windows Azure SDK for .NET. (Microsoft.WindowsAzure.StorageClient.dll)、Windows Azure Media Services SDK for .NET (Microsoft.WindowsAzure.MediaServices.Client.dll) 及 WCF Data Services 5.0 for OData V3 (Microsoft.Data.OData.dll) 程式庫。

    若要使用 Nuget 新增參考,請執行下列步驟。在 Visual Studio 主功能表中,選取 [工具] -> [程式庫套件管理員] -> [Package Manager Console]。在主控台視窗中輸入 Install-Package [package name],然後按 Enter 鍵 (在此例中,使用以下命令:Install-Package windowsazure.mediaservices.)

  4. 在 app.config 檔案中新增 appSettings 區段,並設定您的 Media Services 帳戶名稱與帳戶金鑰的值。您在設定帳戶的時候取得 Media Services 帳戶名稱與帳戶金鑰。將這些值加入 Visual Studio 專案中 app.config 檔案中每一項設定的 value 屬性。

    note附註
    在 Visual Studio 2012 中,預設會新增 App.config 檔案。在 Visual Studio 2010 中,必須手動新增應用程式組態檔案。

    <?xml version="1.0"?>
    <configuration>
      . . . 
      <appSettings>
        <add key="accountName" value="Add-Media-Services-Account-Name" />
        <add key="accountKey" value="Add-Media-Services-Account-Key" />
      </appSettings>
    </configuration>
    
  5. 在您的本機電腦上建立新資料夾,並命名為 supportFiles (在此例中,supportFiles 位於 MediaServicesGettingStarted 專案目錄下)。本逐步解說隨附的專案包含 supportFiles 目錄。您可以將此目錄的內容複製到您的 supportFiles 資料夾中。

  6. 用下列的程式碼覆寫 Program.cs 檔案開頭處現有的 using 陳述式。

    using System;
    using System.Linq;
    using System.Configuration;
    using System.IO;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Collections.Generic;
    using Microsoft.WindowsAzure;
    using Microsoft.WindowsAzure.MediaServices.Client;
    
    
  7. 新增下列類別層級路徑變數。_supportFiles 路徑應指向您在前步驟建立的資料夾。

    // Base support files path.  Update this field to point to the base path  
    // for the local support files folder that you create. 
    private static readonly string _supportFiles =
                Path.GetFullPath(@"../..\supportFiles");
    
    // Paths to support files (within the above base path). You can use 
    // the provided sample media files from the "supportFiles" folder, or 
    // provide paths to your own media files below to run these samples.
    private static readonly string _singleInputFilePath =
        Path.GetFullPath(_supportFiles + @"\multifile\interview2.wmv");
    private static readonly string _outputFilesFolder =
        Path.GetFullPath(_supportFiles + @"\outputfiles");
    
    
  8. 新增下列類別層級變數以擷取驗證和連線設定。這些設定從 App.Config 檔案提取,連接到 Media Services、驗證及取得權杖以便存取伺服器內容時需要這些設定。專案中的程式碼參考這些變數,以建立伺服器內容的執行個體。

    
    private static readonly string _accountKey = ConfigurationManager.AppSettings["accountKey"];
    private static readonly string _accountName = ConfigurationManager.AppSettings["accountName"];
    
    
  9. 新增以下類別層級變數,此變數做為伺服器內容的靜態參考。

    // Field for service context.
    private static CloudMediaContext _context = null;
    

Media Services 內容物件包含 Media Services 程式設計時要存取的所有基礎物件與集合。內容包含對重要集合的參考,包括工作、資產、檔案、存取原則、定位器及其他物件。您必須取得大多數 Media Services 程式設計工作的伺服器內容。

在 Program.cs 檔案中,新增以下程式碼做為 Main 方法的第項目。這段程式碼使用您的 app.config 檔案中的 Media Services 帳戶名稱與帳戶金鑰值,來建立伺服器內容的執行個體。執行個體指派給您在類別層級建立的 _context 變數。

// Get the service context.
_context = new CloudMediaContext(_accountName, _accountKey);

本節中的程式碼會執行下列動作:

  1. 建立空白資產

    您建立資產時,可以指定三種不同的加密選項。

    • AssetCreationOptions.None:不加密。如果要建立未加密的資產,必須設定此選項。

    • AssetCreationOptions.CommonEncryptionProtected:用於 Common Encryption Protected (CENC) 檔案。例如已經有 PlayReady 加密的一組檔案。

    • AssetCreationOptions.StorageEncrypted:儲存體加密。將未加密的輸入檔案上傳到 Azure 儲存體之前,先將檔案加密。

      note附註
      請注意,Media Services 提供磁碟上儲存體加密,而非透過 Digital Rights Manager (DRM) 等線路加密。

  2. 建立要與資產相關聯的 AssetFile 執行個體。

  3. 建立定義權限與資產存取權持續時間的 AccessPolicy 執行個體。

  4. 建立提供資產存取權的定位器執行個體。

  5. 將單一媒體檔案上傳到 Media Services。建立與上傳的程序也稱為擷取資產。

將下列方法新增到類別。

static private IAsset CreateEmptyAsset(string assetName, AssetCreationOptions assetCreationOptions)
{
    var asset = _context.Assets.Create(assetName, assetCreationOptions);

    Console.WriteLine("Asset name: " + asset.Name);
    Console.WriteLine("Time created: " + asset.Created.Date.ToString());

    return asset;
}

static public IAsset CreateAssetAndUploadSingleFile(AssetCreationOptions assetCreationOptions, string singleFilePath)
{
    var assetName = "UploadSingleFile_" + DateTime.UtcNow.ToString();
    var asset = CreateEmptyAsset(assetName, assetCreationOptions);

    var fileName = Path.GetFileName(singleFilePath);

    var assetFile = asset.AssetFiles.Create(fileName);

    Console.WriteLine("Created assetFile {0}", assetFile.Name);

    var accessPolicy = _context.AccessPolicies.Create(assetName, TimeSpan.FromDays(3),
                                                        AccessPermissions.Write | AccessPermissions.List);

    var locator = _context.Locators.CreateLocator(LocatorType.Sas, asset, accessPolicy);

    Console.WriteLine("Upload {0}", assetFile.Name);

    assetFile.Upload(singleFilePath);
    Console.WriteLine("Done uploading of {0} using Upload()", assetFile.Name);

    locator.Delete();
    accessPolicy.Delete();

    return asset;
}

Main 方法中 _context = new CloudMediaContext(_accountName, _accountKey); 這一行之後加入對方法的呼叫。

IAsset asset = CreateAssetAndUploadSingleFile(AssetCreationOptions.None, _singleInputFilePath)

在 Media Services 中,可以建立以許多種方法處理媒體內容的工作 (Job):編碼、加密、執行格式轉換等。Media Services 工作 (Job) 一定會包含一或多個工作 (Task),這些工作 (Task) 指定如何處理工作的詳細資料。您在本節中建立基本的編碼工作 (Task),然後執行使用 Windows Azure Media Encoder 來執行的工作 (Job)。工作 (Task) 使用預設字串指定要執行的編碼類型。若要查看可用的預設編碼值,請參閱「Windows Azure Media Encoder 的工作預設字串」。Media Services 支援的媒體檔案輸入與輸出格式和 Microsoft Expression Encoder 相同。關於支援之格式的清單,請參閱「Windows Azure Media Encoder 支援的轉碼器與檔案類型」。

  1. 將以下 CreateEncodingJob 方法定義新增到您的類別。此方法會完成編碼工作 (Job) 的許多必要步驟:

    • 宣告新工作 (Job)。

    • 宣告負責處理工作 (Job) 的媒體處理器。媒體處理器是元件,負責處理編碼、加密、格式轉換及其他相關的處理工作 (Job)。媒體處理器有許多種 (可以使用 _context.MediaProcessors 逐一查看所有的處理器)。本逐步解說後面介紹的 GetLatestMediaProcessorByName 方法會傳回 Windows Azure Media Encoder 處理器。

    • 宣告新工作 (Task)。每個工作 (Job) 有一或多個工作 (Task)。請注意,處理工作 (Task) 時,您傳遞給它易記名稱、媒體處理器執行個體、工作 (Task) 組態字串,以及一些工作 (Task) 建立選項。組態字串指定編碼設定。此範例使用 H264 Broadband 720p 設定。此預設值會產生 MP4 檔案。如需此預設值和其他預設值的詳細資訊,請參閱Windows Azure Media Encoder 的工作預設字串

    • 將輸入資產新增到工作 (Task)。在此範例中,輸入資產是您在前一節中建立的資產。

    • 將輸出資產新增到工作 (Task)。為輸出資產指定易記名稱、指示是否要在完成工作 (Job) 後將輸出儲存在伺服器上的布林值,以及指定儲存與傳輸輸出時不要加密的 AssetCreationOptions.None 值。

    • 送出工作 (Job)。

      送出工作 (Job) 是執行編碼工作的最後必要步驟。



    方法會執行其他有用但可以選擇的工作 (Task),例如追蹤工作 (Job) 進度及存取您的編碼工作 (Job) 建立的資產:

    • 新增協助程式方法的呼叫以檢查工作 (Job) 進度。這是輪詢方法,會檢查工作 (Job) 狀態並在主控台顯示狀態。

    • 取得工作 (Job) 的更新參考。在 CheckJobProgress 之類的方法之後 (此方法可以讓執行緒上的處理程序停止),必須重新整理工作 (Job) 參考。

    • 取得工作 (Job) 所產生之輸出媒體資產的參考。

    • 呼叫協助程式方法 GetAssetSasUrl 以建立伺服器上之持續輸出資產的共用存取簽章 (SAS) URL。您可以在方法執行完畢後使用此 URL,直接瀏覽至輸出資產。

    • 將 SAS URL 寫入本機檔案。在本逐步解說中將 URL 寫入檔案的原因,是為了方便擷取 URL。

    • 將輸出下載至到機電腦。

    static IJob CreateEncodingJob(IAsset asset, string inputMediaFilePath, string outputFolder)
    {
        // Declare a new job.
        IJob job = _context.Jobs.Create("My encoding job");
        // Get a media processor reference, and pass to it the name of the 
        // processor to use for the specific task.
        IMediaProcessor processor = GetLatestMediaProcessorByName("Windows Azure Media Encoder");
    
        // Create a task with the encoding details, using a string preset.
        ITask task = job.Tasks.AddNew("My encoding task",
            processor,
            "H264 Broadband 720p",
            Microsoft.WindowsAzure.MediaServices.Client.TaskOptions.ProtectedConfiguration);
    
        // Specify the input asset to be encoded.
        task.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 not encrypted. 
        task.OutputAssets.AddNew("Output asset",
            AssetCreationOptions.None);
        // Use the following event handler to check job progress.  
        job.StateChanged += new
                EventHandler<JobStateChangedEventArgs>(StateChanged);
    
        // Launch the job.
        job.Submit();
    
        // Optionally log job details. This displays basic job details
        // to the console and saves them to a JobDetails-{JobId}.txt file 
        // in your output folder.
        LogJobDetails(job.Id);
    
        // Check job execution and wait for job to finish. 
        Task progressJobTask = job.GetExecutionProgressTask(CancellationToken.None);
        progressJobTask.Wait();
    
        // **********
        // Optional code.  Code after this point is not required for 
        // an encoding job, but shows how to access the assets that 
        // are the output of a job, either by creating URLs to the 
        // asset on the server, or by downloading. 
        // **********
    
        // Get an updated job reference.
        job = GetJob(job.Id);
    
        // If job state is Error the event handling 
        // method for job progress should log errors.  Here we check 
        // for error state and exit if needed.
        if (job.State == JobState.Error)
        {
            Console.WriteLine("\nExiting method due to job error.");
            return job;
        }
    
        // Get a reference to the output asset from the job.
        IAsset outputAsset = job.OutputMediaAssets[0];
        IAccessPolicy policy = null;
        ILocator locator = null;
    
        // Declare an access policy for permissions on the asset. 
        // You can call an async or sync create method. 
        policy =
            _context.AccessPolicies.Create("My 30 days readonly policy",
                TimeSpan.FromDays(30),
                AccessPermissions.Read);
    
        // Create a SAS locator to enable direct access to the asset 
        // in blob storage. You can call a sync or async create method.  
        // You can set the optional startTime param as 5 minutes 
        // earlier than Now to compensate for differences in time  
        // between the client and server clocks. 
    
        locator = _context.Locators.CreateLocator(LocatorType.Sas, outputAsset,
            policy,
            DateTime.UtcNow.AddMinutes(-5));
    
        // Build a list of SAS URLs to each file in the asset. 
        List<String> sasUrlList = GetAssetSasUrlList(outputAsset, locator);
    
        // Write the URL list to a local file. You can use the saved 
        // SAS URLs to browse directly to the files in the asset.
        if (sasUrlList != null)
        {
            string outFilePath = Path.GetFullPath(outputFolder + @"\" + "FileSasUrlList.txt");
            StringBuilder fileList = new StringBuilder();
            foreach (string url in sasUrlList)
            {
                fileList.AppendLine(url);
                fileList.AppendLine();
            }
            WriteToFile(outFilePath, fileList.ToString());
    
            // Optionally download the output to the local machine.
            DownloadAssetToLocal(job.Id, outputFolder);
        }
    
        // The following functions will delete 
        // Locators, Assets, etc. that were created. 
        // If you want to delete any or all of the created resources
        // uncomment the function calls. 
    
        //DeleteLocatorsForAsset(asset);
        //DeleteLocatorsForAsset(outputAsset);
    
        //DeleteAssetFilesForAsset(asset);
        //DeleteAssetFilesForAsset(outputAsset);
                
        //// Delete assets
        //DeleteAsset(asset);
        //DeleteAsset(outputAsset);
                
        //DeleteAccessPolicy(policy.Id);
    
        return job;
    }
    
    
  2. Main 方法中先前新增的幾行後面,新增對 CreateEncodingJob 方法的呼叫。

    CreateEncodingJob(asset, _singleInputFilePath, _outputFilesFolder);
    
  3. 將下列協助程式方法新增到類別。這些是支援 CreateEncodingJob 方法的必要項目。以下是協助程式方法的摘要。

    • GetLatestMediaProcessorByName 方法會傳回適當的媒體處理器,以處理編碼、加密或其他相關的處理工作 (Task)。您使用適合想要建立之處理器的字串名稱,來建立媒體處理器。可以傳遞到方法之 mediaProcessor 參數的可能字串:

      • Windows Azure Media Encoder

      • Windows Azure Media Packager

      • Windows Azure Media Encryptor

      • Storage Decryption

      private static IMediaProcessor GetLatestMediaProcessorByName(string mediaProcessorName)
      {
          // The possible strings that can be passed into the 
          // method for the mediaProcessor parameter:
          //   Windows Azure Media Encoder
          //   Windows Azure Media Packager
          //   Windows Azure Media Encryptor
          //   Storage Decryption
      
          var processor = _context.MediaProcessors.Where(p => p.Name == mediaProcessorName).
              ToList().OrderBy(p => new Version(p.Version)).LastOrDefault();
      
          if (processor == null)
              throw new ArgumentException(string.Format("Unknown media processor", mediaProcessorName));
      
          return processor;
      }
      
    • 您執行工作 (Job) 時,往往需要追蹤工作進度的方法。以下程式碼範例定義 StateChanged 事件處理常式。此事件處理常式會追蹤工作 (Job) 進度,並根據狀況提供更新的狀態。這段程式碼也定義 LogJobStop 方法。此協助程式方法會記錄錯誤詳細資料。

      private static void StateChanged(object sender, JobStateChangedEventArgs e)
      {
          Console.WriteLine("Job state changed event:");
          Console.WriteLine("  Previous state: " + e.PreviousState);
          Console.WriteLine("  Current state: " + e.CurrentState);
      
          switch (e.CurrentState)
          {
              case JobState.Finished:
                  Console.WriteLine();
                  Console.WriteLine("********************");
                  Console.WriteLine("Job is finished.");
                  Console.WriteLine("Please wait while local tasks or downloads complete...");
                  Console.WriteLine("********************");
                  Console.WriteLine();
                  Console.WriteLine();
                  break;
              case JobState.Canceling:
              case JobState.Queued:
              case JobState.Scheduled:
              case JobState.Processing:
                  Console.WriteLine("Please wait...\n");
                  break;
              case JobState.Canceled:
              case JobState.Error:
                  // Cast sender as a job.
                  IJob job = (IJob)sender;
                  // Display or log error details as needed.
                  LogJobStop(job.Id);
                  break;
              default:
                  break;
          }
      }
      
      private static void LogJobStop(string jobId)
      {
          StringBuilder builder = new StringBuilder();
          IJob job = GetJob(jobId);
      
          builder.AppendLine("\nThe job stopped due to cancellation or an error.");
          builder.AppendLine("***************************");
          builder.AppendLine("Job ID: " + job.Id);
          builder.AppendLine("Job Name: " + job.Name);
          builder.AppendLine("Job State: " + job.State.ToString());
          builder.AppendLine("Job started (server UTC time): " + job.StartTime.ToString());
          builder.AppendLine("Media Services account name: " + _accountName);
          // Log job errors if they exist.  
          if (job.State == JobState.Error)
          {
              builder.Append("Error Details: \n");
              foreach (ITask task in job.Tasks)
              {
                  foreach (ErrorDetail detail in task.ErrorDetails)
                  {
                      builder.AppendLine("  Task Id: " + task.Id);
                      builder.AppendLine("    Error Code: " + detail.Code);
                      builder.AppendLine("    Error Message: " + detail.Message + "\n");
                  }
              }
          }
          builder.AppendLine("***************************\n");
          // Write the output to a local file and to the console. The template 
          // for an error output file is:  JobStop-{JobId}.txt
          string outputFile = _outputFilesFolder + @"\JobStop-" + JobIdAsFileName(job.Id) + ".txt";
          WriteToFile(outputFile, builder.ToString());
          Console.Write(builder.ToString());
      }
      
      private static void LogJobDetails(string jobId)
      {
          StringBuilder builder = new StringBuilder();
          IJob job = GetJob(jobId);
      
          builder.AppendLine("\nJob ID: " + job.Id);
          builder.AppendLine("Job Name: " + job.Name);
          builder.AppendLine("Job submitted (client UTC time): " + DateTime.UtcNow.ToString());
          builder.AppendLine("Media Services account name: " + _accountName);
      
          // Write the output to a local file and to the console. The template 
          // for an error output file is:  JobDetails-{JobId}.txt
          string outputFile = _outputFilesFolder + @"\JobDetails-" + JobIdAsFileName(job.Id) + ".txt";
          WriteToFile(outputFile, builder.ToString());
          Console.Write(builder.ToString());
      }
              
      private static string JobIdAsFileName(string jobID)
      {
          return jobID.Replace(":", "_");
      }
      
    • WriteToFile 方法會將檔案寫入指定的輸出資料夾。

      static void WriteToFile(string outFilePath, string fileContent)
      {
          StreamWriter sr = File.CreateText(outFilePath);
          sr.Write(fileContent);
          sr.Close();
      }
      
    • 您在 Media Services 中將資產編碼之後,就可以存取編碼工作 (Job) 所產生的輸出資產。本逐步解說介紹存取編碼工作 (Job) 輸出的兩種方式:

      • 建立伺服器上之資產的 SAS URL。

      • 從伺服器下載輸出資產。

      GetAssetSasUrlList 方法會建立資產中所有檔案之 SAS URL 的清單。

      static List<String> GetAssetSasUrlList(IAsset asset, ILocator locator)
      {
          // Declare a list to contain all the SAS URLs.
          List<String> fileSasUrlList = new List<String>();
      
          // If the asset has files, build a list of URLs to 
          // each file in the asset and return. 
          foreach (IAssetFile file in asset.AssetFiles)
          {
              string sasUrl = BuildFileSasUrl(file, locator);
              fileSasUrlList.Add(sasUrl);
          }
      
          // Return the list of SAS URLs.
          return fileSasUrlList;
      }
      
      // Create and return a SAS URL to a single file in an asset. 
      static string BuildFileSasUrl(IAssetFile file, ILocator locator)
      {
          // Take the locator path, add the file name, and build 
          // a full SAS URL to access this file. This is the only 
          // code required to build the full URL.
          var uriBuilder = new UriBuilder(locator.Path);
          uriBuilder.Path += "/" + file.Name;
      
          // Optional:  print the locator.Path to the asset, and 
          // the full SAS URL to the file
          Console.WriteLine("Locator path: ");
          Console.WriteLine(locator.Path);
          Console.WriteLine();
          Console.WriteLine("Full URL to file: ");
          Console.WriteLine(uriBuilder.Uri.AbsoluteUri);
          Console.WriteLine();
      
      
          //Return the SAS URL.
          return uriBuilder.Uri.AbsoluteUri;
      }
      
    • DownloadAssetToLocal 方法會將資產中的每檔案下載到本機資料夾。在此範例中,由於資產是使用輸入媒體檔案建立,因此輸出資產檔案集合包含兩個檔案:編碼媒體檔案 (.mp4 檔案) 與含有資產之中繼資料的 .xml 檔案。方法會下載這兩個檔案。

      static IAsset DownloadAssetToLocal(string jobId, string outputFolder)
      {
          // This method illustrates how to download a single asset. 
          // However, you can iterate through the OutputAssets
          // collection, and download all assets if there are many. 
      
          // Get a reference to the job. 
          IJob job = GetJob(jobId);
          // Get a reference to the first output asset. If there were multiple 
          // output media assets you could iterate and handle each one.
          IAsset outputAsset = job.OutputMediaAssets[0];
      
          IAccessPolicy accessPolicy = _context.AccessPolicies.Create("File Download Policy", TimeSpan.FromDays(30), AccessPermissions.Read);
          ILocator locator = _context.Locators.CreateSasLocator(outputAsset, accessPolicy);
          BlobTransferClient blobTransfer = new BlobTransferClient
          {
              NumberOfConcurrentTransfers = 10,
              ParallelTransferThreadCount = 10
          };
      
          var downloadTasks = new List<Task>();
          foreach (IAssetFile outputFile in outputAsset.AssetFiles)
          {
              // Use the following event handler to check download progress.
              outputFile.DownloadProgressChanged += DownloadProgress;
      
              string localDownloadPath = Path.Combine(outputFolder, outputFile.Name);
      
              Console.WriteLine("File download path:  " + localDownloadPath);
      
              downloadTasks.Add(outputFile.DownloadAsync(Path.GetFullPath(localDownloadPath), blobTransfer, locator, CancellationToken.None));
      
              outputFile.DownloadProgressChanged -= DownloadProgress;
          }
      
          Task.WaitAll(downloadTasks.ToArray());
      
          return outputAsset;
      }
      
      static void DownloadProgress(object sender, DownloadProgressChangedEventArgs e)
      {
          Console.WriteLine(string.Format("{0} % download progress. ", e.Progress));
      }
      
    • GetJobGetAsset 協助程式方法會查詢並傳回工作 (Job) 物件和具有指定識別碼之資產物件的參考。您可以使用同一類 LINQ 查詢來傳回伺服器上其他 Media Services 物件的參考。

      static IJob GetJob(string jobId)
      {
          // Use a Linq select query to get an updated 
          // reference by Id. 
          var jobInstance =
              from j in _context.Jobs
              where j.Id == jobId
              select j;
          // Return the job reference as an Ijob. 
          IJob job = jobInstance.FirstOrDefault();
      
          return job;
      }
      static IAsset GetAsset(string assetId)
      {
          // Use a LINQ Select query to get an asset.
          var assetInstance =
              from a in _context.Assets
              where a.Id == assetId
              select a;
          // Reference the asset as an IAsset.
          IAsset asset = assetInstance.FirstOrDefault();
      
          return asset;
      }
      
      

執行程式 (按 F5)。主控台會顯示類似下面的輸出:

Asset name: UploadSingleFile_11/14/2012 10:09:11 PM
Time created: 11/14/2012 12:00:00 AM
Created assetFile interview2.wmv
Upload interview2.wmv
Done uploading of interview2.wmv using Upload()

Job ID: nb:jid:UUID:ea8d5a66-86b8-9b4d-84bc-6d406259acb8
Job Name: My encoding job
Job submitted (client UTC time): 11/14/2012 10:09:39 PM
Media Services account name: Add-Media-Services-Account-Name
Media Services account location: Add-Media-Services-account-location-name

Job(My encoding job) state: Queued.
Please wait...

Job(My encoding job) state: Processing.
Please wait...

********************
Job(My encoding job) is finished.
Please wait while local tasks or downloads complete...
********************

Locator path:
https://mediasvcd08mtz29tcpws.blob.core.windows-int.net/asset-4f5b42f4-3ade-4c2c
-9d48-44900d4f6b62?st=2012-11-14T22%3A07%3A01Z&se=2012-11-14T23%3A07%3A01Z&sr=c&
si=d07ec40c-02d7-4642-8e54-443b79f3ba3c&sig=XKMo0qJI5w8Fod3NsV%2FBxERnav8Jb6hL7f
xylq3oESc%3D

Full URL to file:
https://mediasvcd08mtz29tcpws.blob.core.windows-int.net/asset-4f5b42f4-3ade-4c2c
-9d48-44900d4f6b62/interview2.mp4?st=2012-11-14T22%3A07%3A01Z&se=2012-11-14T23%3
A07%3A01Z&sr=c&si=d07ec40c-02d7-4642-8e54-443b79f3ba3c&sig=XKMo0qJI5w8Fod3NsV%2F
BxERnav8Jb6hL7fxylq3oESc%3D

Locator path:
https://mediasvcd08mtz29tcpws.blob.core.windows-int.net/asset-4f5b42f4-3ade-4c2c
-9d48-44900d4f6b62?st=2012-11-14T22%3A07%3A01Z&se=2012-11-14T23%3A07%3A01Z&sr=c&
si=d07ec40c-02d7-4642-8e54-443b79f3ba3c&sig=XKMo0qJI5w8Fod3NsV%2FBxERnav8Jb6hL7f
xylq3oESc%3D

Full URL to file:
https://mediasvcd08mtz29tcpws.blob.core.windows-int.net/asset-4f5b42f4-3ade-4c2c
-9d48-44900d4f6b62/interview2_metadata.xml?st=2012-11-14T22%3A07%3A01Z&se=2012-1
1-14T23%3A07%3A01Z&sr=c&si=d07ec40c-02d7-4642-8e54-443b79f3ba3c&sig=XKMo0qJI5w8F
od3NsV%2FBxERnav8Jb6hL7fxylq3oESc%3D

Downloads are in progress, please wait.

File download path:  C:\supportFiles\outputfiles\interview2.mp4
1.70952185308162 % download progress.
3.68508804454907 % download progress.
6.48870388360293 % download progress.
6.83808741232649 % download progress.
. . . 
99.0763740574049 % download progress.
99.1522674787341 % download progress.
100 % download progress.
File download path:  C:\supportFiles\outputfiles\interview2_metadata.xml
100 % download progress.

執行此應用程式後會有下列結果:

  1. 上傳 .wmv 檔案到 Media Services。

  2. 然後使用 Windows Azure Media EncoderH264 Broadband 720p 預設值將檔案編碼。

  3. \supportFiles\outputFiles 資料夾中建立 FileSasUrlList.txt 檔案。檔案包含編碼資產的 URL。

    若要播放媒體檔案,請從文字檔案複製資產的 URL,再貼到瀏覽器中。範例專案包含的媒體檔案類似於下圖:

    視訊播放
  4. .mp4 媒體檔案與 _metadata.xml 檔案會下載到 outputFiles 資料夾中。

note附註
在 Media Services 物件模型中,資產是代表一對多檔案的 Media Services 內容集合物件。定位器路徑提供 Azure Blob URL,這是此資產在 Azure Storage 中的基底路徑。若要存取資產中特定的檔案,請在基底定位器路徑中加入檔案名稱。

本逐步解說示範了建立範例 Media Services 應用程式的許多程式設計工作 (Task)。您已學到基礎的 Media Services 程式設計工作 (Task),包括取得伺服器內容、建立資產、將資產編碼,以及下載或存取伺服器上的資產。關於後續的步驟與更進階的開發工作 (Task),請參閱下列兩個系列。這兩個系列會介紹如何以 Media Services SDK for .NET 或 REST API (針對 .NET 或非 .NET 開發人員) 為基礎來建立應用程式:


建置日期:

2014-04-18
本文對您有任何幫助嗎?
(剩餘 1500 個字元)
感謝您提供意見

社群新增項目

新增
顯示:
© 2014 Microsoft. 著作權所有,並保留一切權利。