销售电话: 1-800-867-1380

使用 Media Services SDK for .NET 批量引入资产

更新时间: 2015年2月

上载大型资产文件可能在资产创建过程中形成瓶颈。批量引入资产(简称“批量引入”)涉及到将资产创建过程与上载过程分离。若要使用批量引入方法,请创建一个描述资产及其关联文件的清单 (IngestManifest)。然后,你可以使用所选上载方法将关联的文件上载到该清单的 Blob 容器。Microsoft Azure Media Services 将会监视与清单关联的 Blob 容器。文件上载到 Blob 容器后,Microsoft Azure Media Services 将基于清单 (IngestManifestAsset) 中资产的配置完成资产创建过程。

本主题介绍使用 Microsoft Azure Media Services SDK for .NET 批量引入资产。有关使用 REST API 批量引入资产的信息,请参阅使用 REST API 批量引入资产

note备注
构建流内容的 URL 时,Media Services 会使用 IAssetFile.Name 属性的值(如 http://{WAMSAccount}.origin.mediaservices.windows.net/{GUID}/{IAssetFile.Name}/streamingParameters)。出于这个原因,不允许使用百分号编码。Name 属性的值不能含有任何以下保留的百分号编码字符:!*'();:@&=+$,/?%#[]"。此外,文件扩展名中只能含有一个“.”。

Important重要提示
本主题中的每个代码示例均使用下载的项目(该项目的解决方案文件为 MediaServicesSDKSamples.sln)中的一个或多个方法进行了说明。若要查找特定示例的代码,请在下载的项目中搜索示例方法名。若要运行特定代码示例,请使用所需的参数调用关联的方法。

批量引入的基本工作流分为以下部分:

note备注
使用 Microsoft Azure Media Services SDK 开发应用程序要求你必须先获取对 Media Services 服务器上下文的引用,如主题Connect to Media Services Using the Media Services SDK中所述。在以下代码示例中,上下文对象由名为 context 的变量表示。

IngestManifest 表示一组要通过批量引入创建的资产及其关联的资产文件。若要创建新的 IngestManifest,请调用通过服务器上下文中的 IngestManifests 集合公开的 Create 方法。此方法将使用你提供的清单名称创建一个新的 IngestManifest

本主题末尾的示例代码部分中提供了完整的示例代码。

IIngestManifest manifest = context.IngestManifests.Create(name);

创建将与批量 IngestManifest 关联的资产。这些资产是使用服务器上下文中的 Assets 集合创建的。在要批量引入的资产上配置所需的加密选项。

本主题末尾的示例代码部分中提供了完整的示例代码。

// Create the assets that will be associated with this bulk ingest manifest
IAsset destAsset1 = _context.Assets.Create(name + "_asset_1", AssetCreationOptions.None);
IAsset destAsset2 = _context.Assets.Create(name + "_asset_2", AssetCreationOptions.None);

一个 IngestManifestAsset 将一个Asset与一个用于批量引入的批量 IngestManifest 相关联。它还关联构成每个AssetAssetFiles。若要创建 IngestManifestAsset,请使用服务器上下文中的 Create 方法。

以下示例演示如何添加两个新的 IngestManifestAssets,这两项将以前创建的两个资产关联到批量引入清单。每个 IngestManifestAsset 还关联一组将在批量引入期间为每个资产上载的文件。文件路径是 MediaServiceSDKSamples 项目的一部分。

本主题末尾的示例代码部分中提供了完整的示例代码。


string filename1 = _singleInputMp4Path;
string filename2 = _primaryFilePath;
string filename3 = _singleInputFilePath;

IIngestManifestAsset bulkAsset1 =  manifest.IngestManifestAssets.Create(destAsset1, new[] { filename1 });
IIngestManifestAsset bulkAsset2 =  manifest.IngestManifestAssets.Create(destAsset2, new[] { filename2, filename3 });

可以使用任何能够将资产文件上载到 Blob 存储容器 URI(由 IngestManifestBlobStorageUriForUpload 属性提供)的高速客户端应用程序。一个明显的高速上载服务就是适用于 Azure 应用程序的点播 Aspera。你还可以编写代码来上载资产文件,如以下代码示例所示。

static void UploadBlobFile(string destBlobURI, string filename)
{
    Task copytask = new Task(() =>
    {
        var storageaccount = new CloudStorageAccount(new StorageCredentials(_storageAccountName, _storageAccountKey), true);
        CloudBlobClient blobClient = storageaccount.CreateCloudBlobClient();
        CloudBlobContainer blobContainer = blobClient.GetContainerReference(destBlobURI);

        string[] splitfilename = filename.Split('\\');
        var blob = blobContainer.GetBlockBlobReference(splitfilename[splitfilename.Length - 1]);

        using (var stream = System.IO.File.OpenRead(filename))
            blob.UploadFromStream(stream);

        lock (consoleWriteLock)
        {
            Console.WriteLine("Upload for {0} completed.", filename);
        }
    });

    copytask.Start();
}

以下代码示例中显示了用于上载本主题中使用的示例资源文件的代码。


UploadBlobFile(manifest.BlobStorageUriForUpload, filename1);
UploadBlobFile(manifest.BlobStorageUriForUpload, filename2);
UploadBlobFile(manifest.BlobStorageUriForUpload, filename3);

可以通过轮询 IngestManifestStatistics 属性来确定与 IngestManifest 关联的所有资产的批量引入进度。若要更新进度信息,每次轮询 Statistics 属性时,都必须使用新的服务器上下文。

以下示例演示如何按照 Id 轮询 IngestManifest

本主题末尾的示例代码部分中提供了完整的示例代码。

static void MonitorBulkManifest(string manifestID)
{
   bool bContinue = true;
   while (bContinue)
   {
      CloudMediaContext context = GetContext();
      IIngestManifest manifest = context.IngestManifests.Where(m => m.Id == manifestID).FirstOrDefault();

      if (manifest != null)
      {
         lock(consoleWriteLock)
         {
            Console.WriteLine("\nWaiting on all file uploads.");
            Console.WriteLine("PendingFilesCount  : {0}", manifest.Statistics.PendingFilesCount);
            Console.WriteLine("FinishedFilesCount : {0}", manifest.Statistics.FinishedFilesCount);
            Console.WriteLine("{0}% complete.\n", (float)manifest.Statistics.FinishedFilesCount / (float)(manifest.Statistics.FinishedFilesCount + manifest.Statistics.PendingFilesCount) * 100);

            if (manifest.Statistics.PendingFilesCount == 0)
            {
               Console.WriteLine("Completed\n");
               bContinue = false;
            }
         }

         if (manifest.Statistics.FinishedFilesCount < manifest.Statistics.PendingFilesCount)
            Thread.Sleep(60000);
      }
      else //=== Manifest is null ===//
         bContinue = false;
   }
}

以下示例代码源自 MediaServicesSDKSample 项目。

using System;
using System.Configuration;
using System.Globalization;
using System.IO;
using System.Net;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Xml;
using System.Linq;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.MediaServices.Client;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using Microsoft.WindowsAzure.Storage.Auth;
using System.Collections.Generic;
using System.Reflection;

namespace Microsoft.Samples.WindowsAzureMediaServicesSDK.BulkIngest
{
    class Program
    {
        private static CloudMediaContext _context = null;
        private static readonly string _supportFiles = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\..\..\supportFiles";
        private static readonly string _singleInputFilePath =
            Path.GetFullPath(_supportFiles + @"\multifile\interview2.wmv");
        private static readonly string _singleInputMp4Path =
            Path.GetFullPath(_supportFiles + @"\multifile\BigBuckBunny.mp4");
        private static readonly string _primaryFilePath =
            Path.GetFullPath(_supportFiles + @"\multifile\interview1.wmv");

        private static System.Object consoleWriteLock = new Object();

        private static readonly string _accountName =
            ConfigurationManager.AppSettings["MediaServicesAccountName"];
        private static readonly string _accountKey =
            ConfigurationManager.AppSettings["MediaServicesAccountKey"];

        // Media Services storage account credentials.
        private static readonly string _storageAccountName =
            ConfigurationManager.AppSettings["MediaServicesStorageAccountName"];
        private static readonly string _storageAccountKey =
            ConfigurationManager.AppSettings["MediaServicesStorageAccountKey"];

        static void Main(string[] args)
        {
            _context = GetContext();
            string manifestName = "TestManifest";

            CreateBulkIngestManifest(manifestName);
            ListIngestManifests();
            DeleteBulkManifest(manifestName);
        }


        static CloudMediaContext GetContext()
        {
            return new CloudMediaContext(_accountName, _accountKey);
        }

        static IIngestManifest CreateBulkIngestManifest(string name)
        {
            Console.WriteLine("\n===============================================");
            Console.WriteLine("========[ CREATE BULK INGEST MANIFEST ]========");
            Console.WriteLine("===============================================\n");


            IIngestManifest manifest = _context.IngestManifests.Create(name);

            IAsset destAsset1 = _context.Assets.Create(name + "_asset_1", AssetCreationOptions.None);
            IAsset destAsset2 = _context.Assets.Create(name + "_asset_2", AssetCreationOptions.None);

            string filename1 = _singleInputMp4Path;
            string filename2 = _primaryFilePath;
            string filename3 = _singleInputFilePath;

            //=== Preently, each asset filename uploaded must be unique for an individual Bulk ingest manifest. So two assets can not have ===//
            //=== the same asset filename or an exception will be thrown for duplicate filename.                                           ===//
            IIngestManifestAsset bulkAsset1 = manifest.IngestManifestAssets.Create(destAsset1, new[] { filename1 });
            IIngestManifestAsset bulkAsset2 = manifest.IngestManifestAssets.Create(destAsset2, new[] { filename2, filename3 });

            ListIngestManifests(manifest.Id);

            Console.WriteLine("\n===============================================");
            Console.WriteLine("===[ BULK INGEST MANIFEST MONITOR FILE COPY]===");
            Console.WriteLine("===============================================\n");

            UploadBlobFile(manifest.BlobStorageUriForUpload, filename1);
            UploadBlobFile(manifest.BlobStorageUriForUpload, filename2);
            UploadBlobFile(manifest.BlobStorageUriForUpload, filename3);

            MonitorBulkManifest(manifest.Id);
            ListIngestManifests(manifest.Id);

            return manifest;
        }


        // Upload a file into Blob Storage
        static void UploadBlobFile(string destBlobURI, string filename)
        {
            Task copytask = new Task(() =>
            {
                var storageaccount = new CloudStorageAccount(new StorageCredentials(_storageAccountName, _storageAccountKey), true);
                CloudBlobClient blobClient = storageaccount.CreateCloudBlobClient();
                CloudBlobContainer blobContainer = blobClient.GetContainerReference(destBlobURI);

                string[] splitfilename = filename.Split('\\');
                var blob = blobContainer.GetBlockBlobReference(splitfilename[splitfilename.Length - 1]);

                using (var stream = System.IO.File.OpenRead(filename))
                    blob.UploadFromStream(stream);

                lock (consoleWriteLock)
                {
                    Console.WriteLine("Upload for {0} completed.", filename);
                }
            });

            copytask.Start();
        }

        static void DeleteBulkManifest(string name)
        {
            Console.WriteLine("\n===============================================");
            Console.WriteLine("=======[ DELETE BULK INGEST MANIFESTS ]========");
            Console.WriteLine("===============================================\n");

            var manifest = _context.IngestManifests.Where(c => c.Name == name).FirstOrDefault();
            DeleteBulkManifestAssets(manifest.Id);

            Console.WriteLine("Deleting Manifest...\n\tName : {0}\n\tManifest ID : {1}...", manifest.Name, manifest.Id);
            manifest.Delete();
            Console.WriteLine("Delete Complete.\n");
        }

        static void DeleteBulkManifestAssets(string manifestID)
        {
            Console.WriteLine("\n===============================================");
            Console.WriteLine("=====[ DELETE BULK INGEST MANIFEST ASSETS ]====");
            Console.WriteLine("===============================================\n");

            foreach (IIngestManifest manifest in _context.IngestManifests.Where(c => c.Id == manifestID))
            {
                Console.WriteLine("Deleting assets for manifest named : {0}...\n", manifest.Name);
                foreach (IIngestManifestAsset manifestAsset in manifest.IngestManifestAssets)
                {
                    foreach (ILocator locator in manifestAsset.Asset.Locators)
                    {
                        Console.WriteLine("Deleting locator {0} for asset {1}", locator.Path, manifestAsset.Asset.Id);
                        locator.Delete();
                    }
                    Console.WriteLine("Deleting asset {0}\n", manifestAsset.Asset.Id);
                    manifestAsset.Asset.Delete();
                }
            }
        }

        static void MonitorBulkManifest(string manifestID)
        {
            bool bContinue = true;
            while (bContinue)
            {
                //=== We need a new context here because IIngestManifestStatistics is considered an expensive ===//
                //=== property and not updated realtime for a context.                                        ===//
                CloudMediaContext context = GetContext();

                IIngestManifest manifest = context.IngestManifests.Where(m => m.Id == manifestID).FirstOrDefault();

                if (manifest != null)
                {
                    lock (consoleWriteLock)
                    {
                        Console.WriteLine("\nWaiting on all file uploads.");
                        Console.WriteLine("PendingFilesCount  : {0}", manifest.Statistics.PendingFilesCount);
                        Console.WriteLine("FinishedFilesCount : {0}", manifest.Statistics.FinishedFilesCount);
                        Console.WriteLine("{0}% complete.\n", (float)manifest.Statistics.FinishedFilesCount / (float)(manifest.Statistics.FinishedFilesCount + manifest.Statistics.PendingFilesCount) * 100);


                        if (manifest.Statistics.PendingFilesCount == 0)
                        {
                            Console.WriteLine("Completed\n");
                            bContinue = false;
                        }
                    }

                    if (manifest.Statistics.FinishedFilesCount < manifest.Statistics.PendingFilesCount)
                    {
                        Thread.Sleep(60000);
                    }
                }
                else //=== Manifest is null ===//
                    bContinue = false;
            }
        }

        static IQueryable<IIngestManifest> ListIngestManifests(string manifestId = "")
        {
            CloudMediaContext context = GetContext();

            Console.WriteLine("\n===============================================");
            Console.WriteLine("===========[ BULK INGEST MANIFESTS ]===========");
            Console.WriteLine("===============================================\n");

            IQueryable<IIngestManifest> manifests = null;

            //=== If an Id is supplied, list the manifest with that Id. Otherwise, list all manifests ===//
            if (manifestId == "")
                manifests = context.IngestManifests;
            else
                manifests = context.IngestManifests.Where(m => m.Id == manifestId);

            foreach (IIngestManifest manifest in manifests)
            {
                Console.WriteLine("Manifest Name  : {0}", manifest.Name);
                Console.WriteLine("Manifest State : {0}", manifest.State.ToString());
                Console.WriteLine("Manifest Id    : {0}", manifest.Id);
                Console.WriteLine("Manifest Last Modified      : {0}", manifest.LastModified.ToLocalTime().ToString());
                Console.WriteLine("Manifest PendingFilesCount  : {0}", manifest.Statistics.PendingFilesCount);
                Console.WriteLine("Manifest FinishedFilesCount : {0}", manifest.Statistics.FinishedFilesCount);
                Console.WriteLine("Manifest BLOB URI : {0}\n", manifest.BlobStorageUriForUpload);

                foreach (IIngestManifestAsset manifestasset in manifest.IngestManifestAssets)
                {
                    Console.WriteLine("\tAsset Name    : {0}", manifestasset.Asset.Name);
                    Console.WriteLine("\tAsset ID      : {0}", manifestasset.Asset.Id);
                    Console.WriteLine("\tAsset Options : {0}", manifestasset.Asset.Options.ToString());
                    Console.WriteLine("\tAsset State   : {0}", manifestasset.Asset.State.ToString());
                    Console.WriteLine("\tAsset Files....");

                    foreach (IIngestManifestFile assetfile in manifestasset.IngestManifestFiles)
                    {
                        Console.WriteLine("\t\t{0}\n\t\tFile State : {1}\n", assetfile.Name, assetfile.State.ToString());
                    }
                    Console.WriteLine("");
                }
            }

            return manifests;
        }
    }
}

App.Config 文件示例

Important重要提示
在运行此示例之前,需要为 MediaServicesAccountName、MediaServicesAccountKey、MediaServicesStorageAccountName 和 MediaServicesStorageAccountKey 添加值。可以通过转到 Azure 门户,选择 Azure Media Service 帐户,然后单击“管理密钥”图标来找到这些值。为 Azure 存储帐户执行相同的操作。

<?xml version="1.0"?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
  </startup>
  <appSettings>
    <add key="MediaServicesAccountName" value="Enter Your Azure Media Services Account Name " />
    <add key="MediaServicesAccountKey" value="Enter Your Azure Media Services Account Key " />
    <add key="MediaServicesStorageAccountName" value=" Enter the Storage Account Name used with Azure Media Services " />
    <add key="MediaServicesStorageAccountKey" value=" Enter the Storage Account Key used with Azure Media Services " />
  </appSettings>
</configuration>

示例代码的示例输出。


===============================================
========[ CREATE BULK INGEST MANIFEST ]========
===============================================


===============================================
===========[ BULK INGEST MANIFESTS ]===========
===============================================

Manifest Name  : TestManifest
Manifest State : Activating
Manifest Id    : nb:mid:UUID:47e2efdf-8ec8-6143-a4ac-bf43efba35c8
Manifest Last Modified      : 2/25/2013 1:50:09 PM
Manifest PendingFilesCount  : 3
Manifest FinishedFilesCount : 0
Manifest BLOB URI : https://mediasvcm13w6rsvm521t.blob.core.windows.net/manifest
-402dcea0-411c-48f2-90fc-805c63a92a72

        Asset Name    : TestManifest_asset_2
        Asset ID      : nb:cid:UUID:0dbfcaf9-e53c-4399-99c2-ba207b1821d9
        Asset Options : None
        Asset State   : Initialized
        Asset Files....
                interview2.wmv
                File State : Pending

                interview1.wmv
                File State : Pending


        Asset Name    : TestManifest_asset_1
        Asset ID      : nb:cid:UUID:7a7188b5-d39d-42de-b3c7-f418174b14f3
        Asset Options : None
        Asset State   : Initialized
        Asset Files....
                BigBuckBunny.mp4
                File State : Pending



===============================================
===[ BULK INGEST MANIFEST MONITOR FILE COPY]===
===============================================


Waiting on all file uploads.
PendingFilesCount  : 3
FinishedFilesCount : 0
0% complete.

Upload for c:\Projects\Media Services\BulkIngestTest\supportFiles\multifile\inte
rview2.wmv completed.
Upload for c:\Projects\Media Services\BulkIngestTest\supportFiles\multifile\BigB
uckBunny.mp4 completed.
Upload for c:\Projects\Media Services\BulkIngestTest\supportFiles\multifile\inte
rview1.wmv completed.

Waiting on all file uploads.
PendingFilesCount  : 0
FinishedFilesCount : 3
100% complete.

Completed


===============================================
===========[ BULK INGEST MANIFESTS ]===========
===============================================

Manifest Name  : TestManifest
Manifest State : Inactive
Manifest Id    : nb:mid:UUID:47e2efdf-8ec8-6143-a4ac-bf43efba35c8
Manifest Last Modified      : 2/25/2013 1:50:48 PM
Manifest PendingFilesCount  : 0
Manifest FinishedFilesCount : 3
Manifest BLOB URI : https://mediasvcm13w6rsvm521t.blob.core.windows.net/manifest
-402dcea0-411c-48f2-90fc-805c63a92a72

        Asset Name    : TestManifest_asset_2
        Asset ID      : nb:cid:UUID:0dbfcaf9-e53c-4399-99c2-ba207b1821d9
        Asset Options : None
        Asset State   : Initialized
        Asset Files....
                interview2.wmv
                File State : Finished

                interview1.wmv
                File State : Finished


        Asset Name    : TestManifest_asset_1
        Asset ID      : nb:cid:UUID:7a7188b5-d39d-42de-b3c7-f418174b14f3
        Asset Options : None
        Asset State   : Initialized
        Asset Files....
                BigBuckBunny.mp4
                File State : Finished



===============================================
===========[ BULK INGEST MANIFESTS ]===========
===============================================

Manifest Name  : TestManifest
Manifest State : Inactive
Manifest Id    : nb:mid:UUID:c44efbcc-8f6a-f94a-aa21-2d0c1166ecb7
Manifest Last Modified      : 2/25/2013 1:47:47 PM
Manifest PendingFilesCount  : 0
Manifest FinishedFilesCount : 0
Manifest BLOB URI : https://mediasvcm13w6rsvm521t.blob.core.windows.net/manifest
-f001a80c-3c37-4a31-8ffc-b4bfe98b56be

        Asset Name    : TestManifest_asset_1
        Asset ID      : nb:cid:UUID:350ceed6-086a-413d-9bb9-a8a2f07a60f5
        Asset Options : None
        Asset State   : Initialized
        Asset Files....

Manifest Name  : TestManifest
Manifest State : Inactive
Manifest Id    : nb:mid:UUID:47e2efdf-8ec8-6143-a4ac-bf43efba35c8
Manifest Last Modified      : 2/25/2013 1:50:48 PM
Manifest PendingFilesCount  : 0
Manifest FinishedFilesCount : 3
Manifest BLOB URI : https://mediasvcm13w6rsvm521t.blob.core.windows.net/manifest
-402dcea0-411c-48f2-90fc-805c63a92a72

        Asset Name    : TestManifest_asset_2
        Asset ID      : nb:cid:UUID:0dbfcaf9-e53c-4399-99c2-ba207b1821d9
        Asset Options : None
        Asset State   : Initialized
        Asset Files....
                interview2.wmv
                File State : Finished

                interview1.wmv
                File State : Finished


        Asset Name    : TestManifest_asset_1
        Asset ID      : nb:cid:UUID:7a7188b5-d39d-42de-b3c7-f418174b14f3
        Asset Options : None
        Asset State   : Initialized
        Asset Files....
                BigBuckBunny.mp4
                File State : Finished



===============================================
=======[ DELETE BULK INGEST MANIFESTS ]========
===============================================


===============================================
=====[ DELETE BULK INGEST MANIFEST ASSETS ]====
===============================================

Deleting assets for manifest named : TestManifest...

Deleting asset nb:cid:UUID:350ceed6-086a-413d-9bb9-a8a2f07a60f5

Deleting Manifest...
        Name : TestManifest
        Manifest ID : nb:mid:UUID:c44efbcc-8f6a-f94a-aa21-2d0c1166ecb7...
Delete Complete.


===============================================
=====[ DELETE BULK INGEST MANIFEST ASSETS ]====
===============================================

Deleting assets for manifest named : TestManifest...

Deleting asset nb:cid:UUID:0dbfcaf9-e53c-4399-99c2-ba207b1821d9

Deleting asset nb:cid:UUID:7a7188b5-d39d-42de-b3c7-f418174b14f3

Deleting Manifest...
        Name : TestManifest
        Manifest ID : nb:mid:UUID:47e2efdf-8ec8-6143-a4ac-bf43efba35c8...
Delete Complete.

你已做好准备,可以继续下一个主题: 静态封装.

另请参阅

本文是否对您有所帮助?
(1500 个剩余字符)
感谢您的反馈
显示:
© 2015 Microsoft