Zelfstudie: Het gebruik van de Digital Rights Management-service voor dynamische versleuteling en licentielevering

media services logo v3


Zoekt u Media Services v2-documentatie?

Notitie

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

U kunt Azure Media Services gebruiken voor het leveren van streams die zijn versleuteld met licenties van Microsoft PlayReady, Google Widevine of Apple FairPlay. Zie Inhoudsbeveiliging met dynamische versleuteling voor een gedetailleerde uitleg.

Media Services voorziet bovendien in een service voor het leveren van licenties van PlayReady, Widevine en FairPlay. Wanneer een gebruiker door DRM beveiligde inhoud aanvraagt, wordt met de speler-app een licentie aangevraagd bij de licentieservice van Media Services. Als de speler-app is geautoriseerd, ontvangt deze een licentie van de licentieservice van Media Services. Een licentie bevat de ontsleutelingssleutel die kan worden gebruikt door de clientspeler om de inhoud te ontsleutelen en te streamen.

Dit artikel is gebaseerd op het voorbeeld waarbij DRM wordt gebruikt voor de versleuteling.

In het voorbeeld in dit artikel wordt het volgende resultaat bereikt:

AMS met DRM beveiligde video in Azure Media Player

In deze zelfstudie ontdekt u hoe u:

  • Een coderingstransformatie kunt maken.
  • De ondertekeningssleutel instellen die wordt gebruik om uw token te verifiëren.
  • Vereisten kunt instellen voor het beleid voor inhoudssleutels.
  • Een StreamingLocator kunt maken met het opgegeven streamingbeleid.
  • Een URL maakt die wordt gebruikt om uw bestand af te spelen.

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

Vereisten

Hieronder wordt aangegeven wat de vereisten zijn om de zelfstudie te voltooien:

De code downloaden en het voorbeeld configureren

Kloon met de volgende opdracht een GitHub-opslagplaats met het volledige .NET-voorbeeld dat in dit artikel wordt beschreven, op de computer:

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

Het voorbeeld 'Versleutelen met DRM' bevindt zich in de map EncryptWithDRM.

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.

Notitie

Met het voorbeeld worden unieke resources gemaakt telkens wanneer u de app uitvoert. Normaal gesproken gebruikt u bestaande resources, zoals transformaties en beleidsregels opnieuw (mits de bestaande resource over de vereiste configuraties beschikt).

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 uitvoeractivum maken

In de uitvoerasset wordt het resultaat van de coderingstaak opgeslagen.

private static async Task<Asset> CreateOutputAssetAsync(IAzureMediaServicesClient client, string resourceGroupName, string accountName, string assetName)
{
    bool existingAsset = true;
    Asset outputAsset;
    try
    {
        // Check if an Asset already exists
        outputAsset = await client.Assets.GetAsync(resourceGroupName, accountName, assetName);
    }
    catch (ErrorResponseException ex) when (ex.Response.StatusCode == System.Net.HttpStatusCode.NotFound)
    {
        existingAsset = false;
    }

    Asset asset = new Asset();
    string outputAssetName = assetName;

    if (existingAsset)
    {
        // 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 coderingstransformatie verkrijgen of maken

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.

Voordat u een nieuwe transformatie gaat maken, moet u eerst controleren of er al een bestaat. Dit doet u 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)
{
    bool createTransform = false;
    Transform transform = null;
    try
    {
        // 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 = client.Transforms.Get(resourceGroupName, accountName, transformName);
    }
    catch (ErrorResponseException ex) when (ex.Response.StatusCode == System.Net.HttpStatusCode.NotFound)
    {
        createTransform = true;
    }

    if (createTransform)
    {
        // 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 indienen

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 deze zelfstudie maakt u invoer voor de taak op basis van een bestand dat rechtstreeks vanuit een HTTPs bron-URL is opgenomen.

private static async Task<Job> SubmitJobAsync(IAzureMediaServicesClient client,
    string resourceGroup,
    string accountName,
    string transformName,
    string outputAssetName,
    string jobName)
{
    // This example shows how to encode from any HTTPs source URL - a new feature of the v3 API.  
    // Change the URL to any accessible HTTPs URL or SAS URL from Azure.
    JobInputHttp jobInput =
        new JobInputHttp(files: new[] { SourceUri });

    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(
        resourceGroup,
        accountName,
        transformName,
        jobName,
        new Job
        {
            Input = jobInput,
            Outputs = jobOutputs,
        });

    return job;
}

Wacht tot de taak is voltooid

Het duurt even voordat de taak is voltooid. Wanneer dit is gebeurd, wilt u daarover een melding ontvangen. 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. 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, 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;
}

Beleid voor inhoudssleutels maken

Een inhoudssleutel biedt veilige toegang tot uw assets. U moet een beleid voor inhoudssleutels maken wanneer u uw inhoud versleutelt met een DRM. Het beleid configureert hoe de inhoudssleutel wordt geleverd aan eindclients. De inhoudssleutel is gekoppeld aan een StreamingLocator. Media Services verzorgt ook de sleutelleveringsservice waarmee versleutelingssleutels en -licenties aan gemachtigde gebruikers worden geleverd.

U moet de vereisten (beperkingen) instellen voor inhoudssleutelbeleid waaraan moet worden voldaan voor het leveren van sleutels met de opgegeven configuratie. In dit voorbeeld worden de volgende configuraties en vereisten ingesteld:

  • Configuratie

    De licenties van PlayReady en Widevine zijn geconfigureerd om te kunnen worden geleverd door de Media Services-service voor het leveren van licenties. Hoewel met deze voorbeeld-app de licentie van FairPlay niet wordt geconfigureerd, bevat deze een methode waarmee u FairPlay kunt configureren. U kunt het configureren van FairPlay als een andere optie toevoegen.

  • Beperking

    Door de app wordt voor het beleid een beperking voor tokens van het type JWT (JSON Web Token) ingesteld.

Wanneer een stream wordt aangevraagd door een speler, maakt Media Services gebruik van de opgegeven sleutel om uw inhoud dynamisch te versleutelen. Voor het ontsleutelen van de stream, wordt door de speler de sleutel van de sleutelleveringsservice aangevraagd. De service evalueert het door u opgegeven beleid voor de inhoudssleutel om te bepalen of de gebruiker is gemachtigd om de sleutel op te halen.

private static async Task<ContentKeyPolicy> GetOrCreateContentKeyPolicyAsync(
    IAzureMediaServicesClient client,
    string resourceGroupName,
    string accountName,
    string contentKeyPolicyName,
    byte[] tokenSigningKey)
{
    bool createPolicy = false;
    ContentKeyPolicy policy = null;
    try
    {
        policy = await client.ContentKeyPolicies.GetAsync(resourceGroupName, accountName, contentKeyPolicyName);
    }
    catch (ErrorResponseException ex) when (ex.Response.StatusCode == System.Net.HttpStatusCode.NotFound)
    {
        createPolicy = true;
    }

    if (createPolicy)
    {
        ContentKeyPolicySymmetricTokenKey primaryKey = new ContentKeyPolicySymmetricTokenKey(tokenSigningKey);
        List<ContentKeyPolicyTokenClaim> requiredClaims = new List<ContentKeyPolicyTokenClaim>()
        {
            ContentKeyPolicyTokenClaim.ContentKeyIdentifierClaim
        };
        List<ContentKeyPolicyRestrictionTokenKey> alternateKeys = null;
        ContentKeyPolicyTokenRestriction restriction
            = new ContentKeyPolicyTokenRestriction(Issuer, Audience, primaryKey, ContentKeyPolicyRestrictionTokenType.Jwt, alternateKeys, requiredClaims);

        ContentKeyPolicyPlayReadyConfiguration playReadyConfig = ConfigurePlayReadyLicenseTemplate();
        ContentKeyPolicyWidevineConfiguration widevineConfig = ConfigureWidevineLicenseTemplate();
        // ContentKeyPolicyFairPlayConfiguration fairplayConfig = ConfigureFairPlayPolicyOptions();

        List<ContentKeyPolicyOption> options = new List<ContentKeyPolicyOption>();

        options.Add(
            new ContentKeyPolicyOption()
            {
                Configuration = playReadyConfig,
                // If you want to set an open restriction, use
                // Restriction = new ContentKeyPolicyOpenRestriction()
                Restriction = restriction
            });

        options.Add(
            new ContentKeyPolicyOption()
            {
                Configuration = widevineConfig,
                Restriction = restriction
            });

        // add CBCS ContentKeyPolicyOption into the list
        //   options.Add(
        //       new ContentKeyPolicyOption()
        //       {
        //           Configuration = fairplayConfig,
        //           Restriction = restriction,
        //           Name = "ContentKeyPolicyOption_CBCS"
        //       });

        policy = await client.ContentKeyPolicies.CreateOrUpdateAsync(resourceGroupName, accountName, contentKeyPolicyName, options);
    }
    else
    {
        // Get the signing key from the existing policy.
        var policyProperties = await client.ContentKeyPolicies.GetPolicyPropertiesWithSecretsAsync(resourceGroupName, accountName, contentKeyPolicyName);
        if (policyProperties.Options[0].Restriction is ContentKeyPolicyTokenRestriction restriction)
        {
            if (restriction.PrimaryVerificationKey is ContentKeyPolicySymmetricTokenKey signingKey)
            {
                TokenSigningKey = signingKey.KeyValue;
            }
        }
    }
    return policy;
}

Een streaming-locator maken

Nadat de codering is voltooid en het inhoudssleutelbeleid is ingesteld, bestaat de volgende stap eruit om de video in de uitvoerasset beschikbaar te maken voor weergave door clients. U maakt de video in twee stappen beschikbaar:

  1. Een streaminglocator maken.
  2. De streaming-URL's bouwen die clients kunnen gebruiken.

Het proces voor het maken van de streaminglocator wordt publiceren genoemd. Standaard is de streaminglocator direct geldig nadat u de API-aanroepen hebt gemaakt. De streaminglocator blijft geldig totdat deze wordt verwijderd, tenzij u de optionele begin- en eindtijden configureert.

Bij het maken van een streaminglocator moet u de gewenste StreamingPolicyName opgeven. In deze zelfstudie gebruiken we een vooraf gedefinieerd Streaming-beleid. Dit wordt door Azure Media Services gebruikt om te bepalen hoe de inhoud voor streaming moet worden gepubliceerd. In dit voorbeeld stellen we StreamingLocator.StreamingPolicyName in op het beleid Predefined_MultiDrmCencStreaming. Er worden dan PlayReady- en Widevine-versleutelingen toegepast, en de sleutel wordt aan de afspeelclient geleverd op basis van de geconfigureerde DRM-licenties. Als u wilt dat uw stream ook met CBCS (FairPlay) wordt versleuteld, gebruikt u Predefined_MultiDrmStreaming.

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 StreamingPolicy-vermeldingen. U dient geen nieuw StreamingPolicy voor elke StreamingLocator te maken.

private static async Task<StreamingLocator> CreateStreamingLocatorAsync(
    IAzureMediaServicesClient client,
    string resourceGroup,
    string accountName,
    string assetName,
    string locatorName,
    string contentPolicyName)
{
    // If you also added FairPlay, use "Predefined_MultiDrmStreaming
    StreamingLocator locator = await client.StreamingLocators.CreateAsync(
        resourceGroup,
        accountName,
        locatorName,
        new StreamingLocator
        {
            AssetName = assetName,
            // "Predefined_MultiDrmCencStreaming" policy supports envelope and cenc encryption
            // And sets two content keys on the StreamingLocator
            StreamingPolicyName = "Predefined_MultiDrmCencStreaming",
            DefaultContentKeyPolicyName = contentPolicyName
        });

    return locator;
}

Een test-token ophalen

In deze zelfstudie geven we voor het inhoudssleutelbeleid op dat het een tokenbeperking heeft. Het beleid met de tokenbeperking moet vergezeld gaan van een token dat is uitgegeven door een beveiligingstokenservice (STS). Media Services biedt ondersteuning voor tokens in de JWT-indelingen en dat is wat we in het voorbeeld gaan configureren.

De ContentKeyIdentifierClaim wordt in de ContentKeyPolicy gebruikt, wat inhoudt dat de token die aan de sleutelleveringsservice wordt gepresenteerd, de identificatie van de ContentKey moet bevatten. In het voorbeeld wordt geen inhoudssleutel opgegeven bij het maken van de streaminglocator. Het systeem maakt een willekeurige aan. Om de testtoken te kunnen maken, moet de ContentKeyId de claim ContentKeyIdentifierClaim kunnen invoegen.

private static string GetTokenAsync(string issuer, string audience, string keyIdentifier, byte[] tokenVerificationKey)
{
    var tokenSigningKey = new SymmetricSecurityKey(tokenVerificationKey);

    SigningCredentials cred = new SigningCredentials(
        tokenSigningKey,
        // Use the  HmacSha256 and not the HmacSha256Signature option, or the token will not work!
        SecurityAlgorithms.HmacSha256,
        SecurityAlgorithms.Sha256Digest);

    Claim[] claims = new Claim[]
    {
        new Claim(ContentKeyPolicyTokenClaim.ContentKeyIdentifierClaim.ClaimType, keyIdentifier)
    };

    // To set a limit on how many times the same token can be used to request a key or a license.
    // add  the "urn:microsoft:azure:mediaservices:maxuses" claim.
    // For example, claims.Add(new Claim("urn:microsoft:azure:mediaservices:maxuses", 4));

    JwtSecurityToken token = new JwtSecurityToken(
        issuer: issuer,
        audience: audience,
        claims: claims,
        notBefore: DateTime.Now.AddMinutes(-5),
        expires: DateTime.Now.AddMinutes(60),
        signingCredentials: cred);

    JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();

    return handler.WriteToken(token);
}

Een streaming-URL samenstellen

Nu de StreamingLocator is gemaakt, kunt u de streaming-URL's ophalen. Als u de URL wilt samenstellen, moet u de hostnaam van het StreamingEndpoint en het pad van de streaminglocator 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.

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

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

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

        // Look for just the DASH path and generate a URL for the Azure Media Player to playback the content with the AES token to decrypt.
        // Note that the JWT token is set to expire in 1 hour. 
        if (path.StreamingProtocol == StreamingPolicyStreamingProtocol.Dash)
        {
            uriBuilder.Path = path.Paths[0];

            dashPath = uriBuilder.ToString();

        }
    }
    return dashPath;
}

Wanneer u de app uitvoert, wordt het volgende scherm weergegeven:

Beschermen met drm

U kunt een browser openen en de resulterende URL erin plakken om de demopagina van Azure Media Player te starten waarin de URL en token al zijn ingevuld.

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, StreamingLocators) enzovoorts opnieuw. Als u wilt dat uw account na het experiment is opgeschoond, moet u de resources verwijderen die u niet van plan bent opnieuw te 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);
    }
}

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

Aanvullende opmerkingen

  • Widevine is een service van Google Inc. en is onderworpen aan de servicevoorwaarden en het privacybeleid van Google Inc.

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

Uitchecken