Tutoriel : Diffuser en direct avec Media Services en utilisant .NET 5.0

Dans Azure Media Services, les événements en direct sont responsables du traitement de contenu de streaming en direct. Un événement en direct fournit un point de terminaison d’entrée (URL d’ingestion) que vous fournissez ensuite à un encodeur live. Il reçoit des flux d’entrée d’un encodeur live et les rend disponibles pour le streaming par le biais d’un ou de plusieurs points de terminaison de streaming. Les événements en direct fournissent également un point de terminaison d’aperçu (URL d’aperçu) que vous utilisez pour prévisualiser et valider votre flux avant de poursuivre le traitement ou la distribution.

Ce tutoriel explique comment utiliser .NET 5.0 pour créer un type de Pass-through d'événement en direct. Ce didacticiel présente les procédures suivantes :

Si vous n’avez pas d’abonnement Azure, créez un compte gratuit avant de commencer.

Notes

Bien que ce didacticiel utilise des exemples .NET SDK, les étapes générales sont les mêmes pour l’API REST, l’interface de ligne de commande et d’autres kits de développement logiciel (SDK) pris en charge.

Prérequis

Pour ce tutoriel, vous devez disposer des éléments suivants :

Vous avez besoin de ces éléments supplémentaires pour les logiciels de streaming en direct :

  • Une caméra ou appareil (tel qu’un ordinateur portable) utilisé pour diffuser un événement.

  • Un encodeur logiciel local qui encode votre flux de caméra et l’envoie au service de streaming en direct Media Services via le protocole RTMP (Real-Time Messaging Protocol). Pour plus d’informations, consultez Encodeurs live locaux recommandés. La diffusion doit se faire au format RTMP ou Smooth Streaming.

    Cet exemple part du principe que vous allez utiliser Open Broadcaster Software (OBS) Studio pour diffuser le RTMP au point de terminaison d’ingestion. Installez OBS Studio.

Conseil

Consultez Streaming en direct avec Media Services v3 avant de commencer.

Télécharger et configurer l’exemple

Clonez le dépôt GitHub qui contient l’exemple .NET de streaming en direct sur votre machine en utilisant la commande suivante :

git clone https://github.com/Azure-Samples/media-services-v3-dotnet.git

L’exemple de streaming en direct se trouve dans le dossier Live.

Ouvrez appsettings.json dans votre projet téléchargé. Remplacez les valeurs par les informations d’identification que vous avez obtenues en accédant aux API.

Notes

Vous pouvez également utiliser le format de fichier .env à la racine du projet afin de définir vos variables d’environnement une seule fois pour tous les projets du dépôt d’exemples .NET. Il vous suffit de copier le fichier sample.env, puis de renseigner les informations que vous avez obtenues à partir de la page Accéder à l’API de Media Services dans le portail Azure ou à partir d’Azure CLI. Renommez le fichier sample.env en .env pour l’utiliser dans tous les projets.

Le fichier .gitignore est déjà configuré pour empêcher la publication de ce fichier dans votre dépôt dupliqué.

Important

Cet exemple utilise un suffixe unique pour chaque ressource. Si vous annulez le débogage ou vous fermez l’application sans l’avoir effectué, vous obtiendrez plusieurs événements en direct sur votre compte.

Veillez à arrêter les événements en direct en cours d’exécution. Sinon, vous serez facturé !

Examiner le code qui effectue la diffusion en continu

Cette section examine les fonctions définies dans les fichiers (du dossier Common_Utils) Authentication.cs et Program.cs du projet LiveEventWithDVR.

L’exemple crée un suffixe unique pour chaque ressource afin d’éviter tout conflit de noms si vous exécutez l’exemple plusieurs fois sans le supprimer.

Commencer à utiliser les API Media Services avec le SDK .NET

Authentication.cs crée un objet AzureMediaServicesClient à l’aide des informations d’identification fournies dans les fichiers de configuration locaux (appsettings.jssur ou .env).

Un objet AzureMediaServicesClient vous permet de commencer à utiliser des API Media Services avec .NET. Pour créer l’objet, vous devez fournir des informations d’identification pour que le client puisse se connecter à Azure avec Azure Active Directory, implémenté dans GetCredentailsAsync. Une autre option consiste à utiliser l’authentification interactive, qui est implémentée dans GetCredentialsInteractiveAuthAsync.

public static async Task<IAzureMediaServicesClient> CreateMediaServicesClientAsync(ConfigWrapper config, bool interactive = false)
{
    ServiceClientCredentials credentials;
    if (interactive)
        credentials = await GetCredentialsInteractiveAuthAsync(config);
    else
        credentials = await GetCredentialsAsync(config);

    return new AzureMediaServicesClient(config.ArmEndpoint, credentials)
    {
        SubscriptionId = config.SubscriptionId,
    };
}

Dans le code que vous avez cloné au début de l’article, la fonction GetCredentialsAsynccrée l’objet ServiceClientCredentials en fonction des informations d’identification fournies dans le fichier de configuration local (appsettings.json) ou par le biais du fichier de variables d’environnement .env à la racine du dépôt.

private static async Task<ServiceClientCredentials> GetCredentialsAsync(ConfigWrapper config)
{
    // Use ConfidentialClientApplicationBuilder.AcquireTokenForClient to get a token using a service principal with symmetric key

    var scopes = new[] { config.ArmAadAudience + "/.default" };

    var app = ConfidentialClientApplicationBuilder.Create(config.AadClientId)
        .WithClientSecret(config.AadSecret)
        .WithAuthority(AzureCloudInstance.AzurePublic, config.AadTenantId)
        .Build();

    var authResult = await app.AcquireTokenForClient(scopes)
                                             .ExecuteAsync()
                                             .ConfigureAwait(false);

    return new TokenCredentials(authResult.AccessToken, TokenType);
}

Dans le cas de l’authentification interactive, la fonction GetCredentialsInteractiveAuthAsync crée l’objet ServiceClientCredentials en fonction d’une authentification interactive et des paramètres de connexion fournis dans le fichier config local (appsettings.json) ou via le fichier de variables d’environnement .env situé à la racine du dépôt. Dans ce cas, AADCLIENTID et AADSECRET ne sont pas nécessaires dans le fichier de variables d'environnement ou de configuration.

private static async Task<ServiceClientCredentials> GetCredentialsInteractiveAuthAsync(ConfigWrapper config)
{
    var scopes = new[] { config.ArmAadAudience + "/user_impersonation" };

    // client application of Az Cli
    string ClientApplicationId = "04b07795-8ddb-461a-bbee-02f9e1bf7b46";

    AuthenticationResult result = null;

    IPublicClientApplication app = PublicClientApplicationBuilder.Create(ClientApplicationId)
        .WithAuthority(AzureCloudInstance.AzurePublic, config.AadTenantId)
        .WithRedirectUri("http://localhost")
        .Build();

    var accounts = await app.GetAccountsAsync();

    try
    {
        result = await app.AcquireTokenSilent(scopes, accounts.FirstOrDefault()).ExecuteAsync();
    }
    catch (MsalUiRequiredException)
    {
        try
        {
            result = await app.AcquireTokenInteractive(scopes).ExecuteAsync();
        }
        catch (MsalException maslException)
        {
            Console.Error.WriteLine($"ERROR: MSAL interactive authentication exception with code '{maslException.ErrorCode}' and message '{maslException.Message}'.");
        }
    }
    catch (MsalException maslException)
    {
        Console.Error.WriteLine($"ERROR: MSAL silent authentication exception with code '{maslException.ErrorCode}' and message '{maslException.Message}'.");
    }

    return new TokenCredentials(result.AccessToken, TokenType);
}

Créer un événement en temps réel

Cette section montre comment créer un type de Pass-through d’événement en direct (LiveEventEncodingType défini sur None). Pour plus d’informations sur les types disponibles, consultez Types d’événements en direct. En plus de Pass-through, vous pouvez utiliser un événement de transcodage live pour un encodage cloud à débit adaptatif 720p ou 1080p.

Vous souhaiterez peut-être spécifier les éléments suivants lors de la création de l’événement en direct :

  • Protocole d’ingestion pour l’événement en direct. Les protocoles RTMP, RTMPS et Smooth Streaming sont pris en charge. Vous ne pouvez pas changer l’option de protocole pendant l’exécution de l’événement en direct ou des sorties en direct qui lui sont associées. Si vous avez besoin d’autres protocoles, créez des événements en direct distincts pour chaque protocole de streaming.

  • Restrictions IP sur l’ingestion et l’aperçu. Vous pouvez définir les adresses IP autorisées à recevoir du contenu vidéo sur cet événement en direct. Les adresses IP autorisées peuvent être spécifiées sous l’une des formes suivantes :

    • Une adresse IP unique (par exemple, 10.0.0.1)
    • Plage d’adresses IP qui utilise une adresse IP et un masque de sous-réseau de routage CIDR (Classless InterDomain Routing) (par exemple, 10.0.0.1/22)
    • Plage d’adresses IP utilisant une adresse IP et un masque de sous-réseau décimal séparé par des points (par exemple, 10.0.0.1(255.255.252.0))

    Si aucune adresse IP n’est spécifiée et qu’il n’existe pas de définition de règle, alors aucune adresse IP ne sera autorisée. Pour autoriser toutes les adresses IP, créez une règle et définissez la valeur 0.0.0.0/0. Les adresses IP doivent utiliser un des formats suivants : adresses IPv4 à quatre chiffres ou une plage d’adresses CIDR.

  • Démarrage automatique d’un événement quand vous le créez. Quand le démarrage automatique est défini sur true, l’événement en direct démarre après sa création. La facturation commence donc dès le démarrage de l’événement en direct. Vous devez appeler explicitement la commande Stop sur la ressource de l’événement en direct pour arrêter toute facturation supplémentaire. Pour plus d’informations, consultez États et facturation des événements en direct.

    Des modes veille permettent de démarrer l’événement en direct dans un état « alloué » à moindre coût qui accélère le passage à l’état En cours d’exécution. C’est utile dans certains, par exemple quand des pools très sollicités doivent distribuer rapidement des canaux aux diffuseurs.

  • Un nom d’hôte statique et un GUID unique. Pour qu’une URL d’ingestion soit prévisible et plus facile à gérer dans un encodeur live matériel, affectez la valeur true à la propriété useStaticHostname. Pour plus d’informations, consultez URL d’ingestion des événements en direct.

Console.WriteLine($"Creating a live event named {liveEventName}");
Console.WriteLine();

// Creating the LiveEvent - the primary object for live streaming in AMS. 
// See the overview - https://docs.microsoft.com/azure/media-services/latest/live-streaming-overview

// Create the LiveEvent

// Understand the concepts of what a live event and a live output is in AMS first!
// Read the following - https://docs.microsoft.com/azure/media-services/latest/live-events-outputs-concept
// 1) Understand the billing implications for the various states
// 2) Understand the different live event types, pass-through and encoding
// 3) Understand how to use long-running async operations 
// 4) Understand the available Standby mode and how it differs from the Running Mode. 
// 5) Understand the differences between a LiveOutput and the Asset that it records to.  They are two different concepts.
//    A live output can be considered as the "tape recorder" and the Asset is the tape that is inserted into it for recording.
// 6) Understand the advanced options such as low latency, and live transcription/captioning support. 
//    Live Transcription - https://docs.microsoft.com/en-us/azure/media-services/latest/live-transcription
//    Low Latency - https://docs.microsoft.com/en-us/azure/media-services/latest/live-event-latency

// When broadcasting to a live event, please use one of the verified on-premises live streaming encoders.
// While operating this tutorial, it is recommended to start out using OBS Studio before moving to another encoder. 

// Note: When creating a LiveEvent, you can specify allowed IP addresses in one of the following formats:                 
//      IpV4 address with 4 numbers
//      CIDR address range  

IPRange allAllowIPRange = new(
    name: "AllowAll",
    address: "0.0.0.0",
    subnetPrefixLength: 0
);

// Create the LiveEvent input IP access control object
// this will control the IP that the encoder is running on and restrict access to only that encoder IP range.
LiveEventInputAccessControl liveEventInputAccess = new()
{
    Ip = new IPAccessControl(
            allow: new IPRange[]
            {
                // re-use the same range here for the sample, but in production you can lock this
                // down to the ip range for your on-premises live encoder, laptop, or device that is sending
                // the live stream
                allAllowIPRange
            }
        )

};

// Create the LiveEvent Preview IP access control object. 
// This will restrict which clients can view the preview endpoint
LiveEventPreview liveEventPreview = new()
{
    AccessControl = new LiveEventPreviewAccessControl(
        ip: new IPAccessControl(
            allow: new IPRange[]
            {
                 // re-use the same range here for the sample, but in production you can lock this to the IPs of your 
                // devices that would be monitoring the live preview. 
                allAllowIPRange
            }
        )
    )
};

// To get the same ingest URL for the same LiveEvent name:
// 1. Set useStaticHostname to true so you have ingest like: 
//        rtmps://liveevent-hevc12-eventgridmediaservice-usw22.channel.media.azure.net:2935/live/522f9b27dd2d4b26aeb9ef8ab96c5c77           
// 2. Set the inputs:accessToken to a desired GUID string (with or without hyphen) to make it simpler to update your encoder settings

// See REST API documentation for details on each setting value
// https://docs.microsoft.com/rest/api/media/liveevents/create 

LiveEvent liveEvent = new(
    location: mediaService.Location,
    description: "Sample LiveEvent from .NET SDK sample",
    // Set useStaticHostname to true to make the ingest and preview URL host name the same. 
    // This can slow things down a bit. 
    useStaticHostname: true,

    // 1) Set up the input settings for the Live event...
    input: new LiveEventInput(
        streamingProtocol: LiveEventInputProtocol.RTMP,  // options are RTMP or Smooth Streaming ingest format.
                                                         // This sets a static access token for use on the ingest path. 
                                                         // Combining this with useStaticHostname:true will give you the same ingest URL on every creation.
                                                         // This is helpful when you only want to enter the URL into a single encoder one time for this Live Event name
        accessToken: "acf7b6ef-8a37-425f-b8fc-51c2d6a5a86a",  // Use this value when you want to make sure the ingest URL is static and always the same. If omitted, the service will generate a random GUID value.
        accessControl: liveEventInputAccess, // controls the IP restriction for the source encoder.
        keyFrameIntervalDuration: "PT2S" // Set this to match the ingest encoder's settings
    ),
    // 2) Set the live event to use pass-through or cloud encoding modes...
    encoding: new LiveEventEncoding(
        // Set this to Standard (720P) or Premium1080P to use the cloud live encoder.
        // See https://go.microsoft.com/fwlink/?linkid=2095101 for more information
        // Otherwise, set to PassthroughBasic or PassthroughStandard to use the two different pass-through modes. 
        encodingType: LiveEventEncodingType.PassthroughStandard // Choose the type of live event - standard or basic pass-through, or the encoding types for 720P or 1080P
                                                 // OPTIONAL settings when using live cloud encoding type:
                                                 // keyFrameInterval: "PT2S", //If this value is not set for an encoding live event, the fragment duration defaults to 2 seconds. The value cannot be set for pass-through live events.
                                                 // presetName: null, // only used for custom defined presets. 
                                                 //stretchMode: "None" // can be used to determine stretch on encoder mode
    ),
    // 3) Set up the Preview endpoint for monitoring based on the settings above we already set.
    preview: liveEventPreview,
    // 4) Set up more advanced options on the live event. Low Latency is the most common one.
    streamOptions: new List<StreamOptionsFlag?>()
    {
        // Set this to Default or Low Latency
        // When using Low Latency mode, you must configure the Azure Media Player to use the 
        // quick start heuristic profile or you won't notice the change. 
        // In the AMP player client side JS options, set -  heuristicProfile: "Low Latency Heuristic Profile". 
        // To use low latency optimally, you should tune your encoder settings down to 1 second GOP size instead of 2 seconds.
        StreamOptionsFlag.LowLatency
    }
//,
// 5) Optionally enable live transcriptions if desired. This is only supported on PassthroughStandard, and the transcoding live event types. It is not supported on Basic pass-through type.
// WARNING : This is extra cost ($$$), so please check pricing before enabling.
/*transcriptions:new List<LiveEventTranscription>(){
    new LiveEventTranscription(
        // The value should be in BCP-47 format (e.g: 'en-US'). See https://go.microsoft.com/fwlink/?linkid=2133742
        language: "en-us",
        outputTranscriptionTrack : new LiveEventOutputTranscriptionTrack(
            trackName: "English" // set the name you want to appear in the output manifest
        )
    )
}*/
);

// Start monitoring LiveEvent events using Event Grid and Event Hub
try
{
    // Please refer README for Event Hub and storage settings.
    // A storage account is required to process the Event Hub events from the Event Grid subscription in this sample.

    // Create a new host to process events from an Event Hub.
    Console.WriteLine("Creating a new client to process events from an Event Hub...");
    var credential = new DefaultAzureCredential();
    var storageConnectionString = string.Format("DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}",
       config.StorageAccountName, config.StorageAccountKey);
    var blobContainerName = config.StorageContainerName;
    var eventHubsConnectionString = config.EventHubConnectionString;
    var eventHubName = config.EventHubName;
    var consumerGroup = config.EventHubConsumerGroup;

    storageClient = new BlobContainerClient(
        storageConnectionString,
        blobContainerName);

    processorClient = new EventProcessorClient(
        storageClient,
        consumerGroup,
        eventHubsConnectionString,
        eventHubName);

    mediaEventProcessor = new MediaServicesEventProcessor(null, null, liveEventName);
    processorClient.ProcessEventAsync += mediaEventProcessor.ProcessEventsAsync;
    processorClient.ProcessErrorAsync += mediaEventProcessor.ProcessErrorAsync;

    await processorClient.StartProcessingAsync();
}
catch (Exception e)
{
    Console.WriteLine("Failed to connect to Event Hub, please refer README for Event Hub and storage settings. Skipping event monitoring...");
    Console.WriteLine(e.Message);
}

Console.WriteLine("Creating the LiveEvent, please be patient as this can take time to complete async.");
Console.WriteLine("Live Event creation is an async operation in Azure and timing can depend on resources available.");

// When autostart is set to true, the Live Event will be started after creation. 
// That means, the billing starts as soon as the Live Event starts running. 
// You must explicitly call Stop on the Live Event resource to halt further billing.
// The following operation can sometimes take awhile. Be patient.
// On optional workflow is to first call allocate() instead of create. 
// https://docs.microsoft.com/en-us/rest/api/media/liveevents/allocate 
// This allows you to allocate the resources and place the live event into a "Standby" mode until 
// you are ready to transition to "Running". This is useful when you want to pool resources in a warm "Standby" state at a reduced cost.
// The transition from Standby to "Running" is much faster than cold creation to "Running" using the autostart property.
// Returns a long running operation polling object that can be used to poll until completion.

Stopwatch watch = Stopwatch.StartNew();
liveEvent = await client.LiveEvents.CreateAsync(
    config.ResourceGroup,
    config.AccountName,
    liveEventName,
    liveEvent,
    // When autostart is set to true, you should "await" this method operation to complete. 
    // The Live Event will be started after creation. 
    // You may choose not to do this, but create the object, and then start it using the standby state to 
    // keep the resources "warm" and billing at a lower cost until you are ready to go live. 
    // That increases the speed of startup when you are ready to go live. 
    autoStart: false);
watch.Stop();
string elapsedTime = String.Format(":{0:00}.{1:00}", watch.Elapsed.Seconds, watch.Elapsed.Milliseconds / 10);
Console.WriteLine($"Create Live Event run time : {elapsedTime}");

Obtenir les URL de réception

Après la création de l’événement en direct, vous pouvez obtenir des URL d’ingestion que vous fournirez à l’encodeur live. L’encodeur utilise ces URL pour entrer un flux dynamique.

// Get the RTMP ingest URL to configure in OBS Studio. 
// The endpoints is a collection of RTMP primary and secondary, and RTMPS primary and secondary URLs. 
// to get the primary secure RTMPS, it is usually going to be index 3, but you could add a loop here to confirm...
string ingestUrl = liveEvent.Input.Endpoints.First().Url;
Console.WriteLine($"The RTMP ingest URL to enter into OBS Studio is:");
Console.WriteLine($"\t{ingestUrl}");
Console.WriteLine("Make sure to enter a Stream Key into the OBS studio settings. It can be any value or you can repeat the accessToken used in the ingest URL path.");
Console.WriteLine();

Obtenir l’URL d’aperçu

Utilisez previewEndpoint pour obtenir un aperçu et vérifier que l’entrée de l’encodeur est bien reçue.

Important

Avant de poursuivre, veillez à ce que la vidéo transite par l’URL d’aperçu.

// Use the previewEndpoint to preview and verify
// that the input from the encoder is actually being received
// The preview endpoint URL also support the addition of various format strings for HLS (format=m3u8-cmaf) and DASH (format=mpd-time-cmaf) for example.
// The default manifest is Smooth. 
string previewEndpoint = liveEvent.Preview.Endpoints.First().Url;
Console.WriteLine($"The preview url is:");
Console.WriteLine($"\t{previewEndpoint}");
Console.WriteLine();

Console.WriteLine($"Open the live preview in your browser and use the Azure Media Player to monitor the preview playback:");
Console.WriteLine($"\thttps://ampdemo.azureedge.net/?url={previewEndpoint}&heuristicprofile=lowlatency");
Console.WriteLine();

Créer et gérer des événements en direct et des sorties en direct

Une fois que le flux transite dans l’événement en direct, vous pouvez commencer l’événement de streaming en créant un actif multimédia, une sortie en direct et un localisateur de streaming. Le flux est alors archivé et mis à la disposition des observateurs via le point de terminaison de diffusion en continu.

Quand vous apprenez ces concepts, il est utile de penser à l’objet d’actif multimédia comme si c’était la cassette que vous insériez dans un magnétoscope à l’époque. La sortie en direct est le magnétoscope. L’événement en direct est simplement le signal vidéo arrivant à l’arrière de l’appareil.

Vous créez d’abord le signal en créant l’événement en direct. Le signal n’est pas transmis tant que vous n’avez pas démarré cet événement en direct et que vous n’avez pas connecté votre encodeur à l’entrée.

La « cassette » peut être créée à tout moment. Il s’agit juste d’un actif multimédia vide que vous allez transmettre à l’objet de sortie en direct, le « magnétoscope » dans cette analogie.

Le « magnétoscope » peut également être créé à tout moment. Vous pouvez créer une sortie en direct avant de démarrer le flux du signal, ou après. Si vous avez besoin d’accélérer les opérations, il est parfois utile de créer la sortie avant de démarrer le flux du signal.

Pour arrêter le « magnétoscope », vous appelez delete sur LiveOutput. Cette action ne supprime pas le contenu de la « bande » (actif multimédia). L’actif multimédia est toujours conservé avec le contenu vidéo archivé tant que vous n’appelez pas delete explicitement sur l’actif multimédia lui-même.

La section suivante vous guidera tout au long de la création de l’actif multimédia et de la sortie en direct.

Créer une ressource

Créez un actif multimédia pour la sortie en direct à utiliser. Dans notre analogie, il s’agit de la « cassette » sur laquelle nous enregistrons le signal vidéo en direct. Les visiteurs peuvent voir le contenu en direct ou à la demande à partir de cette cassette virtuelle.

// Create an Asset for the LiveOutput to use. Think of this as the "tape" that will be recorded to. 
// The asset entity points to a folder/container in your Azure Storage account. 
Console.WriteLine($"Creating an asset named {assetName}");
Console.WriteLine();
Asset asset = await client.Assets.CreateOrUpdateAsync(config.ResourceGroup, config.AccountName, assetName, new Asset());

Créer une sortie en direct

Les sorties en direct démarrent quand elles sont créées et s’arrêtent quand elles sont supprimées. Quand vous supprimez la sortie en direct, vous ne supprimez pas l’actif multimédia sous-jacent ou le contenu de celui-ci. Cela revient à éjecter la « cassette ». L’actif multimédia contenant l’enregistrement dure aussi longtemps que vous le souhaitez. Quand il est éjecté (c’est-à-dire, quand la sortie en direct est supprimée), il est immédiatement disponible pour un visionnage à la demande.

// Create the Live Output - think of this as the "tape recorder for the live event". 
// Live outputs are optional, but are required if you want to archive the event to storage,
// use the asset for on-demand playback later, or if you want to enable cloud DVR time-shifting.
// We will use the asset created above for the "tape" to record to. 
string manifestName = "output";
Console.WriteLine($"Creating a live output named {liveOutputName}");
Console.WriteLine();

watch = Stopwatch.StartNew();
// See the REST API for details on each of the settings on Live Output
// https://docs.microsoft.com/rest/api/media/liveoutputs/create
LiveOutput liveOutput = new(
    assetName: asset.Name,
    manifestName: manifestName, // The HLS and DASH manifest file name. This is recommended to set if you want a deterministic manifest path up front.
                                // archive window can be set from 3 minutes to 25 hours. Content that falls outside of ArchiveWindowLength
                                // is continuously discarded from storage and is non-recoverable. For a full event archive, set to the maximum, 25 hours.
    archiveWindowLength: TimeSpan.FromHours(1)
);
liveOutput = await client.LiveOutputs.CreateAsync(
    config.ResourceGroup,
    config.AccountName,
    liveEventName,
    liveOutputName,
    liveOutput);
elapsedTime = String.Format(":{0:00}.{1:00}", watch.Elapsed.Seconds, watch.Elapsed.Milliseconds / 10);
Console.WriteLine($"Create Live Output run time : {elapsedTime}");
Console.WriteLine();

Créer un localisateur de diffusion en continu

Notes

Une fois votre compte Media Services créé, un point de terminaison de streaming par défaut est ajouté à votre compte dans l’état Arrêté. Pour démarrer le streaming de votre contenu et tirer parti de l’empaquetage dynamique et du chiffrement dynamique, le point de terminaison de streaming à partir duquel vous souhaitez diffuser du contenu doit se trouver à l’état En cours d’exécution.

Quand vous publiez l’actif multimédia en utilisant un localisateur de streaming, l’événement en direct (jusqu’à la longueur de la fenêtre DVR) reste visible jusqu’à l’expiration ou la suppression du localisateur de streaming, en fonction de ce qui se produit en premier. C’est comme cela que vous pouvez mettre l’enregistrement sur « cassette » virtuelle à la disposition de votre public pour le regarder en direct et à la demande. La même URL peut être utilisée pour regarder l’événement en direct, la fenêtre DVR ou l’actif multimédia à la demande quand l’enregistrement est terminé (quand la sortie en direct est supprimée).

Console.WriteLine($"Creating a streaming locator named {streamingLocatorName}");
Console.WriteLine();

IList<string> filters = new List<string>
{
    drvAssetFilterName
};
StreamingLocator locator = await client.StreamingLocators.CreateAsync(config.ResourceGroup,
    config.AccountName,
    drvStreamingLocatorName,
    new StreamingLocator
    {
        AssetName = assetName,
        StreamingPolicyName = PredefinedStreamingPolicy.ClearStreamingOnly,
        Filters = filters   // Associate the dvr filter with StreamingLocator.
    });

// Get the default Streaming Endpoint on the account
StreamingEndpoint streamingEndpoint = await client.StreamingEndpoints.GetAsync(config.ResourceGroup, config.AccountName, streamingEndpointName);

// If it's not running, Start it. 
if (streamingEndpoint.ResourceState != StreamingEndpointResourceState.Running)
{
    Console.WriteLine("Streaming Endpoint was Stopped, restarting now..");
    await client.StreamingEndpoints.StartAsync(config.ResourceGroup, config.AccountName, streamingEndpointName);

    // Since we started the endpoint, we should stop it in cleanup.
    stopEndpoint = true;
}

// Get the URL to stream the output
ListPathsResponse paths = await client.StreamingLocators.ListPathsAsync(resourceGroupName, accountName, locatorName);

foreach (StreamingPath path in paths.StreamingPaths)
{
    UriBuilder uriBuilder = new UriBuilder();
    uriBuilder.Scheme = "https";
    uriBuilder.Host = streamingEndpoint.HostName;

    uriBuilder.Path = path.Paths[0];
    // Get the URL from the uriBuilder: uriBuilder.ToString()
}

Supprimer les ressources de votre compte Media Services

Si vous avez terminé de diffuser en streaming les événements et que vous voulez nettoyer les ressources provisionnées précédemment, utilisez la procédure ci-dessous :

  1. Arrêtez d’envoyer le flux à partir de l’encodeur.
  2. Arrêtez l’événement en temps réel. Une fois l’événement en direct arrêté, aucun frais n’est encouru. Lorsque vous devez le redémarrer, il possède la même URL de réception. Vous n’avez donc pas besoin de reconfigurer votre encodeur.
  3. Arrêtez votre point de terminaison de streaming, sauf si vous souhaitez continuer à fournir l’archive de votre événement en direct en tant que flux à la demande. Si l’événement en direct est à l’état Arrêté, aucun frais n’est encouru.
private static async Task CleanupLiveEventAndOutputAsync(IAzureMediaServicesClient client, string resourceGroup, string accountName, string liveEventName, string liveOutputName)
{
    try
    {
        LiveEvent liveEvent = await client.LiveEvents.GetAsync(resourceGroup, accountName, liveEventName);

        Console.WriteLine("Deleting Live Output");
        Stopwatch watch = Stopwatch.StartNew();

        await client.LiveOutputs.DeleteAsync(resourceGroup, accountName, liveEventName, liveOutputName);

        String elapsedTime = String.Format(":{0:00}.{1:00}", watch.Elapsed.Seconds, watch.Elapsed.Milliseconds / 10);
        Console.WriteLine($"Delete Live Output run time : {elapsedTime}");

        if (liveEvent != null)
        {
            if (liveEvent.ResourceState == LiveEventResourceState.Running)
            {
                watch = Stopwatch.StartNew();
                // If the LiveEvent is running, stop it and have it remove any LiveOutputs
                await client.LiveEvents.StopAsync(resourceGroup, accountName, liveEventName, removeOutputsOnStop: false);
                elapsedTime = String.Format(":{0:00}.{1:00}", watch.Elapsed.Seconds, watch.Elapsed.Milliseconds / 10);
                Console.WriteLine($"Stop Live Event run time : {elapsedTime}");
            }

            // Delete the LiveEvent
            await client.LiveEvents.DeleteAsync(resourceGroup, accountName, liveEventName);
        }
    }
    catch (ErrorResponseException e)
    {
        Console.WriteLine("CleanupLiveEventAndOutputAsync -- Hit ErrorResponseException");
        Console.WriteLine($"\tCode: {e.Body.Error.Code}");
        Console.WriteLine($"\tCode: {e.Body.Error.Message}");
        Console.WriteLine();
    }
}
private static async Task CleanupLocatorandAssetAsync(IAzureMediaServicesClient client, string resourceGroup, string accountName, string streamingLocatorName, string assetName)
{
    try
    {
        // Delete the Streaming Locator
        await client.StreamingLocators.DeleteAsync(resourceGroup, accountName, streamingLocatorName);

        // Delete the Archive Asset
        await client.Assets.DeleteAsync(resourceGroup, accountName, assetName);
    }
    catch (ErrorResponseException e)
    {
        Console.WriteLine("CleanupLocatorandAssetAsync -- Hit ErrorResponseException");
        Console.WriteLine($"\tCode: {e.Body.Error.Code}");
        Console.WriteLine($"\tCode: {e.Body.Error.Message}");
        Console.WriteLine();
    }
}

Regarder l’événement

Appuyez sur Ctrl+F5 pour exécuter le code. Cela génère des URL de flux de sortie que vous pouvez utiliser pour regarder votre événement en direct. Copiez l’URL de diffusion en continu que vous avez obtenu pour créer un localisateur de diffusion en continu. Vous pouvez utiliser le lecteur multimédia de votre choix. Le Lecteur multimédia Azure est disponible pour tester votre flux sur le site de démonstration du Lecteur multimédia.

Une fois arrêté, un événement en direct est automatiquement converti en contenu à la demande. Même après l’arrêt et la suppression de l’événement, les utilisateurs pourront lire votre contenu archivé en tant que vidéo à la demande tant que vous n’aurez pas supprimé l’élément multimédia. Vous ne pouvez pas supprimer un actif multimédia si un événement est en train de l’utiliser. Vous devez d’abord supprimer l’événement.

Nettoyer les ressources restantes

Si vous n’avez plus besoin des ressources de votre groupe de ressources, notamment les comptes de stockage et Media Services que vous avez créés pour ce tutoriel, supprimez le groupe de ressources que vous avez créé.

Exécutez la commande d’interface de ligne de commande ci-dessous :

az group delete --name amsResourceGroup

Important

Le fait de laisser l’événement en direct s’exécuter entraîne des frais. Sachez que si le projet ou le programme cesse de répondre ou est fermé pour une raison quelconque, l’événement en direct peut continuer de s’exécuter et ainsi entraîner des frais.

Poser des questions, envoyer des commentaires, obtenir des mises à jour

Découvrez l’article Communauté Azure Media Services pour découvrir les différentes façons dont vous pouvez poser des questions, faire des commentaires et obtenir des mises à jour sur Media Services.

Étapes suivantes

Diffuser des fichiers