Come eseguire lo streaming live con Servizi multimediali di Azure per creare flussi a più bitrate con .NETHow to perform live streaming using Azure Media Services to create multi-bitrate streams with .NET

logo di servizi multimedialimedia services logo


Nota

Per completare l'esercitazione, è necessario un account Azure. Per informazioni dettagliate, vedere la pagina relativa alla versione di valutazione gratuita di Azure.

PanoramicaOverview

Questa esercitazione illustra i passaggi per creare un canale che riceve un flusso live a velocità in bit singola e lo codifica in un flusso a più velocità in bit.This tutorial walks you through the steps of creating a Channel that receives a single-bitrate live stream and encodes it to multi-bitrate stream.

Per altre informazioni concettuali sui canali correlati abilitati per la codifica live, vedere Uso di canali abilitati per l'esecuzione della codifica live con Servizi multimediali di Azure.For more conceptual information related to Channels that are enabled for live encoding, see Live streaming using Azure Media Services to create multi-bitrate streams.

Scenario comune di streaming liveCommon Live Streaming Scenario

I seguenti passaggi descrivono le attività relative alla creazione di applicazioni comuni di streaming live.The following steps describe tasks involved in creating common live streaming applications.

Nota

Attualmente, la durata massima consigliata per un evento live è 8 ore.Currently, the max recommended duration of a live event is 8 hours. Se è necessario eseguire un canale per una durata superiore, contattare amshelp@microsoft.com.Please contact amshelp@microsoft.com if you need to run a Channel for longer periods of time.

  1. Connettere una videocamera a un computer.Connect a video camera to a computer. Avviare e configurare un codificatore live locale che può restituire un flusso a bitrate singolo in uno dei protocolli seguenti: RTMP o Smooth Streaming.Launch and configure an on-premises live encoder that can output a single bitrate stream in one of the following protocols: RTMP or Smooth Streaming. Per altre informazioni, vedere l'argomento relativo a codificatori live e supporto RTMP di Servizi multimediali di Azure.For more information, see Azure Media Services RTMP Support and Live Encoders.

    Questa operazione può essere eseguita anche dopo la creazione del canale.This step could also be performed after you create your Channel.

  2. Creare e avviare un canale.Create and start a Channel.

  3. Recuperare l'URL di inserimento del canale.Retrieve the Channel ingest URL.

    L'URL di inserimento viene usato dal codificatore live per inviare il flusso al canale.The ingest URL is used by the live encoder to send the stream to the Channel.

  4. Recuperare l'URL di anteprima del canale.Retrieve the Channel preview URL.

    Usare questo URL per verificare che il canale riceva correttamente il flusso live.Use this URL to verify that your channel is properly receiving the live stream.

  5. Creare un asset.Create an asset.

  6. Se si desidera che l'asset sia crittografato in modo dinamico durante la riproduzione, seguire questa procedura:If you want for the asset to be dynamically encrypted during playback, do the following:

  7. Creare una chiave simmetrica.Create a content key.

  8. Configurare i criteri di autorizzazione della chiave simmetrica.Configure the content key's authorization policy.

  9. Configurare i criteri di distribuzione degli asset (usati per la creazione dinamica dei pacchetti e la crittografia dinamica).Configure asset delivery policy (used by dynamic packaging and dynamic encryption).

  10. Creare un programma e specificare di usare l'asset creato.Create a program and specify to use the asset that you created.

  11. Pubblicare l'asset associato al programma creando un localizzatore OnDemand.Publish the asset associated with the program by creating an OnDemand locator.

    Nota

    Quando l'account AMS viene creato, un endpoint di streaming predefinito viene aggiunto all'account con stato Arrestato.When your AMS account is created a default streaming endpoint is added to your account in the Stopped state. L'endpoint di streaming da cui si vuole trasmettere il contenuto deve essere nello stato In esecuzione.The streaming endpoint from which you want to stream content has to be in the Running state.

  12. Avviare il programma quando si è pronti a iniziare lo streaming e l'archiviazione.Start the program when you are ready to start streaming and archiving.

  13. Facoltativamente, il codificatore live può ricevere il segnale per l'avvio di un annuncio.Optionally, the live encoder can be signaled to start an advertisement. L'annuncio viene inserito nel flusso di output.The advertisement is inserted in the output stream.

  14. Arrestare il programma ogni volta che si vuole interrompere lo streaming e l'archiviazione dell'evento.Stop the program whenever you want to stop streaming and archiving the event.

  15. Eliminare il programma e, facoltativamente, eliminare l'asset.Delete the Program (and optionally delete the asset).

Contenuto dell'esercitazioneWhat you'll learn

Questo articolo illustra come eseguire diverse operazioni su canali e programmi tramite Media Services .NET SDK.This article shows you how to execute different operations on channels and programs using Media Services .NET SDK. Poiché molte operazioni hanno un'esecuzione prolungata, vengono usate API .NET che gestiscono questo tipo di operazioni.Because many operations are long-running .NET APIs that manage long running operations are used.

Questo articolo illustra come eseguire le operazioni seguenti:The article shows how to do the following:

  1. Creare e avviare un canale.Create and start a channel. Vengono usate API con esecuzione prolungata.Long-running APIs are used.
  2. Ottenere l'endpoint di inserimento (input) del canale.Get the channels ingest (input) endpoint. L'endpoint deve essere fornito al codificatore che invia un flusso live a velocità in bit singola.This endpoint should be provided to the encoder that can send a single bitrate live stream.
  3. Ottenere l'endpoint di anteprima.Get the preview endpoint. Questo endpoint viene usato per visualizzare il flusso in anteprima.This endpoint is used to preview your stream.
  4. Creare un asset che viene usato per archiviare il contenuto.Create an asset that is used to store your content. È necessario configurare anche i criteri di distribuzione degli asset, come illustrato in questo esempio.The asset delivery policies should be configured as well, as shown in this example.
  5. Creare un programma e specificare l'uso dell'asset creato in precedenza.Create a program and specify to use the asset that was created earlier. Avvia il programma.Start the program. Vengono usate API con esecuzione prolungata.Long-running APIs are used.
  6. Creare un localizzatore per l'asset in modo che il contenuto venga pubblicato e possa essere trasmesso in streaming ai client.Create a locator for the asset, so the content gets published and can be streamed to your clients.
  7. Mostrare e nascondere slate.Show and hide slates. Avviare e arrestare annunci.Start and stop advertisements. Vengono usate API con esecuzione prolungata.Long-running APIs are used.
  8. Pulire il canale e tutte le risorse associate.Clean up your channel and all the associated resources.

PrerequisitiPrerequisites

Per completare l'esercitazione è necessario quanto segue.The following are required to complete the tutorial.

  • Un account Azure.An Azure account. Se non si dispone di un account Azure, è possibile creare un account di valutazione gratuito in pochi minuti.If you don't have an account, you can create a free trial account in just a couple of minutes. Per informazioni dettagliate, vedere la pagina relativa alla versione di valutazione gratuita di Azure.For details, see Azure Free Trial. sono inclusi crediti da usare per provare i servizi di Azure a pagamento.You get credits that can be used to try out paid Azure services. Una volta esauriti i crediti, è possibile mantenere l'account e usare le funzionalità e i servizi di Azure gratuiti, ad esempio la funzionalità App Web nel servizio app di Azure.Even after the credits are used up, you can keep the account and use free Azure services and features, such as the Web Apps feature in Azure App Service.
  • Account di Servizi multimediali.A Media Services account. Per creare un account di Servizi multimediali, vedere l'argomento relativo alla creazione di un account.To create a Media Services account, see Create Account.
  • Visual Studio 2010 SP1 (Professional, Premium, Ultimate o Express) o versioni successive.Visual Studio 2010 SP1 (Professional, Premium, Ultimate, or Express) or later versions.
  • È necessario usare Media Services .NET SDK versione 3.2.0.0 o successiva.You must use Media Services .NET SDK version 3.2.0.0 or newer.
  • Una webcam e un codificatore in grado di inviare un flusso live a velocità in bit singola.A webcam and an encoder that can send a single bitrate live stream.

ConsiderazioniConsiderations

  • Attualmente, la durata massima consigliata per un evento live è 8 ore.Currently, the max recommended duration of a live event is 8 hours. Se è necessario eseguire un canale per una durata superiore, contattare amshelp@microsoft.com.Please contact amshelp@microsoft.com if you need to run a Channel for longer periods of time.
  • È previsto un limite di 1.000.000 di criteri per i diversi criteri AMS (ad esempio per i criteri Locator o ContentKeyAuthorizationPolicy).There is a limit of 1,000,000 policies for different AMS policies (for example, for Locator policy or ContentKeyAuthorizationPolicy). Usare lo stesso ID criterio se si usano sempre gli stessi giorni/autorizzazioni di accesso, come nel cado di criteri per i localizzatori che devono rimanere attivi per molto tempo (criteri di non caricamento).You should use the same policy ID if you are always using the same days / access permissions, for example, policies for locators that are intended to remain in place for a long time (non-upload policies). Per altre informazioni, vedere questo articolo.For more information, see this article.

Scaricare un esempioDownload sample

È possibile scaricare l'esempio descritto in questo articolo qui.You can download the sample that is described in this article from here.

Configurare lo sviluppo con Media Services SDK per .NETSet up for development with Media Services SDK for .NET

Configurare l'ambiente di sviluppo e popolare il file di app.config con le informazioni di connessione, come descritto in sviluppo di servizi multimediali con .NET.Set up your development environment and populate the app.config file with connection information, as described in Media Services development with .NET.

Esempio di codiceCode example

using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using Microsoft.WindowsAzure.MediaServices.Client;
using Microsoft.WindowsAzure.MediaServices.Client.DynamicEncryption;

namespace EncodeLiveStreamWithAmsClear
{
    class Program
    {
        private const string ChannelName = "channel001";
        private const string AssetName = "asset001";
        private const string ProgramName = "program001";

        // Read values from the App.config file.
        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"];

        private static CloudMediaContext _context = null;

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

            var tokenProvider = new AzureAdTokenProvider(tokenCredentials);

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

            IChannel channel = CreateAndStartChannel();

            // The channel's input endpoint:
            string ingestUrl = channel.Input.Endpoints.FirstOrDefault().Url.ToString();

            Console.WriteLine("Intest URL: {0}", ingestUrl);


            // Use the previewEndpoint to preview and verify 
            // that the input from the encoder is actually reaching the Channel. 
            string previewEndpoint = channel.Preview.Endpoints.FirstOrDefault().Url.ToString();

            Console.WriteLine("Preview URL: {0}", previewEndpoint);

            // When Live Encoding is enabled, you can now get a preview of the live feed as it reaches the Channel. 
            // This can be a valuable tool to check whether your live feed is actually reaching the Channel. 
            // The thumbnail is exposed via the same end-point as the Channel Preview URL.
            string thumbnailUri = new UriBuilder
            {
                Scheme = Uri.UriSchemeHttps,
                Host = channel.Preview.Endpoints.FirstOrDefault().Url.Host,
                Path = "thumbnails/input.jpg"
            }.Uri.ToString();

            Console.WriteLine("Thumbain URL: {0}", thumbnailUri);

            // Once you previewed your stream and verified that it is flowing into your Channel, 
            // you can create an event by creating an Asset, Program, and Streaming Locator. 
            IAsset asset = CreateAndConfigureAsset();

            IProgram program = CreateAndStartProgram(channel, asset);

            ILocator locator = CreateLocatorForAsset(program.Asset, program.ArchiveWindowLength);

            // You can use slates and ads only if the channel type is Standard.  
            StartStopAdsSlates(channel);

            // Once you are done streaming, clean up your resources.
            Cleanup(channel);
        }

        public static IChannel CreateAndStartChannel()
        {
            var channelInput = CreateChannelInput();
            var channelPreview = CreateChannelPreview();
            var channelEncoding = CreateChannelEncoding();

            ChannelCreationOptions options = new ChannelCreationOptions
            {
                EncodingType = ChannelEncodingType.Standard,
                Name = ChannelName,
                Input = channelInput,
                Preview = channelPreview,
                Encoding = channelEncoding
            };

            Log("Creating channel");
            IOperation channelCreateOperation = _context.Channels.SendCreateOperation(options);
            string channelId = TrackOperation(channelCreateOperation, "Channel create");

            IChannel channel = _context.Channels.FirstOrDefault(c => c.Id == channelId);

            Log("Starting channel");
            var channelStartOperation = channel.SendStartOperation();
            TrackOperation(channelStartOperation, "Channel start");

            return channel;
        }

        /// <summary>
        /// Create channel input, used in channel creation options. 
        /// </summary>
        /// <returns></returns>
        private static ChannelInput CreateChannelInput()
        {
            // When creating a Channel, you can specify allowed IP addresses in one of the following formats: 
            // IpV4 address with 4 numbers
            // CIDR address range

            return new ChannelInput
            {
                StreamingProtocol = StreamingProtocol.FragmentedMP4,
                AccessControl = new ChannelAccessControl
                {
                    IPAllowList = new List<IPRange>
                    {
                        new IPRange
                        {
                        Name = "TestChannelInput001",
                        Address = IPAddress.Parse("0.0.0.0"),
                        SubnetPrefixLength = 0
                        }
                    }
                }
            };
        }

        /// <summary>
        /// Create channel preview, used in channel creation options. 
        /// </summary>
        /// <returns></returns>
        private static ChannelPreview CreateChannelPreview()
        {
            // When creating a Channel, you can specify allowed IP addresses in one of the following formats: 
            // IpV4 address with 4 numbers
            // CIDR address range

            return new ChannelPreview
            {
                AccessControl = new ChannelAccessControl
                {
                    IPAllowList = new List<IPRange>
                {
                    new IPRange
                    {
                    Name = "TestChannelPreview001",
                    Address = IPAddress.Parse("0.0.0.0"),
                    SubnetPrefixLength = 0
                    }
                }
                }
            };
        }

        /// <summary>
        /// Create channel encoding, used in channel creation options. 
        /// </summary>
        /// <returns></returns>
        private static ChannelEncoding CreateChannelEncoding()
        {
            return new ChannelEncoding
            {
                SystemPreset = "Default720p",
                IgnoreCea708ClosedCaptions = false,
                AdMarkerSource = AdMarkerSource.Api
            };
        }

        /// <summary>
        /// Create an asset and configure asset delivery policies.
        /// </summary>
        /// <returns></returns>
        public static IAsset CreateAndConfigureAsset()
        {
            IAsset asset = _context.Assets.Create(AssetName, AssetCreationOptions.None);

            IAssetDeliveryPolicy policy =
            _context.AssetDeliveryPolicies.Create("Clear Policy",
            AssetDeliveryPolicyType.NoDynamicEncryption,
            AssetDeliveryProtocol.HLS | AssetDeliveryProtocol.SmoothStreaming | AssetDeliveryProtocol.Dash, null);

            asset.DeliveryPolicies.Add(policy);

            return asset;
        }

        /// <summary>
        /// Create a Program on the Channel. You can have multiple Programs that overlap or are sequential;
        /// however each Program must have a unique name within your Media Services account.
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="asset"></param>
        /// <returns></returns>
        public static IProgram CreateAndStartProgram(IChannel channel, IAsset asset)
        {
            IProgram program = channel.Programs.Create(ProgramName, TimeSpan.FromHours(3), asset.Id);
            Log("Program created", program.Id);

            Log("Starting program");
            var programStartOperation = program.SendStartOperation();
            TrackOperation(programStartOperation, "Program start");

            return program;
        }

        /// <summary>
        /// Create locators in order to be able to publish and stream the video.
        /// </summary>
        /// <param name="asset"></param>
        /// <param name="ArchiveWindowLength"></param>
        /// <returns></returns>
        public static ILocator CreateLocatorForAsset(IAsset asset, TimeSpan ArchiveWindowLength)
        {
            // You cannot create a streaming locator using an AccessPolicy that includes write or delete permissions.            
            var locator = _context.Locators.CreateLocator
            (
                LocatorType.OnDemandOrigin,
                asset,
                _context.AccessPolicies.Create
                (
                    "Live Stream Policy",
                    ArchiveWindowLength,
                    AccessPermissions.Read
                )
            );

            return locator;
        }

        /// <summary>
        /// Perform operations on slates.
        /// </summary>
        /// <param name="channel"></param>
        public static void StartStopAdsSlates(IChannel channel)
        {
            int cueId = new Random().Next(int.MaxValue);
            var path = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\\..\\SlateJPG\\DefaultAzurePortalSlate.jpg"));

            Log("Creating asset");
            var slateAsset = _context.Assets.Create("Slate test asset " + DateTime.Now.ToString("yyyy-MM-dd HH-mm"), AssetCreationOptions.None);
            Log("Slate asset created", slateAsset.Id);

            Log("Uploading file");
            var assetFile = slateAsset.AssetFiles.Create("DefaultAzurePortalSlate.jpg");
            assetFile.Upload(path);
            assetFile.IsPrimary = true;
            assetFile.Update();

            Log("Showing slate");
            var showSlateOperation = channel.SendShowSlateOperation(TimeSpan.FromMinutes(1), slateAsset.Id);
            TrackOperation(showSlateOperation, "Show slate");

            Log("Hiding slate");
            var hideSlateOperation = channel.SendHideSlateOperation();
            TrackOperation(hideSlateOperation, "Hide slate");

            Log("Starting ad");
            var startAdOperation = channel.SendStartAdvertisementOperation(TimeSpan.FromMinutes(1), cueId, false);
            TrackOperation(startAdOperation, "Start ad");

            Log("Ending ad");
            var endAdOperation = channel.SendEndAdvertisementOperation(cueId);
            TrackOperation(endAdOperation, "End ad");

            Log("Deleting slate asset");
            slateAsset.Delete();
        }

        /// <summary>
        /// Clean up resources associated with the channel.
        /// </summary>
        /// <param name="channel"></param>
        public static void Cleanup(IChannel channel)
        {
            IAsset asset;
            if (channel != null)
            {
                foreach (var program in channel.Programs)
                {
                    asset = _context.Assets.FirstOrDefault(se => se.Id == program.AssetId);

                    Log("Stopping program");
                    var programStopOperation = program.SendStopOperation();
                    TrackOperation(programStopOperation, "Program stop");

                    program.Delete();

                    if (asset != null)
                    {
                        Log("Deleting locators");
                        foreach (var l in asset.Locators)
                            l.Delete();

                        Log("Deleting asset");
                        asset.Delete();
                    }
                }

                Log("Stopping channel");
                var channelStopOperation = channel.SendStopOperation();
                TrackOperation(channelStopOperation, "Channel stop");

                Log("Deleting channel");
                var channelDeleteOperation = channel.SendDeleteOperation();
                TrackOperation(channelDeleteOperation, "Channel delete");
            }
        }

        /// <summary>
        /// Track long running operations.
        /// </summary>
        /// <param name="operation"></param>
        /// <param name="description"></param>
        /// <returns></returns>
        public static string TrackOperation(IOperation operation, string description)
        {
            string entityId = null;
            bool isCompleted = false;

            Log("starting to track ", null, operation.Id);
            while (isCompleted == false)
            {
                operation = _context.Operations.GetOperation(operation.Id);
                isCompleted = IsCompleted(operation, out entityId);
                System.Threading.Thread.Sleep(TimeSpan.FromSeconds(30));
            }
            // If we got here, the operation succeeded.
            Log(description + " in completed", operation.TargetEntityId, operation.Id);

            return entityId;
        }

        /// <summary> 
        /// Checks if the operation has been completed. 
        /// If the operation succeeded, the created entity Id is returned in the out parameter.
        /// </summary> 
        /// <param name="operationId">The operation Id.</param> 
        /// <param name="channel">
        /// If the operation succeeded, 
        /// the entity Id associated with the successful operation is returned in the out parameter.</param>
        /// <returns>Returns false if the operation is still in progress; otherwise, true.</returns> 
        private static bool IsCompleted(IOperation operation, out string entityId)
        {
            bool completed = false;

            entityId = null;

            switch (operation.State)
            {
                case OperationState.Failed:
                    // Handle the failure. 
                    // For example, throw an exception. 
                    // Use the following information in the exception: operationId, operation.ErrorMessage.
                    Log("operation failed", operation.TargetEntityId, operation.Id);
                    break;
                case OperationState.Succeeded:
                    completed = true;
                    entityId = operation.TargetEntityId;
                    break;
                case OperationState.InProgress:
                    completed = false;
                    Log("operation in progress", operation.TargetEntityId, operation.Id);
                    break;
            }
            return completed;
        }

        private static void Log(string action, string entityId = null, string operationId = null)
        {
            Console.WriteLine(
            "{0,-21}{1,-51}{2,-51}{3,-51}",
            DateTime.Now.ToString("yyyy'-'MM'-'dd HH':'mm':'ss"),
            action,
            entityId ?? string.Empty,
            operationId ?? string.Empty);
        }
    }
}

Passaggio successivoNext step

Analizzare i percorsi di apprendimento di Servizi multimediali.Review Media Services learning paths.

Servizi multimediali v3 (versione più recente)Media Services v3 (latest)

Scopri la versione più recente di servizi multimediali di Azure.Check out the latest version of Azure Media Services!

Servizi multimediali v2 (legacy)Media Services v2 (legacy)

Fornire commenti e suggerimentiProvide feedback

Usare il forum di suggerimenti degli utenti per fornire commenti e suggerimenti su come migliorare Servizi multimediali di Azure.Use the User Voice forum to provide feedback and make suggestions on how to improve Azure Media Services. È anche possibile passare direttamente a una delle categorie seguenti:You also can go directly to one of the following categories: