Сайт dreamspark пишет что код истек :( |
Media Services
В Windows Azure Media Services необходимо создавать работы (jobs) обработки мультимедиа-контента: шифрования, кодирования, конвертирования и т.д.. Работа Media Services всегда содержит в себе определение нескольких задач. Далее мы создадим простую задачу кодирования, после чего запустим ее на выполнение с Windows Azure Media Encoder. Задача будет использовать специальную строку настройки – пресет (preset) – для того, чтобы определить тип кодирования. Windows Azure Media Services поддерживвает аналогичный Microsoft Expression Encoder набор форматов.
Ниже приведен метод CreateEncodingJob, который необходимо добавить в класс. Метод выполняет следующие задачи:
- Определяет новую работу
- Определяет обработчик мультимедиа (media processor) для обработки работы. Обработчик мультимедиа – это компонент, который выполняет шифрование, кодирование, конвертирование и другие задачи. Всего есть несколько доступных обработчиков, список которых можно получить, вызвав _context.MediaProcessors. Метод GetLatestMediaProcessorByName возвращает обработчик.
- Определяет новую задачу. Каждая работа содержит одну и более задач. Задача определяется ее именем, экземпляром обработчика мультимедиа, строки конфигурации задачи и различных опций создания задачи. Строка конфигурации задачи определяет настройки кодирования. Например, здесь используется настройка H264 Broadband 720p, и этот пресет ведет к созданию одного файла MP4.
- Добавляет в задачу входной ассет. В этом примере входной ассет был создан ранее.
- Добавляет в задачу выходной ассет. Для выходного ассета определяется имя, булево значение, обозначающее, сохранять результат на сервере или нет, и AssetCreationOptions.None, обозначающий, что результат не шифруется при передаче и транспортировке.
- Устанавливает работу в очередь.
Метод также демонстрирует выполнение других задач, таких как отслеживание статуса выполнения задачи и получение доступа к ассету, созданному работой кодирования.
static IJob CreateEncodingJob(IAsset asset, string inputMediaFilePath, string outputFolder) { IJob job = _context.Jobs.Create("My encoding job"); IMediaProcessor processor = GetLatestMediaProcessorByName("Windows Azure Media Encoder"); ITask task = job.Tasks.AddNew("My encoding task", processor, "H264 Broadband 720p", Microsoft.WindowsAzure.MediaServices.Client.TaskOptions.ProtectedConfiguration); task.InputAssets.Add(asset); task.OutputAssets.AddNew("Output asset", AssetCreationOptions.None); job.StateChanged += new EventHandler<JobStateChangedEventArgs>(StateChanged); job.Submit(); LogJobDetails(job.Id); // Проверка выполнения работы и ожидание ее окончания. Task progressJobTask = job.GetExecutionProgressTask(CancellationToken.None); progressJobTask.Wait(); // Код показывает, как можно получить доступ к ассетам-результату работы двумя способами – созданием URL-ов к ассетам и простому скачиванию job = GetJob(job.Id); if (job.State == JobState.Error) { Console.WriteLine("\nExiting method due to job error."); return job; } IAsset outputAsset = job.OutputMediaAssets[0]; IAccessPolicy policy = null; ILocator locator = null; policy = _context.AccessPolicies.Create("My 30 days readonly policy", TimeSpan.FromDays(30), AccessPermissions.Read); // Создание локатора Shared Access Signature для предоставления прямого доступа к ассету в хранилище блобов. Можно вызывать синхронный или асинхронный метод создания. Можно задавать опциональный параметр startTime, равный значению, на пять минут раннему нежели Now, для выравнивания различий во времени между часами клиента и сервера. locator = _context.Locators.CreateLocator(LocatorType.Sas, outputAsset, policy, DateTime.UtcNow.AddMinutes(-5)); List<String> sasUrlList = GetAssetSasUrlList(outputAsset, locator); // Запись списка URL-ов в локальный файл. Можно использовать сохраненные URL-ы для получения файлов ассета. 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()); DownloadAssetToLocal(job.Id, outputFolder); } return job; }
Добавим в метод Main вызов метода CreateEncodingJob после добавленного ранее кода.
CreateEncodingJob(asset, _singleInputFilePath, _outputFilesFolder);
Добавим приведенный ниже код, необходимый для выполнения метода CreateEncodingJob. Он выполняет следующие задачи:
1. Метод GetLatestMediaProcessorByName возвращает обработчик мультимедиа, выполняющий различные задачи. Вы создаете обработчик, используя имя обработчика. Возможные значения имени: Windows Azure Media Encoder,Windows Azure Media Packager,Windows Azure Media Encryptor,Storage Decryption.
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; }
Код ниже содержит обработчик события StateChanged, необходимый для отслеживания выполнения работы и логирования.
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: // Приведение к типу IJob job = (IJob)sender; // Логирование 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("Media Services account name: " + _accountName); 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"); 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); 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(); }
После получения ассетов получить к ним доступ возможно двумя способами:
- Создав SAS URL ассета на сервере
- Скачав ассеты с сервера
Метод GetAssetSasUrlList создает список SAS URL-ов на все файл ассета.
static List<String> GetAssetSasUrlList(IAsset asset, ILocator locator) { List<String> fileSasUrlList = new List<String>(); foreach (IAssetFile file in asset.AssetFiles) { string sasUrl = BuildFileSasUrl(file, locator); fileSasUrlList.Add(sasUrl); } return fileSasUrlList; } static string BuildFileSasUrl(IAssetFile file, ILocator locator) { // Получение пути-локатора, добавление имени файла для получения полного SAS URL для доступа к файлу. var uriBuilder = new UriBuilder(locator.Path); uriBuilder.Path += "/" + file.Name; Console.WriteLine("Locator path: "); Console.WriteLine(locator.Path); Console.WriteLine(); Console.WriteLine("Full URL to file: "); Console.WriteLine(uriBuilder.Uri.AbsoluteUri); Console.WriteLine(); return uriBuilder.Uri.AbsoluteUri; }
Метод DownloadAssetToLocal скачивает все файлы ассета в локальную директорию. В данном примере, так как ассет был создан из одного входящего файла, выходной ассет будет иметь колллекцию, содержащую два файла – закодированный файл (.mp4) и .xml файл с метаданными ассета. Метод скачивает оба файла.
static IAsset DownloadAssetToLocal(string jobId, string outputFolder) { // Этот метод показывает, как скачивать один ассет. Доступ ко всем ассетам можно получить с помощью коллекции OutputAssets. IJob job = GetJob(jobId); 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) { 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)); }
Методы GetJob и GetAsset запрашивают и возвращают ссылки на работу и ассет с указанными идентификаторами.
static IJob GetJob(string jobId) { var jobInstance = from j in _context.Jobs where j.Id == jobId select j; IJob job = jobInstance.FirstOrDefault(); return job; } static IAsset GetAsset(string assetId) { var assetInstance = from a in _context.Assets where a.Id == assetId select a; 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() … 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.
После запуска приложения происходит следующая последовательность действий:
- В Media Services загружается .wmv.
- Файл кодируется с использованием H264 Broadband 720p. Windows Azure Media Encoder.
- В supportFiles\outputFiles создается файл FileSasUrlList.txt, содержащий URL на закодированный ассет.
- Файлы .mp4 и _metadata.xmml скачиваются в директорию outputFiles.