Så här utför du direktsänd strömning med Azure Media Services för att skapa dataströmmar i multibithastighet med .NETHow to perform live streaming using Azure Media Services to create multi-bitrate streams with .NET

Media Services-logotypmedia services logo


Anteckning

Du behöver ett Azure-konto för att genomföra kursen. Mer information om den kostnadsfria utvärderingsversionen av Azure finns Kostnadsfri utvärderingsversion av Azure.

ÖversiktOverview

Den här självstudien visar dig stegen för att skapa en kanal som tar emot en direktsänd dataström med enkel bithastighet och kodar den till en dataström med multibithastighet.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.

Mer konceptinformation relaterad till kanaler som är aktiverade för Live Encoding finns i Direktsänd strömning med Azure Media Services för att skapa dataströmmar i multibithastighet.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.

Vanligt scenario för direktsänd strömningCommon Live Streaming Scenario

Följande steg beskriver uppgifter som ingår i att skapa vanliga program för direktsänd strömning.The following steps describe tasks involved in creating common live streaming applications.

Anteckning

Den rekommenderade maximala längden för en direktsänd händelse är för närvarande 8 timmar.Currently, the max recommended duration of a live event is 8 hours. Kontakta amshelp@microsoft.com om du behöver köra en kanal under en längre tidsperiod.Please contact amshelp@microsoft.com if you need to run a Channel for longer periods of time.

  1. Anslut en videokamera till en dator.Connect a video camera to a computer. Starta och konfigurera en lokal livekodare som kan mata ut en dataström med enkel bithastighet i något av följande protokoll: RTMP eller 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. Mer information finns i Support och direktsända kodare för Azure Media Services RTMP.For more information, see Azure Media Services RTMP Support and Live Encoders.

    Det här steget kan också utföras när du har skapat din kanal.This step could also be performed after you create your Channel.

  2. Skapa och starta en kanal.Create and start a Channel.

  3. Hämta kanalens infognings-URL.Retrieve the Channel ingest URL.

    Infognings-URL:en används av livekodaren för att skicka dataströmmen till kanalen.The ingest URL is used by the live encoder to send the stream to the Channel.

  4. Hämta kanalens förhandsgransknings-URL.Retrieve the Channel preview URL.

    Använd denna URL för att kontrollera att din kanal tar emot den direktsända dataströmmen korrekt.Use this URL to verify that your channel is properly receiving the live stream.

  5. Skapa en tillgång.Create an asset.

  6. Om du vill att tillgången ska vara dynamiskt krypterad under uppspelningen gör du följande:If you want for the asset to be dynamically encrypted during playback, do the following:

  7. Skapa en innehållsnyckel.Create a content key.

  8. Konfigurera en auktoriseringsprincip för innehållsnyckeln.Configure the content key's authorization policy.

  9. Konfigurera en princip för tillgångsleveranser (används av dynamisk paketering och dynamisk kryptering).Configure asset delivery policy (used by dynamic packaging and dynamic encryption).

  10. Skapa ett program och ange att den tillgång som du skapade ska användas.Create a program and specify to use the asset that you created.

  11. Publicera tillgången som är associerad till programmet genom att skapa en OnDemand-positionerare.Publish the asset associated with the program by creating an OnDemand locator.

    Anteckning

    När ditt AMS-konto skapas läggs en standard-slutpunkt för direktuppspelning till på ditt konto med tillståndet Stoppad.When your AMS account is created a default streaming endpoint is added to your account in the Stopped state. Slutpunkten för direktuppspelning som du vill spela upp innehåll från måste ha tillståndet Körs.The streaming endpoint from which you want to stream content has to be in the Running state.

  12. Starta programmet när du är redo att påbörja strömning och arkivering.Start the program when you are ready to start streaming and archiving.

  13. Som alternativ kan den direktsända kodaren få signal om att starta en annons.Optionally, the live encoder can be signaled to start an advertisement. Annonsen infogas i utdataströmmen.The advertisement is inserted in the output stream.

  14. Stoppa programmet när du vill stoppa strömningen och arkiveringen av händelsen.Stop the program whenever you want to stop streaming and archiving the event.

  15. Ta bort programmet (och ta eventuellt bort tillgången).Delete the Program (and optionally delete the asset).

Det här lär du digWhat you'll learn

I den här artikeln visas hur du utför olika åtgärder i kanaler och program med hjälp av Media Services .NET SDK.This article shows you how to execute different operations on channels and programs using Media Services .NET SDK. Eftersom många åtgärder är långvariga används .NET-API:er som hanterar långvariga åtgärder.Because many operations are long-running .NET APIs that manage long running operations are used.

Artikeln visar hur du gör följande:The article shows how to do the following:

  1. Skapa och starta en kanal.Create and start a channel. Långvariga API:er används.Long-running APIs are used.
  2. Hämta kanalernas infogningsslutpunkter (indata).Get the channels ingest (input) endpoint. Den här slutpunkten ska tillhandahållas till den kodare som kan skicka en direktsänd dataström med enkel bithastighet.This endpoint should be provided to the encoder that can send a single bitrate live stream.
  3. Hämta förhandsgranskningsslutpunkten.Get the preview endpoint. Den här slutpunkten används för att förhandsgranska dataströmmen.This endpoint is used to preview your stream.
  4. Skapa en tillgång som används för att lagra innehållet.Create an asset that is used to store your content. Principerna för tillgångsleverans ska också konfigureras, så som visas i det här exemplet.The asset delivery policies should be configured as well, as shown in this example.
  5. Skapa ett program och ange att den tillgång som du skapade tidigare ska användas.Create a program and specify to use the asset that was created earlier. Starta programmet.Start the program. Långvariga API:er används.Long-running APIs are used.
  6. Skapa en positionerare för tillgången, så att innehållet publiceras och kan strömmas till dina klienter.Create a locator for the asset, so the content gets published and can be streamed to your clients.
  7. Visa eller dölj pekdatorer.Show and hide slates. Starta och stoppa annonser.Start and stop advertisements. Långvariga API:er används.Long-running APIs are used.
  8. Rensa din kanal och alla associerade resurser.Clean up your channel and all the associated resources.

FörutsättningarPrerequisites

Följande krävs för att kunna genomföra självstudien.The following are required to complete the tutorial.

  • Ett Azure-konto.An Azure account. Om du inte har något konto kan skapa du ett kostnadsfritt utvärderingskonto på bara några minuter.If you don't have an account, you can create a free trial account in just a couple of minutes. Mer information om den kostnadsfria utvärderingsversionen av Azure finns Kostnadsfri utvärderingsversion av Azure.For details, see Azure Free Trial. Du får kredit som kan användas för att prova Azure-tjänster som normalt inte är kostnadsfria.You get credits that can be used to try out paid Azure services. Du kan behålla kontot även efter att krediten är slut och använda gratis Azure-tjänster och -funktioner som Web Apps-funktionen i Azure App Service.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.
  • Ett Media Services-konto.A Media Services account. Mer information om att skapa ett Media Services-konto finns i Skapa konto.To create a Media Services account, see Create Account.
  • Visual Studio 2010 SP1 (Professional, Premium, Ultimate eller Express) eller senare versioner.Visual Studio 2010 SP1 (Professional, Premium, Ultimate, or Express) or later versions.
  • Du måste använda Media Services .NET SDK version 3.2.0.0 eller senare.You must use Media Services .NET SDK version 3.2.0.0 or newer.
  • En webbkamera och en kodare som kan skicka en direktsänd dataström i enkel bithastighet.A webcam and an encoder that can send a single bitrate live stream.

ÖvervägandenConsiderations

  • Den rekommenderade maximala längden för en direktsänd händelse är för närvarande 8 timmar.Currently, the max recommended duration of a live event is 8 hours. Kontakta amshelp@microsoft.com om du behöver köra en kanal under en längre tidsperiod.Please contact amshelp@microsoft.com if you need to run a Channel for longer periods of time.
  • Det finns en gräns på 1 000 000 principer för olika AMS-principer (till exempel för positionerarprincipen eller ContentKeyAuthorizationPolicy).There is a limit of 1,000,000 policies for different AMS policies (for example, for Locator policy or ContentKeyAuthorizationPolicy). Du bör använda samma princip-ID om du alltid använder samma dagar/åtkomstbehörigheter, till exempel principer för positionerare som är avsedda att vara på plats under en längre tid (icke-överföringsprinciper).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). Mer information finns i den här artikeln.For more information, see this article.

Ladda ned exempelDownload sample

Du kan hämta exemplet som beskrivs i artikeln här.You can download the sample that is described in this article from here.

Konfigurera för utveckling med Media Services SDK för .NETSet up for development with Media Services SDK for .NET

Konfigurera utvecklings miljön och fyll i app.config-filen med anslutnings information, enligt beskrivningen i Media Services utveckling med .net.Set up your development environment and populate the app.config file with connection information, as described in Media Services development with .NET.

KodexempelCode 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);
        }
    }
}

Nästa stegNext step

Granska sökvägarna för Media Services-utbildning.Review Media Services learning paths.

Media Services v3 (senaste)Media Services v3 (latest)

Kolla in den senaste versionen av Azure Media Services!Check out the latest version of Azure Media Services!

Media Services v2 (äldre)Media Services v2 (legacy)

Ge feedbackProvide feedback

Använd User Voice-forumet för att ge feedback och förslag på hur Azure Media Services kan förbättras.Use the User Voice forum to provide feedback and make suggestions on how to improve Azure Media Services. Du kan även gå direkt till någon av följande kategorier:You also can go directly to one of the following categories: