|
Сайт 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.