Exporter (0) Imprimer
Développer tout

Gestion des notifications de travaux de Media Services

Mis à jour: novembre 2013

Microsoft Azure Media Services est en mesure de distribuer des messages de notification au service de file d'attente de stockage Azure lors du traitement de tâches multimédias. Cette rubrique décrit comment obtenir ces messages de notification du service de file d'attente de stockage.

Les messages transmis au service de file d'attente de stockage sont accessibles partout dans le monde. L'architecture de messagerie de file d'attente Azure est fiable et hautement évolutive. L'interrogation du service de file d'attente de stockage est recommandée par rapport à d'autres méthodes.

L'un des scénarios courants pour écouter les notifications des Media Services est lorsque vous développez un système de gestion de contenu qui doit exécuter une tâche supplémentaire après l'encodage d'une tâche (par exemple, déclencher la prochaine étape du flux de travail ou publier un contenu).

Considérations

Tenez compte de ce qui suit lorsque vous développez des applications Services de média qui utilisent la file d'attente de stockage Azure.

Exemple de code

L'exemple de code dans cette section accomplit ce qui suit :

  1. Définit la classe EncodingJobMessage qui mappe au format du message de notification. Le code désérialise les messages reçus de la file d'attente dans les objets de type EncodingJobMessage.

  2. Charge les informations des comptes Media Services et Storage à partir du fichier app.config. Utilise ces informations pour créer des objets CloudMediaContext et CloudQueue.

  3. Crée la file d'attente qui recevra les messages de notification concernant la tâche d'encodage.

  4. Crée le point de terminaison de notification qui est mappé à la file d'attente.

  5. Attache le point de terminaison de notification à la tâche et soumet la tâche d'encodage. Vous pouvez avoir plusieurs points de terminaison de notification attachés à une tâche.

    Dans cet exemple, nous sommes seulement intéressés par les dernières étapes du traitement des tâches, ce qui fait que nous passons NotificationJobState.FinalStatesOnly à la méthode AddNew.

    job.JobNotificationSubscriptions.AddNew(NotificationJobState.FinalStatesOnly, _notificationEndPoint); 
    
    Si vous passez NotificationJobState.All, vous devez vous attendre à obtenir toutes les notifications de changement d'état : En file d'attente -> Planifiés -> Traitement -> Terminés. Cependant, comme indiqué plus haut, le service de file d'attente de stockage Azure ne garantit pas une diffusion ordonnée. Vous pouvez utiliser la propriété Timestamp (définie sur le type EncodingJobMessage dans l'exemple ci-dessous) pour ordonner les messages. Il est possible d'obtenir des messages de notification en double. Utilisez la propriété ETag (définie sur le type EncodingJobMessage) pour vérifier les doublons. Notez qu'il est également possible que certaines notifications de changement d'état soient ignorées.

  6. Attendez que les travaux atteignent l'état Finished en vérifiant la file d'attente toutes les 10 secondes. Supprime les messages une fois qu'ils ont été traités.

  7. Supprime la file d'attente et le point de terminaison de notification.

noteRemarque
La méthode recommandée pour suivre l'état d'un travail est l'écoute des messages de notification, comme le montre l'exemple suivant.

Vous pouvez aussi vérifier l'état d'un travail en utilisant la propriété IJob.State. Notez qu'un message de notification concernant l'achèvement d'un travail peut arriver avant que l'State de IJob soit défini surFinished. La propriété IJob.State  reflète l'état exact avec un léger retard.  

using System; using System.Linq; using System.Configuration; using System.IO; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Collections.Generic; using Microsoft.WindowsAzure.MediaServices.Client; using System.Web; using Microsoft.WindowsAzure.Storage; using Microsoft.WindowsAzure.Storage.Auth; using Microsoft.WindowsAzure.Storage.Queue; using System.Runtime.Serialization.Json;  namespace JobNotification {     public class EncodingJobMessage     {         // MessageVersion is used for version control.          public String MessageVersion { get; set; }              // Type of the event. Valid values are          // JobStateChange and NotificationEndpointRegistration.         public String EventType { get; set; }              // ETag is used to help the customer detect if          // the message is a duplicate of another message previously sent.         public String ETag { get; set; }              // Time of occurrence of the event.         public String TimeStamp { get; set; }          // Collection of values specific to the event.          // For the JobStateChange event the values are:         //     JobId - Id of the Job that triggered the notification.         //     NewState- The new state of the Job. Valid values are:         //          Scheduled, Processing, Canceling, Cancelled, Error, Finished         //     OldState- The old state of the Job. Valid values are:         //          Scheduled, Processing, Canceling, Cancelled, Error, Finished          // For the NotificationEndpointRegistration event the values are:         //     NotificationEndpointId- Id of the NotificationEndpoint          //          that triggered the notification.         //     State- The state of the Endpoint.          //          Valid values are: Registered and Unregistered.          public IDictionary<string, object> Properties { get; set; }     }      class Program     {         private static CloudMediaContext _context = null;         private static CloudQueue _queue = null;         private static INotificationEndPoint _notificationEndPoint = null;          private static readonly string _singleInputMp4Path =             Path.GetFullPath(@"C:\supportFiles\multifile\BigBuckBunny.mp4");          static void Main(string[] args)         {             // Get the values from app.config file.             string mediaServicesAccountName = ConfigurationManager.AppSettings["MediaServicesAccountName"];             string mediaServicesAccountKey = ConfigurationManager.AppSettings["MediaServicesAccountKey"];             string storageConnectionString = ConfigurationManager.AppSettings["StorageConnectionString"];               string endPointAddress = Guid.NewGuid().ToString();              // Create the context.              _context = new CloudMediaContext(mediaServicesAccountName, mediaServicesAccountKey);              // Create the queue that will be receiving the notification messages.             _queue = CreateQueue(storageConnectionString, endPointAddress);              // Create the notification point that is mapped to the queue.             _notificationEndPoint =                      _context.NotificationEndPoints.Create(                     Guid.NewGuid().ToString(), NotificationEndPointType.AzureQueue, endPointAddress);               if (_notificationEndPoint != null)             {                 IJob job = SubmitEncodingJobWithNotificationEndPoint(_singleInputMp4Path);                 WaitForJobToReachedFinishedState(job.Id);             }              // Clean up.             _queue.Delete();                   _notificationEndPoint.Delete();        }           static public CloudQueue CreateQueue(string storageAccountConnectionString, string endPointAddress)         {             CloudStorageAccount storageAccount = CloudStorageAccount.Parse(storageAccountConnectionString);              // Create the queue client             CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();              // Retrieve a reference to a queue             CloudQueue queue = queueClient.GetQueueReference(endPointAddress);              // Create the queue if it doesn't already exist             queue.CreateIfNotExists();              return queue;         }            // Upload a video file, and encode to Smooth Streaming format         public static IJob SubmitEncodingJobWithNotificationEndPoint(string inputMediaFilePath)         {             // Declare a new job.             IJob job = _context.Jobs.Create("My MP4 to Smooth Streaming encoding job");              //Create an encrypted asset and upload the mp4.              IAsset asset = CreateAssetAndUploadSingleFile(AssetCreationOptions.StorageEncrypted,                  inputMediaFilePath);              // Get a media processor reference, and pass to it the name of the              // processor to use for the specific task.             IMediaProcessor processor = GetLatestMediaProcessorByName("Azure Media Encoder");              // Create a task with the conversion details, using a configuration file.              ITask task = job.Tasks.AddNew("My Mp4 to Smooth Task",                 processor,                 "H264 Smooth Streaming 720p",                 Microsoft.WindowsAzure.MediaServices.Client.TaskOptions.None);              // Specify the input asset to be encoded.             task.InputAssets.Add(asset);              // Add an output asset to contain the results of the job.             task.OutputAssets.AddNew("Output asset",                 AssetCreationOptions.None);              // Add a notification point to the job. You can add multiple notification points.               job.JobNotificationSubscriptions.AddNew(NotificationJobState.FinalStatesOnly,                  _notificationEndPoint);              job.Submit();              return job;         }          public static void WaitForJobToReachedFinishedState(string jobId)         {             int expectedState = (int)JobState.Finished;             int timeOutInSeconds = 600;              bool jobReachedExpectedState = false;             DateTime startTime = DateTime.Now;             int jobState = -1;              while (!jobReachedExpectedState)             {                 // Specify how often you want to get messages from the queue.                 Thread.Sleep(TimeSpan.FromSeconds(10));                  foreach (var message in _queue.GetMessages(10))                 {                     using (Stream stream = new MemoryStream(message.AsBytes))                     {                         DataContractJsonSerializerSettings settings = new DataContractJsonSerializerSettings();                         settings.UseSimpleDictionaryFormat = true;                         DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(EncodingJobMessage), settings);                         EncodingJobMessage encodingJobMsg = (EncodingJobMessage)ser.ReadObject(stream);                          Console.WriteLine();                          // Display the message information.                         Console.WriteLine("EventType: {0}", encodingJobMsg.EventType);                         Console.WriteLine("MessageVersion: {0}", encodingJobMsg.MessageVersion);                         Console.WriteLine("ETag: {0}", encodingJobMsg.ETag);                         Console.WriteLine("TimeStamp: {0}", encodingJobMsg.TimeStamp);                         foreach (var property in encodingJobMsg.Properties)                         {                             Console.WriteLine("    {0}: {1}", property.Key, property.Value);                         }                          // We are only interested in messages                          // where EventType is "JobStateChange".                         if (encodingJobMsg.EventType == "JobStateChange")                         {                             string JobId = (String)encodingJobMsg.Properties.Where(j => j.Key == "JobId").FirstOrDefault().Value;                             if (JobId == jobId)                             {                                 string oldJobStateStr = (String)encodingJobMsg.Properties.                                                             Where(j => j.Key == "OldState").FirstOrDefault().Value;                                 string newJobStateStr = (String)encodingJobMsg.Properties.                                                             Where(j => j.Key == "NewState").FirstOrDefault().Value;                                  JobState oldJobState = (JobState)Enum.Parse(typeof(JobState), oldJobStateStr);                                 JobState newJobState = (JobState)Enum.Parse(typeof(JobState), newJobStateStr);                                  if (newJobState == (JobState)expectedState)                                 {                                     Console.WriteLine("job with Id: {0} reached expected state: {1}",                                          jobId, newJobState);                                     jobReachedExpectedState = true;                                     break;                                 }                             }                         }                     }                     // Delete the message after we've read it.                     _queue.DeleteMessage(message);                 }                  // Wait until timeout                 TimeSpan timeDiff = DateTime.Now - startTime;                 bool timedOut = (timeDiff.TotalSeconds > timeOutInSeconds);                 if (timedOut)                 {                     Console.WriteLine(@"Timeout for checking job notification messages,                                          latest found state ='{0}', wait time = {1} secs",                         jobState,                         timeDiff.TotalSeconds);                      throw new TimeoutException();                 }             }         }             static private IAsset CreateAssetAndUploadSingleFile(AssetCreationOptions assetCreationOptions, string singleFilePath)         {             var asset = _context.Assets.Create("UploadSingleFile_" + DateTime.UtcNow.ToString(),                  assetCreationOptions);              var fileName = Path.GetFileName(singleFilePath);              var assetFile = asset.AssetFiles.Create(fileName);              Console.WriteLine("Created assetFile {0}", assetFile.Name);             Console.WriteLine("Upload {0}", assetFile.Name);              assetFile.Upload(singleFilePath);             Console.WriteLine("Done uploading of {0}", assetFile.Name);              return asset;         }          static private 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;         }     } } 

L'exemple ci-dessus donne le résultat suivant. Vos valeurs peuvent être différentes.

Created assetFile BigBuckBunny.mp4 Upload BigBuckBunny.mp4 Done uploading of BigBuckBunny.mp4  EventType: NotificationEndPointRegistration MessageVersion: 1.0 ETag: e0238957a9b25bdf3351a88e57978d6a81a84527fad03bc23861dbe28ab293f6 TimeStamp: 2013-05-14T20:22:37     NotificationEndPointId: nb:nepid:UUID:d6af9412-2488-45b2-ba1f-6e0ade6dbc27     State: Registered     Name: dde957b2-006e-41f2-9869-a978870ac620     Created: 2013-05-14T20:22:35  EventType: JobStateChange MessageVersion: 1.0 ETag: 4e381f37c2d844bde06ace650310284d6928b1e50101d82d1b56220cfcb6076c TimeStamp: 2013-05-14T20:24:40     JobId: nb:jid:UUID:526291de-f166-be47-b62a-11ffe6d4be54     JobName: My MP4 to Smooth Streaming encoding job     NewState: Finished     OldState: Processing     AccountName: westeuropewamsaccount job with Id: nb:jid:UUID:526291de-f166-be47-b62a-11ffe6d4be54 reached expected  State: Finished 


Date de génération :

2014-05-23

Ajouts de la communauté

AJOUTER
Microsoft réalise une enquête en ligne pour recueillir votre opinion sur le site Web de MSDN. Si vous choisissez d’y participer, cette enquête en ligne vous sera présentée lorsque vous quitterez le site Web de MSDN.

Si vous souhaitez y participer,
Afficher:
© 2014 Microsoft