使用 .NET 将文件上传到媒体服务帐户Upload files into a Media Services account using .NET

备注

不会向媒体服务 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

在媒体服务中,可以将数字文件上传(引入)到资产中。In Media Services, you upload (or ingest) your digital files into an asset. 资产实体可以包含视频、音频、图像、缩略图集合、文本轨道和隐藏式字幕文件(以及这些文件的相关元数据。)上传文件完成后,相关内容即安全地存储在云中供后续处理和流式处理。The Asset entity can contain video, audio, images, thumbnail collections, text tracks and closed caption files (and the metadata about these files.) Once the files are uploaded, your content is stored securely in the cloud for further processing and streaming.

资产中的文件称为 资产文件The files in the asset are called Asset Files. AssetFile 实例和实际媒体文件是两个不同的对象。The AssetFile instance and the actual media file are two distinct objects. AssetFile 实例包含有关媒体文件的元数据,而媒体文件包含实际媒体内容。The AssetFile instance contains metadata about the media file, while the media file contains the actual media content.

注意事项Considerations

请注意以下事项:The following considerations apply:

  • 构建流内容的 URL 时,媒体服务会使用 IAssetFile.Name 属性的值(如 http://{AMSAccount}.origin.mediaservices.chinacloudapi.cn/{GUID}/{IAssetFile.Name}/streamingParameters。)出于这个原因,不允许使用百分号编码。Media Services uses the value of the IAssetFile.Name property when building URLs for the streaming content (for example, http://{AMSAccount}.origin.mediaservices.chinacloudapi.cn/{GUID}/{IAssetFile.Name}/streamingParameters.) For this reason, percent-encoding is not allowed. Name 属性的值不能含有任何以下百分号编码保留字符:!*'();:@&=+$,/?%#[]"。The value of the Name property cannot have any of the following percent-encoding-reserved characters: !*'();:@&=+$,/?%#[]". 此外,文件扩展名中只能含有一个“.”。Also, there can only be one '.' for the file name extension.
  • 名称长度不应超过 260 个字符。The length of the name should not be greater than 260 characters.
  • 在媒体服务中进行处理时,系统支持的最大文件大小存在限制。There is a limit to the maximum file size supported for processing in Media Services. 有关文件大小限制的详细信息,请参阅此文See this article for details about the file size limitation.
  • 不同 AMS 策略的策略限制为 1,000,000 个(例如,对于定位器策略或 ContentKeyAuthorizationPolicy)。There is a limit of 1,000,000 policies for different AMS policies (for example, for Locator policy or ContentKeyAuthorizationPolicy). 如果始终使用相同的日期/访问权限,则应使用相同的策略 ID,例如,用于要长期就地保留的定位符的策略(非上传策略)。You should use the same policy ID if you are always using the same days / access permissions, for example, policies for locators that are intended to remain in place for a long time (non-upload policies). 有关详细信息,请参阅本文For more information, see this article.

创建资产时,可以指定以下加密选项:When you create assets, you can specify the following encryption options:

  • - 不使用加密。None - No encryption is used. 这是默认值。This is the default value. 使用此选项时,内容在传送过程中或静态存储过程中都不会受到保护。When using this option your content is not protected in transit or at rest in storage. 如果计划使用渐进式下载传送 MP4,则使用此选项:If you plan to deliver an MP4 using progressive download, use this option:

  • CommonEncryption - 上传经过通用加密或 PlayReady DRM 加密并保护的内容(例如,受 PlayReady DRM 保护的平滑流式处理)时使用此选项。CommonEncryption - Use this option if you are uploading content that has already been encrypted and protected with Common Encryption or PlayReady DRM (for example, Smooth Streaming protected with PlayReady DRM).

  • EnvelopeEncrypted - 如果要上传使用 AES 加密的 HLS,请使用此选项。EnvelopeEncrypted – Use this option if you are uploading HLS encrypted with AES. 请注意,Transform Manager 必须已对文件进行编码和加密。Note that the files must have been encoded and encrypted by Transform Manager.

  • StorageEncrypted - 使用 AES-256 位加密在本地加密明文内容,并将其上传到 Azure Storage 中以加密形式静态存储相关内容。StorageEncrypted - Encrypts your clear content locally using AES-256 bit encryption and then uploads it to Azure Storage where it is stored encrypted at rest. 受存储加密保护的资产会在编码前自动解密并放入经过加密的文件系统中,并可选择在重新上传为新的输出资产前重新加密。Assets protected with Storage Encryption are automatically unencrypted and placed in an encrypted file system prior to encoding, and optionally re-encrypted prior to uploading back as a new output asset. 存储加密的主要用例是在磁盘上通过静态增强加密来保护高品质的输入媒体文件。The primary use case for Storage Encryption is when you want to secure your high-quality input media files with strong encryption at rest on disk.

    媒体服务为资产提供磁盘上的存储加密,而不是通过数字权限管理器 (DRM) 等线路提供加密。Media Services provides on-disk storage encryption for your assets, not over-the-wire like Digital Rights Manager (DRM).

    如果资产已经过存储加密,则必须配置资产传送策略。If your asset is storage encrypted, you must configure asset delivery policy. 有关详细信息,请参阅配置资产传送策略For more information, see Configuring asset delivery policy.

如果指定使用 CommonEncrypted 选项或 EnvelopeEncrypted 选项加密资产,则需要将资产关联到 ContentKeyIf you specify for your asset to be encrypted with a CommonEncrypted option, or an EnvelopeEncrypted option, you need to associate your asset with a ContentKey. 有关详细信息,请参阅如何创建 ContentKeyFor more information, see How to create a ContentKey.

如果指定使用 StorageEncrypted 选项加密资产,适用于 .NET 的媒体服务 SDK 将为资产创建 StorageEncrypted ContentKey 。If you specify for your asset to be encrypted with a StorageEncrypted option, the Media Services SDK for .NET creates a StorageEncrypted ContentKey for your asset.

本文说明如何使用媒体服务 .NET SDK 以及媒体服务 .NET SDK 扩展将文件上传到媒体服务资产中。This article shows how to use Media Services .NET SDK as well as Media Services .NET SDK extensions to upload files into a Media Services asset.

使用媒体服务 .NET SDK 上传单个文件Upload a single file with Media Services .NET SDK

以下代码使用 .NET 上传单个文件。The following code uses .NET to upload a single file. AccessPolicy 和 Locator 由 Upload 函数创建和销毁。The AccessPolicy and Locator are created and destroyed by the Upload function.

        static public IAsset CreateAssetAndUploadSingleFile(AssetCreationOptions assetCreationOptions, string singleFilePath)
        {
            if (!File.Exists(singleFilePath))
            {
                Console.WriteLine("File does not exist.");
                return null;
            }

            var assetName = Path.GetFileNameWithoutExtension(singleFilePath);
            IAsset inputAsset = _context.Assets.Create(assetName, assetCreationOptions);

            var assetFile = inputAsset.AssetFiles.Create(Path.GetFileName(singleFilePath));

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

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

            return inputAsset;
        }

使用媒体服务 .NET SDK 上传多个文件Upload multiple files with Media Services .NET SDK

以下代码演示如何创建资产及上传多个文件。The following code shows how to create an asset and upload multiple files.

代码执行以下操作:The code does the following:

  • 使用上一步中定义的 CreateEmptyAsset 方法创建一个空资产。Creates an empty asset using the CreateEmptyAsset method defined in the previous step.
  • 创建用于定义权限以及资产访问持续时间的 AccessPolicy 实例。Creates an AccessPolicy instance that defines the permissions and duration of access to the asset.
  • 创建用于提供资产访问权限的 Locator 实例。Creates a Locator instance that provides access to the asset.
  • 创建 BlobTransferClient 实例。Creates a BlobTransferClient instance. 此类型表示对 Azure Blob 进行操作的客户端。This type represents a client that operates on the Azure blobs. 在此示例中,客户端将监视上传进度。In this example, the client monitors the upload progress.
  • 枚举指定目录下的所有文件,并为每个文件创建一个 AssetFile 实例。Enumerates through files in the specified directory and creates an AssetFile instance for each file.
  • 使用 UploadAsync 方法将文件上传到媒体服务中。Uploads the files into Media Services using the UploadAsync method.

备注

使用 UploadAsync 方法可确保调用不会阻塞并且文件并行上传。Use the UploadAsync method to ensure that the calls are not blocking and the files are uploaded in parallel.

        static public IAsset CreateAssetAndUploadMultipleFiles(AssetCreationOptions assetCreationOptions, string folderPath)
        {
            var assetName = "UploadMultipleFiles_" + DateTime.UtcNow.ToString();

            IAsset asset = _context.Assets.Create(assetName, assetCreationOptions);

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

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

            var blobTransferClient = new BlobTransferClient();
            blobTransferClient.NumberOfConcurrentTransfers = 20;
            blobTransferClient.ParallelTransferThreadCount = 20;

            blobTransferClient.TransferProgressChanged += blobTransferClient_TransferProgressChanged;

            var filePaths = Directory.EnumerateFiles(folderPath);

            Console.WriteLine("There are {0} files in {1}", filePaths.Count(), folderPath);

            if (!filePaths.Any())
            {
                throw new FileNotFoundException(String.Format("No files in directory, check folderPath: {0}", folderPath));
            }

            var uploadTasks = new List<Task>();
            foreach (var filePath in filePaths)
            {
                var assetFile = asset.AssetFiles.Create(Path.GetFileName(filePath));
                Console.WriteLine("Created assetFile {0}", assetFile.Name);

                // It is recommended to validate AssetFiles before upload. 
                Console.WriteLine("Start uploading of {0}", assetFile.Name);
                uploadTasks.Add(assetFile.UploadAsync(filePath, blobTransferClient, locator, CancellationToken.None));
            }

            Task.WaitAll(uploadTasks.ToArray());
            Console.WriteLine("Done uploading the files");

            blobTransferClient.TransferProgressChanged -= blobTransferClient_TransferProgressChanged;

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

            return asset;
        }

    static void  blobTransferClient_TransferProgressChanged(object sender, BlobTransferProgressChangedEventArgs e)
    {
        if (e.ProgressPercentage > 4) // Avoid startup jitter, as the upload tasks are added.
        {
            Console.WriteLine("{0}% upload competed for {1}.", e.ProgressPercentage, e.LocalFile);
        }
    }

上传大量资产时,请注意以下事项:When uploading a large number of assets, consider the following:

  • 每个线程创建一个新的 CloudMediaContext 对象。Create a new CloudMediaContext object per thread. CloudMediaContext 类不是线程安全的。The CloudMediaContext class is not thread-safe.
  • 将 NumberOfConcurrentTransfers 从默认值 2 增加到更高的值(如 5)。Increase NumberOfConcurrentTransfers from the default value of 2 to a higher value like 5. 设置此属性会影响 CloudMediaContext的所有实例。Setting this property affects all instances of CloudMediaContext.
  • 将 ParallelTransferThreadCount 保留为默认值 10。Keep ParallelTransferThreadCount at the default value of 10.

使用媒体服务 .NET SDK 批量引入资产Ingesting Assets in Bulk using Media Services .NET SDK

上传大型资产文件可能在资产创建过程中形成瓶颈。Uploading large asset files can be a bottleneck during asset creation. 批量引入资产(简称“批量引入”)涉及将资产创建过程与上传过程分离。Ingesting Assets in Bulk or “Bulk Ingesting”, involves decoupling asset creation from the upload process. 若要使用批量引入方法,请创建一个描述资产及其关联文件的清单 (IngestManifest)。To use a bulk ingesting approach, create a manifest (IngestManifest) that describes the asset and its associated files. 然后,用户可以使用所选上传方法将关联的文件上传到该清单的 Blob 容器。Then use the upload method of your choice to upload the associated files to the manifest's blob container. Azure 媒体服务会监视与清单关联的 Blob 容器。Azure Media Services watches the blob container associated with the manifest. 文件上传到 Blob 容器后,Azure 媒体服务基于清单 (IngestManifestAsset) 中资产的配置完成资产创建过程。Once a file is uploaded to the blob container, Azure Media Services completes the asset creation based on the configuration of the asset in the manifest (IngestManifestAsset).

若要创建新的 IngestManifest,请调用通过 CloudMediaContext 中的 IngestManifests 集合公开的 Create 方法。To create a new IngestManifest, call the Create method exposed by the IngestManifests collection on the CloudMediaContext. 此方法将使用所提供的清单名称创建一个新的 IngestManifest。This method creates a new IngestManifest with the manifest name you provide.

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

创建与批量 IngestManifest 关联的资产。Create the assets that are associated with the bulk IngestManifest. 在要批量引入的资产上配置所需的加密选项。Configure the desired encryption options on the asset for bulk ingesting.

    // 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 将一个资产与一个用于批量引入的批量 IngestManifest 相关联。An IngestManifestAsset associates an Asset with a bulk IngestManifest for bulk ingesting. 它还关联构成每个资产的 AssetFiles。It also associates the AssetFiles that makes up each Asset. 若要创建 IngestManifestAsset,请使用服务器上下文中的 Create 方法。To create an IngestManifestAsset, use the Create method on the server context.

以下示例演示如何添加两个新的 IngestManifestAssets,这两项将以前创建的两个资产关联到批量引入清单。The following example demonstrates adding two new IngestManifestAssets that associate the two assets previously created to the bulk ingest manifest. 每个 IngestManifestAsset 还关联在批量引入期间为每个资产上传的一组文件。Each IngestManifestAsset also associates a set of files that are uploaded for each asset during bulk ingesting.

    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(由 IngestManifest 的 IIngestManifest.BlobStorageUriForUpload 属性提供)的高速客户端应用程序。You can use any high-speed client application capable of uploading the asset files to the blob storage container URI provided by the IIngestManifest.BlobStorageUriForUpload property of the IngestManifest.

以下代码显示如何使用 .NET SDK 上传资产文件。The following code shows how to use .NET SDK to upload the assets files.

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

            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();
    }

以下代码示例展示了用于上传本文中使用的示例资产文件的代码:The code for uploading the asset files for the sample used in this article is shown in the following code example:

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

可以通过轮询 IngestManifest 的 Statistics 属性来确定与 IngestManifest 关联的所有资产的批量引入进度。You can determine the progress of the bulk ingesting for all assets associated with an IngestManifest by polling the Statistics property of the IngestManifest. 若要更新进度信息,每次轮询 Statistics 属性时,都必须使用新的 CloudMediaContextIn order to update progress information, you must use a new CloudMediaContext each time you poll the Statistics property.

以下示例演示如何按 ID轮询 IngestManifest。The following example demonstrates polling an IngestManifest by its Id.

    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;
       }
    }

使用 .NET SDK 扩展上传文件Upload files using .NET SDK Extensions

以下示例演示如何使用 .NET SDK 扩展上传单个文件。The following example shows how to upload a single file using .NET SDK Extensions. 在此情况下,使用 CreateFromFile 方法,但也可以使用异步版本 (CreateFromFileAsync)。In this case the CreateFromFile method is used, but the asynchronous version is also available (CreateFromFileAsync). 通过 CreateFromFile 方法可以指定文件名、加密选项和回叫,以报告文件的上传进度。The CreateFromFile method lets you specify the file name, encryption option, and a callback in order to report the upload progress of the file.

    static public IAsset UploadFile(string fileName, AssetCreationOptions options)
    {
        IAsset inputAsset = _context.Assets.CreateFromFile(
            fileName,
            options,
            (af, p) =>
            {
                Console.WriteLine("Uploading '{0}' - Progress: {1:0.##}%", af.Name, p.Progress);
            });

        Console.WriteLine("Asset {0} created.", inputAsset.Id);

        return inputAsset;
    }

以下示例调用 UploadFile 函数,并指定存储加密作为资产创建选项。The following example calls UploadFile function and specifies storage encryption as the asset creation option.

    var asset = UploadFile(@"C:\VideoFiles\BigBuckBunny.mp4", AssetCreationOptions.StorageEncrypted);

后续步骤Next steps

现即可编码已上传的资产。You can now encode your uploaded assets. 有关详细信息,请参阅对资产进行编码For more information, see Encode assets.

也可使用 Azure Functions 根据到达已配置容器的文件触发编码作业。You can also use Azure Functions to trigger an encoding job based on a file arriving in the configured container. 有关详细信息,请参阅此示例For more information, see this sample.

媒体服务学习路径Media Services learning paths

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

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

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

后续步骤Next step

将资产上传到媒体服务后,请转到如何获取媒体处理器一文。Now that you have uploaded an asset to Media Services, go to the How to Get a Media Processor article.