Zelfstudie: Video's uploaden, coderen en streamen met Media Services v3

media services logo v3


Zoekt u Media Services v2-documentatie?

Notitie

Hoewel in deze zelfstudie .NET SDK-voorbeelden worden gebruikt, zijn de algemene stappen hetzelfde voor REST API-, de CLI- of andere ondersteunde SDK's.

Met Azure Media Services kunt u mediabestanden coderen in indelingen die kunnen worden afgespeeld met een groot aantal verschillende browsers en apparaten. Zo kunt u bijvoorbeeld inhoud streamen in de indelingen Apple HLS of MPEG DASH. Voordat u gaat streamen, moet u uw digitale mediabestand van hoge kwaliteit coderen. Zie Het concept codering voor hulp bij het coderen. In deze zelfstudie wordt een lokaal videobestand geüpload en wordt het geüploade bestand gecodeerd. U kunt ook inhoud coderen die u toegankelijk maakt via een HTTPS-URL. Zie Taakinvoer maken via een HTTP(s)-URL voor meer informatie.

Een video afspelen met Azure Media Player

In deze zelfstudie ontdekt u hoe u:

  • Download de voorbeeld-app, zoals beschreven in het onderwerp.
  • Onderzoek de code die het uploaden, coderen en streamen regelt.
  • Voer de app uit.
  • Test de streaming-URL.
  • Resources opschonen.

Als u geen Azure-abonnement hebt, maakt u een gratis account voordat u begint.

Vereisten

Het voorbeeld downloaden en configureren

Gebruik de volgende opdracht om een GitHub-opslagplaats met het .NET-voorbeeld voor het streamen van video op uw computer te klonen:

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

Het voorbeeld bevindt zich de map UploadEncodeAndStreamFiles.

Open appsettings.json in het project dat u hebt gedownload. Vervang de waarden door referenties die u hebt verkregen via toegang tot API's.

Notitie

U kunt ook de bestandsindeling .env in de hoofdmap van het project gebruiken om uw omgevingsvariabelen slechts één keer in te stellen voor alle projecten in de opslagplaats met .NET-voorbeelden. Kopieer het bestand sample.env en vul vervolgens de gegevens in die u hebt ontvangen van de Media Services API-toegangspagina in het Azure Portal of de Azure CLI. Wijzig de naam van het bestand sample.env in alleen .env om het in alle projecten te gebruiken.

Het bestand .gitignore is al geconfigureerd om te voorkomen dat dit bestand naar uw gevorkte opslagplaats wordt gepubliceerd.

De code controleren die wordt geüpload, gecodeerd en gestreamd

In dit gedeelte worden de functies bekeken die zijn gedefinieerd in het bestand Program.cs van het project UploadEncodeAndStreamFiles.

In het voorbeeld worden de volgende acties uitgevoerd:

  1. Er wordt een nieuwe transformatie gemaakt (eerst wordt gecontroleerd of de opgegeven transformatie bestaat).
  2. Er wordt een uitvoerasset gemaakt die wordt gebruikt als uitvoer van de coderingstaak.
  3. Er wordt een invoer asset gemaakt en het opgegeven lokale videobestand wordt erin geladen. De asset wordt gebruikt als de invoer voor de taak.
  4. De coderingstaak wordt met behulp van de gemaakte invoer en uitvoer verzonden.
  5. De status van de taak controleren.
  6. Er wordt een streaming-locator gemaakt.
  7. Er worden streaming-URL's samengesteld.

Aan de slag Media Services API's met de .NET SDK

Als u Media Services api's wilt gebruiken met .NET, moet u een AzureMediaServicesClient -object maken. Als u het object wilt maken, moet u referenties voor de client leveren om verbinding te maken met Azure met behulp van Azure Active Directory. Een andere optie is het gebruik van interactieve verificatie, die is geïmplementeerd in 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,
    };
}

In de code die u aan het begin van het artikel hebt gekloond, maakt de functie het object op basis van de referenties die zijn opgegeven in het lokale configuratiebestand (appsettings.jsop ) of via het GetCredentialsAsync ServiceClientCredentials bestand met omgevingsvariabelen .env in ** de hoofdmap van de opslagplaats.

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

In het geval van interactieve verificatie maakt de functie het object op basis van een interactieve verificatie en de verbindingsparameters die zijn opgegeven in het lokale configuratiebestand (appsettings.jsop ) of via het GetCredentialsInteractiveAuthAsync ServiceClientCredentials bestand met omgevingsvariabelen .env in ** de hoofdmap van de opslagplaats. In dat geval zijn AADCLIENTID en AADSECRET niet nodig in het bestand met configuratie- of omgevingsvariabelen.

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 ex)
    {
        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);
}

Een invoerasset maken en er een lokaal bestand in uploaden

Met de functie CreateInputAsset wordt een nieuwe invoerasset gemaakt en het opgegeven lokale videobestand wordt hierin geladen. Deze asset wordt gebruikt als invoer voor uw coderingstaak. In Media Services v3 kan de invoer voor een taak een asset zijn ofof inhoud die u beschikbaar stelt voor uw Media Services-account via HTTPS-URL's. Zie dit artikel als u wilt weten hoe u een HTTPS-URL kunt coderen.

In Media Services v3 kunt u Azure Storage-API's gebruiken om bestanden te uploaden. Het volgende .NET-fragment laat zien hoe.

De volgende functie voert deze acties uit:

  • Er wordt een asset gemaakt.

  • Er wordt een beschrijfbare SAS-URL opgehaald voor de container in opslag van de asset.

    Als u de functie ListContainerSas van de asset gebruikt om SAS-URL's op te halen, moet u er rekening mee houden dat met deze functie meerdere SAS-URL's worden geretourneerd, aangezien er voor elk opslagaccount twee opslagaccountsleutels zijn. Een opslagaccount heeft twee sleutels omdat dit naadloze rotatie van opslagaccountsleutels mogelijk maakt (bijvoorbeeld als u een van de sleutels wilt wijzigen terwijl u de andere gebruikt en vervolgens de nieuwe sleutel wilt gebruiken en de andere roteert). De eerste SAS-URL staat voor opslagsleutel 1 en een tweede voor opslagsleutel 2.

  • Uploadt het bestand naar de container in opslag met behulp van de SAS-URL.

private static async Task<Asset> CreateInputAssetAsync(
    IAzureMediaServicesClient client,
    string resourceGroupName,
    string accountName,
    string assetName,
    string fileToUpload)
{
    // In this example, we are assuming that the asset name is unique.
    //
    // If you already have an asset with the desired name, use the Assets.Get method
    // to get the existing asset. In Media Services v3, the Get method on entities returns null 
    // if the entity doesn't exist (a case-insensitive check on the name).

    // Call Media Services API to create an Asset.
    // This method creates a container in storage for the Asset.
    // The files (blobs) associated with the asset will be stored in this container.
    Asset asset = await client.Assets.CreateOrUpdateAsync(resourceGroupName, accountName, assetName, new Asset());

    // Use Media Services API to get back a response that contains
    // SAS URL for the Asset container into which to upload blobs.
    // That is where you would specify read-write permissions 
    // and the exparation time for the SAS URL.
    var response = await client.Assets.ListContainerSasAsync(
        resourceGroupName,
        accountName,
        assetName,
        permissions: AssetContainerPermission.ReadWrite,
        expiryTime: DateTime.UtcNow.AddHours(4).ToUniversalTime());

    var sasUri = new Uri(response.AssetContainerSasUrls.First());

    // Use Storage API to get a reference to the Asset container
    // that was created by calling Asset's CreateOrUpdate method.  
    BlobContainerClient container = new BlobContainerClient(sasUri);
    BlobClient blob = container.GetBlobClient(Path.GetFileName(fileToUpload));

    // Use Strorage API to upload the file into the container in storage.
    await blob.UploadAsync(fileToUpload);

    return asset;
}

Een uitvoerasset maken voor het opslaan van het resultaat van een taak

In de uitvoerasset wordt het resultaat van de coderingstaak opgeslagen. Het project definieert de functie DownloadResults die de resultaten van deze uitvoerasset naar de uitvoermap downloadt zodat u kunt zien wat u hebt gekregen.

private static async Task<Asset> CreateOutputAssetAsync(IAzureMediaServicesClient client, string resourceGroupName, string accountName, string assetName)
{
    // Check if an Asset already exists
    Asset outputAsset = await client.Assets.GetAsync(resourceGroupName, accountName, assetName);
    Asset asset = new Asset();
    string outputAssetName = assetName;

    if (outputAsset != null)
    {
        // Name collision! In order to get the sample to work, let's just go ahead and create a unique asset name
        // Note that the returned Asset can have a different name than the one specified as an input parameter.
        // You may want to update this part to throw an Exception instead, and handle name collisions differently.
        string uniqueness = $"-{Guid.NewGuid():N}";
        outputAssetName += uniqueness;

        Console.WriteLine("Warning – found an existing Asset with name = " + assetName);
        Console.WriteLine("Creating an Asset with this name instead: " + outputAssetName);
    }

    return await client.Assets.CreateOrUpdateAsync(resourceGroupName, accountName, outputAssetName, asset);
}

Een transformatie en een taak maken die het geüploade bestand codeert

Bij het coderen of verwerken van inhoud in Media Services is het gebruikelijk om de coderingsinstellingen als recept in te stellen. U dient vervolgens een taak in te dienen om het recept toe te passen op een video. Door voor elke nieuwe video nieuwe taken in te dienen, past u het recept toe op alle video's in de bibliotheek. Een recept in Media Services wordt een transformatie genoemd. Zie Transformaties en taken voor meer informatie. Het voorbeeld dat wordt beschreven in deze zelfstudie definieert een recept dat de video codeert om het te streamen naar tal van iOS- en Android-apparaten.

Transformeren

Bij het maken van een nieuw transformatie-exemplaar, moet u opgeven wat u als uitvoer wilt maken. De vereiste parameter is een TransformOutput-object, zoals weergegeven in de onderstaande code. Elke transformatie-uitvoer bevat een voorinstelling. Voorinstelling bevat de stapsgewijze instructies van de video- en/of audioverwerkingen die moeten worden gebruikt voor het genereren van de gewenste TransformOutput. Het voorbeeld dat in dit artikel wordt beschreven, maakt gebruik van een ingebouwde voorinstelling genaamd AdaptiveStreaming . De voorinstelling codeert de invoervideo in een automatisch gegenereerde bitrate-ladder (bitrate-resolutieparen) op basis van de invoerresolutie en bitsnelheid en produceert ISO MP4-bestanden met H.264-video en AAC-audio die overeenkomen met elk bitrate-resolutiepaar. Zie een bitrate-ladder automatisch genereren voor meer informatie over deze voorinstelling.

U kunt een ingebouwde EncoderNamedPreset gebruiken of aangepaste voorinstellingen gebruiken. Zie Coderingsvoorinstellingen aanpassen voor meer informatie.

Bij het maken van een transformatie moet u controleren of er al een bestaat met de methode Ophalen zoals weergegeven in de volgende code. In Media Services-v3 retourneert de methode Ophalen van entiteiten null als de entiteit (een hoofdlettergevoelige controle van de naam).

private static async Task<Transform> GetOrCreateTransformAsync(
    IAzureMediaServicesClient client,
    string resourceGroupName,
    string accountName,
    string transformName)
{
    // Does a Transform already exist with the desired name? Assume that an existing Transform with the desired name
    // also uses the same recipe or Preset for processing content.
    Transform transform = await client.Transforms.GetAsync(resourceGroupName, accountName, transformName);

    if (transform == null)
    {
        // You need to specify what you want it to produce as an output
        TransformOutput[] output = new TransformOutput[]
        {
            new TransformOutput
            {
                // The preset for the Transform is set to one of Media Services built-in sample presets.
                // You can  customize the encoding settings by changing this to use "StandardEncoderPreset" class.
                Preset = new BuiltInStandardEncoderPreset()
                {
                    // This sample uses the built-in encoding preset for Adaptive Bitrate Streaming.
                    PresetName = EncoderNamedPreset.AdaptiveStreaming
                }
            }
        };

        // Create the Transform with the output defined above
        transform = await client.Transforms.CreateOrUpdateAsync(resourceGroupName, accountName, transformName, output);
    }

    return transform;
}

Taak

Zoals eerder vermeld, is het transformatie-object het recept en is de taak de werkelijke aanvraag bij Media Services om deze transformatie toe te passen op een bepaalde invoervideo of audio-inhoud. De taak bevat informatie zoals de locatie van de invoervideo en de locatie voor de uitvoer.

In dit voorbeeld is de invoervideo geüpload naar uw lokale machine. Zie dit artikel voor meer informatie over het coderen van een HTTPS-URL.

private static async Task<Job> SubmitJobAsync(IAzureMediaServicesClient client,
    string resourceGroupName,
    string accountName,
    string transformName,
    string jobName,
    string inputAssetName,
    string outputAssetName)
{
    // Use the name of the created input asset to create the job input.
    JobInput jobInput = new JobInputAsset(assetName: inputAssetName);

    JobOutput[] jobOutputs =
    {
        new JobOutputAsset(outputAssetName),
    };

    // In this example, we are assuming that the job name is unique.
    //
    // If you already have a job with the desired name, use the Jobs.Get method
    // to get the existing job. In Media Services v3, the Get method on entities returns null 
    // if the entity doesn't exist (a case-insensitive check on the name).
    Job job = await client.Jobs.CreateAsync(
        resourceGroupName,
        accountName,
        transformName,
        jobName,
        new Job
        {
            Input = jobInput,
            Outputs = jobOutputs,
        });

    return job;
}

Wacht tot de taak is voltooid

De taak neemt enige tijd in beslag en wanneer deze is voltooid, wordt u hiervan op de hoogte gesteld. In het onderstaande codevoorbeeld ziet u hoe de status van de taak kan worden opgevraagd in de service. Navragen is geen aanbevolen best practice voor productie-apps vanwege mogelijke latentie. Polling kan worden beperkt bij een te intensief gebruik op een account. Ontwikkelaars moeten in plaats daarvan Event Grid gebruiken.

Event Grid is ontworpen voor hoge beschikbaarheid, consistente prestaties en dynamisch schalen. Met Event Grid kunnen uw apps luisteren naar en reageren op gebeurtenissen uit vrijwel alle Azure-services, evenals aangepaste bronnen. Eenvoudige, op HTTP gebaseerde reactieve gebeurtenisafhandeling maakt het mogelijk om efficiënte oplossingen te bouwen met intelligente filtering en routering van gebeurtenissen. Zie Gebeurtenissen routeren naar een aangepast eindpunt.

De taak doorloopt meestal de volgende statussen: Gepland, In de wachtrij geplaatst, Verwerken, Voltooid (de eindstatus). Als bij de taak een fout is opgetreden is, krijgt u de status Fout. Als de taak momenteel wordt geannuleerd, krijgt u de meldingen Wordt geannuleerd en Geannuleerd wanneer het annuleren is voltooid.

private static async Task<Job> WaitForJobToFinishAsync(IAzureMediaServicesClient client,
    string resourceGroupName,
    string accountName,
    string transformName,
    string jobName)
{
    const int SleepIntervalMs = 20 * 1000;

    Job job;
    do
    {
        job = await client.Jobs.GetAsync(resourceGroupName, accountName, transformName, jobName);

        Console.WriteLine($"Job is '{job.State}'.");
        for (int i = 0; i < job.Outputs.Count; i++)
        {
            JobOutput output = job.Outputs[i];
            Console.Write($"\tJobOutput[{i}] is '{output.State}'.");
            if (output.State == JobState.Processing)
            {
                Console.Write($"  Progress (%): '{output.Progress}'.");
            }

            Console.WriteLine();
        }

        if (job.State != JobState.Finished && job.State != JobState.Error && job.State != JobState.Canceled)
        {
            await Task.Delay(SleepIntervalMs);
        }
    }
    while (job.State != JobState.Finished && job.State != JobState.Error && job.State != JobState.Canceled);

    return job;
}

Foutcodes in taak

Zie Foutcodes.

Een streaming-locator ophalen

Nadat de codering is voltooid, bestaat de volgende stap eruit om de video in de uitvoerasset beschikbaar te maken voor weergave door clients. U kunt het in twee stappen beschikbaar maken: maak eerst een streaming-locator en bouw vervolgens de streaming-URL's die de clients kunnen gebruiken.

Het proces van het maken van een streaming-locator wordt publiceren genoemd. Nadat u de API-aanroepen hebt uitgevoerd, is de streaming-locator standaard onmiddellijk geldig totdat deze wordt verwijderd, tenzij u de optionele start- en eindtijden configureert.

Bij het maken van een StreamingLocator moet u de gewenste StreamingPolicyName opgeven. In dit voorbeeld gaat u in-the-clear (of niet-versleutelde) inhoud streamen, zodat het vooraf gedefinieerde, duidelijke streamingbeleid, PredefinedStreamingPolicy.ClearStreamingOnly, wordt gebruikt.

Belangrijk

Wanneer u een aangepast streamingbeleid gebruikt, moet u een beperkte set met dergelijke beleidsregels ontwerpen voor uw Media Service-account, en deze opnieuw gebruiken voor de StreamingLocators wanneer dezelfde versleutelingsopties en protocollen nodig zijn. Uw Media Service-account heeft een quotum voor het aantal streaming-beleidsvermeldingen. U hoeft geen nieuw streaming-beleid te maken voor elke streaming-locator.

Bij de volgende code wordt ervan uitgegaan dat u de functie met een unieke locatorName aanroept.

private static async Task<StreamingLocator> CreateStreamingLocatorAsync(
    IAzureMediaServicesClient client,
    string resourceGroup,
    string accountName,
    string assetName,
    string locatorName)
{
    StreamingLocator locator = await client.StreamingLocators.CreateAsync(
        resourceGroup,
        accountName,
        locatorName,
        new StreamingLocator
        {
            AssetName = assetName,
            StreamingPolicyName = PredefinedStreamingPolicy.ClearStreamingOnly
        });

    return locator;
}

Terwijl in het voorbeeld in dit onderwerp streaming wordt behandeld, kunt u dezelfde aanroep gebruiken om een streaming-locator te maken voor het leveren van video via progressief downloaden.

Streaming-URL's ophalen

Nu de streaming-locator is gemaakt, kunt u de streaming-URL's ophalen, zoals weergegeven in GetStreamingURLs. Als u een URL wilt samenstellen, moet u de hostnaam van het streaming-eindpunt en het pad van de streaming-locator samenvoegen. In dit voorbeeld wordt het standaardstreaming-eindpunt gebruikt. Wanneer u voor het eerst een Media Service-account maakt, wordt dit standaardstreaming-eindpunt gestopt. Daarom moet u Start aanroepen.

Notitie

In deze methode hebt u de locatorName nodig die is gebruikt bij het maken van de streaming-locator voor de uitvoerasset.

private static async Task<IList<string>> GetStreamingUrlsAsync(
    IAzureMediaServicesClient client,
    string resourceGroupName,
    string accountName,
    String locatorName)
{
    const string DefaultStreamingEndpointName = "default";

    IList<string> streamingUrls = new List<string>();

    StreamingEndpoint streamingEndpoint = await client.StreamingEndpoints.GetAsync(resourceGroupName, accountName, DefaultStreamingEndpointName);

    if (streamingEndpoint != null)
    {
        if (streamingEndpoint.ResourceState != StreamingEndpointResourceState.Running)
        {
            await client.StreamingEndpoints.StartAsync(resourceGroupName, accountName, DefaultStreamingEndpointName);
        }
    }

    ListPathsResponse paths = await client.StreamingLocators.ListPathsAsync(resourceGroupName, accountName, locatorName);

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

            Path = path.Paths[0]
        };
        streamingUrls.Add(uriBuilder.ToString());
    }

    return streamingUrls;
}

Resources in uw Media Services-account opschonen

Over het algemeen moet u alles opschonen, behalve objecten die u van plan bent opnieuw te gebruiken (meestal gebruikt u transformaties opnieuw en behoudt u StreamingLocators, enzovoort). Als u wilt dat uw account na het experiment wordt opgeschoond, moet u de resources verwijderen die u niet opnieuw wilt gebruiken. Met het volgende codevoorbeeld worden de taak, de gemaakte assets en het beleid voor inhoudssleutels verwijderd:

private static async Task CleanUpAsync(
   IAzureMediaServicesClient client,
   string resourceGroupName,
   string accountName,
   string transformName,
   string jobName,
   List<string> assetNames,
   string contentKeyPolicyName = null
   )
{
    await client.Jobs.DeleteAsync(resourceGroupName, accountName, transformName, jobName);

    foreach (var assetName in assetNames)
    {
        await client.Assets.DeleteAsync(resourceGroupName, accountName, assetName);
    }

    if (contentKeyPolicyName != null)
    {
        client.ContentKeyPolicies.Delete(resourceGroupName, accountName, contentKeyPolicyName);
    }
}

De voorbeeld-app uitvoeren

  1. Druk op Ctrl+F5 om de app EncodeAndStreamFiles uit te voeren.
  2. Kopieer een van de streaming-URL's van de console.

In dit voorbeeld worden URL's weergegeven die kunnen worden gebruikt om de video met verschillende protocollen af te spelen:

Voorbeelduitvoer met URL's voor streaming-video van Media Services

De streaming-URL testen

In dit artikel gebruiken we Azure Media Player om de stream te testen.

Notitie

Als een speler wordt gehost op een https-site, moet u de URL bijwerken naar 'https'.

  1. Open een browser en ga naar https://aka.ms/azuremediaplayer/.
  2. Plak in het vak URL: een van de streaming-URL's die u hebt verkregen tijdens het uitvoeren van de app.
  3. Selecteer Speler bijwerken.

Azure Media Player kan worden gebruikt voor testdoeleinden, maar mag niet worden gebruikt in een productieomgeving.

Resources opschonen

Als u de resources van de resourcegroep niet meer nodig hebt, met inbegrip van de Media Services en opslagaccounts die u hebt gemaakt voor deze zelfstudie, verwijdert u de resourcegroep die u eerder hebt gemaakt.

Voer de volgende CLI-opdracht uit:

az group delete --name amsResourceGroup

Multithreading

De SDK's van Azure Media Services v3 zijn niet thread-safe. Als u een app met meerdere threads ontwikkelt, moet u per thread een nieuw AzureMediaServicesClient-object genereren en gebruiken.

Vragen stellen, feedback geven, updates ophalen

Ga naar het artikel van de Azure Media Services-community voor verschillende manieren om vragen te stellen, feedback te geven en updates voor Media Services op te halen.

Volgende stappen

Nu u weet hoe u uw video kunt uploaden, coderen en streamen, kunt u doorgaan naar het volgende artikel: