使用 .NET 通过 Media Encoder Standard 对资产进行编码

编码作业是媒体服务中最常见的处理操作之一。 可通过创建编码作业将媒体文件从一种编码转换为另一种编码。 进行编码时,可以使用媒体服务内置的 Media Encoder。 另外,也可以使用媒体服务合作伙伴提供的编码器;第三方编码器可通过 Azure Marketplace 购得。

本文介绍如何使用 .NET 通过 Media Encoder Standard (MES) 对资产进行编码。 Media Encoder Standard 使用此处所述的编码器预设之一进行配置。

建议始终将源文件编码为自适应比特率 MP4 集,然后使用动态打包将该集转换为所需的格式。

如果输出资产已经过存储加密,则必须配置资产传送策略。 有关详细信息,请参阅配置资产传送策略

Note

MES 会生成一个输出文件,其名称包含输入文件名的前 32 个字符。 该名称基于预设文件中指定的内容。 例如,"FileName": "{Basename}_{Index}{Extension}"。 {Basename} 替换为输入文件名的前 32 个字符。

MES 格式

格式和编解码器

MES 预设

Media Encoder Standard 使用此处所述的其中一个编码器预设进行配置。

输入和输出元数据

如果使用 MES 为输入资产(或资产)编码,在该编码任务成功完成时,便能获取输出资产。 输出资产包含视频、音频、缩略图、清单等等,具体视你使用的编码预设而定。

输出资产还包含提供输入资产相关元数据的文件。 元数据 XML 文件的名称采用下列格式:<asset_id>_metadata.xml(例如,41114ad3-eb5e-4c57-8d92-5354e2b7d4a4_metadata.xml),其中 <asset_id> 是输入资产的 AssetId 值。 此处描述了此输入元数据 XML 的架构。

输出资产还包含提供输出资产相关元数据的文件。 元数据 XML 文件的名称采用下列格式:<source_file_name>_manifest.xml(例如,BigBuckBunny_manifest.xml)。 此处描述了此输出元数据 XML 的架构。

如果想要检查这两个元数据文件中的任意一个,可以创建 SAS 定位器并将文件下载到本地计算机。 可以就如何创建 SAS 定位器并下载使用媒体服务 .NET SDK 扩展的文件找到相关示例。

下载示例

可从此处获取并运行说明如何使用 MES 进行编码的示例。

.NET 示例代码

以下代码示例使用媒体服务 .NET SDK 执行下列任务:

  • 创建编码作业。
  • 获取对 Media Encoder Standard 编码器的引用。
  • 指定使用自适应流式处理预设。
  • 将一个编码任务添加到该作业。
  • 指定要编码的输入资产。
  • 创建包含所编码资产的输出资产。
  • 添加事件处理程序以检查作业进度。
  • 提交作业。

创建和配置 Visual Studio 项目

设置开发环境,并在 app.config 文件中填充连接信息,如使用 .NET 进行媒体服务开发中所述。

示例

using System;
using System.Linq;
using System.Configuration;
using System.IO;
using System.Threading;
using Microsoft.WindowsAzure.MediaServices.Client;

namespace MediaEncoderStandardSample
{
    class Program
    {
        private static readonly string _AADTenantDomain =
            ConfigurationManager.AppSettings["AMSAADTenantDomain"];
        private static readonly string _RESTAPIEndpoint =
            ConfigurationManager.AppSettings["AMSRESTAPIEndpoint"];
        private static readonly string _AMSClientId =
            ConfigurationManager.AppSettings["AMSClientId"];
        private static readonly string _AMSClientSecret =
            ConfigurationManager.AppSettings["AMSClientSecret"];

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

        private static readonly string _supportFiles =
            Path.GetFullPath(@"../..\Media");

        static void Main(string[] args)
        {
            AzureAdTokenCredentials tokenCredentials =
                new AzureAdTokenCredentials(_AADTenantDomain,
                    new AzureAdClientSymmetricKey(_AMSClientId, _AMSClientSecret),
                    AzureEnvironments.AzureChinaCloudEnvironment);

            var tokenProvider = new AzureAdTokenProvider(tokenCredentials);

            _context = new CloudMediaContext(new Uri(_RESTAPIEndpoint), tokenProvider);


            // Get an uploaded asset.
            var asset = _context.Assets.FirstOrDefault();

            // Encode and generate the output using the "Adaptive Streaming" preset.
            EncodeToAdaptiveBitrateMP4Set(asset);

            Console.ReadLine();
        }

        static public IAsset EncodeToAdaptiveBitrateMP4Set(IAsset asset)
        {
            // Declare a new job.
            IJob job = _context.Jobs.Create("Media Encoder Standard Job");
            // Get a media processor reference, and pass to it the name of the 
            // processor to use for the specific task.
            IMediaProcessor processor = GetLatestMediaProcessorByName("Media Encoder Standard");

            // Create a task with the encoding details, using a string preset.
            // In this case "Adaptive Streaming" preset is used.
            ITask task = job.Tasks.AddNew("My encoding task",
                processor,
                "Adaptive Streaming",
                TaskOptions.None);

            // 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);

            job.StateChanged += new EventHandler<JobStateChangedEventArgs>(JobStateChanged);
            job.Submit();
            job.GetExecutionProgressTask(CancellationToken.None).Wait();

            return job.OutputMediaAssets[0];
        }

        private static void JobStateChanged(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("Job is finished. Please wait while local tasks or downloads complete...");
                    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.
                    break;
                default:
                    break;
            }
        }

        private static IMediaProcessor GetLatestMediaProcessorByName(string mediaProcessorName)
        {
            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;
        }
    }
}

后续步骤

如何使用 Media Encoder Standard 通过 .NET 来生成缩略图 媒体服务编码概述