Tutorial: Give an Azure Function app access to a Media Services account

Media Services logo v3


Warning

Azure Media Services will be retired June 30th, 2024. For more information, see the AMS Retirement Guide.

Suppose you want let visitors to your website or application to know that you are “On Air” in your broadcasting studio. You can determine when Media Services Live Events are running using the Media Services API but this may be hard to call from an embedded device. Instead, you could expose an HTTP API for your embedded device using Azure Functions. Azure Functions could then call Media Services to get the state of the Live Event.

Managed Identities giving a Function App access to a Media Services account

This tutorial uses the 2020-05-01 Media Services API.

Sign in to Azure

To use any of the commands in this article, you first have to be signed in to the subscription that you want to use.

Sign in to Azure. When you use this command, you will be prompted for the subscription you want to use.

az login

Set subscription

Use this command to set the subscription that you want to work with.

Set the Azure subscription with the CLI

In the following command, provide the Azure subscription ID that you want to use for the Media Services account.

az account set --subscription <subscriptionName>

Prerequisites

Important

You are strongly encouraged to work through the Create a C# function in Azure from the command line quickstart before attempting this tutorial. That is because the set up steps included there are the same steps needed here. It will also give you a chance to work with a simple example on which this tutorial is based.

Resource names

Before you get started, decide on the names of the resources you'll create. They should be easily identifiable as a set, especially if you aren't planning to use them after you're done testing. Naming rules are different for many resource types so it's best to stick with all lower case. For example, "mediatest1rg" for your resource group name and "mediatest1stor" for your storage account name. Use the same names for each step in this article.

You'll see these names referenced in the commands below. The names of resources you'll need are:

  • myRG
  • myStorageAccount
  • myAmsAccount
  • location
  • myFunction: use "OnAir"
  • myLiveEvent: use "live1"
  • ipaddresses use: "0.0.0./32"

Note

The hyphens above are only used to separate guidance words. Because of the inconsistency of naming resources in Azure services, don't use hyphens when you name your resources.

Anything represented by 00000000-0000-0000-0000000000 is the unique identifier of the resource. This value is usually returned by a JSON response. You should copy and paste the JSON responses in Notepad or other text editor, as those responses will contain values you will need for later CLI commands.

Also, you don't create the region name. The region name is determined by Azure.

List Azure regions

If you're not sure of the actual region name to use, use this command to get a listing:

Use this command to list the regions available for your account.

az account list-locations --query "[].{DisplayName:displayName, Name:name}" -o table

Sequence

Each of the steps below is done in a particular order because one or more values from the JSON responses are used in the next step in the sequence.

Create a Storage account

The Media Services account you'll create must have a storage account associated with it. Create the storage account for the Media Services account first. You'll use your-storage-account-name for subsequent steps.

Create an Azure Storage account with the CLI

Use the following commands to create an Azure Storage account.

To create a storage account, you must first create a resource group within a location.

To list available locations, use the following command:

List available locations with the CLI

To list available locations, use the following command:

az account list-locations

Create a resource group with the CLI

To create a resource group, use the following command:

az group create -n <resourceGroupName> --location chooseLocation

Choose a SKU

You also need to choose a SKU for your storage account. You can list storage accounts.

Choose a SKU from the following list: Standard_LRS, Standard_GRS, Standard_RAGRS, Standard_ZRS, Premium_LRS, Premium_ZRS, Standard_GZRS, Standard_RAGZRS.

  • Change myStorageAccount to a unique name with a length of fewer than 24 characters.
  • Change chooseLocation to the region you want to work within.
  • Change chooseSKU to your preferred SKU.
az storage account create -n <myStorageAccount> -g <resourceGroup>  --location <chooseLocation> --sku <chooseSKU>

Create a Media Services account

Now create the Media Services account. Look for the `

For more information about this command, see the Media Services CLI reference.

Set up the Azure Function

In this section, you'll set up your Azure Function.

Get the code

Use the Azure Functions to create your function project and retrieve the code from the HTTP template.

func init MediaServicesLiveMonitor –dotnet

Change directory

Make sure you change your working directory to the project directory. Otherwise you'll get errors.

cd .\MediaServicesLiveMonitor\

Name your function

func new --name OnAir --template "HTTP trigger" --authlevel "anonymous"

Configure the functions project

Install Media Services and other extensions

Run the dotnet add package command in the Terminal window to install the extension packages that you need in your project. The following command installs the Media Services and Azure Identity packages.

dotnet add package Microsoft.Azure.Management.Media
dotnet add package Azure.Identity

Edit the OnAir.cs code

Change the OnAir.cs file. Change subscriptionId, resourceGroup, and mediaServicesAccountName variables to the ones you decided upon earlier.

using Azure.Core;
using Azure.Identity;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Management.Media;
using Microsoft.Azure.Management.Media.Models;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Rest;
using System.Threading.Tasks;

namespace MediaServicesLiveMonitor
{
    public static class OnAir
    {
        [FunctionName("OnAir")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            string name = req.Query["name"];

            if (string.IsNullOrWhiteSpace(name))
            {
                return new BadRequestObjectResult("Missing 'name' URL parameter");
            }

            var credential = new ManagedIdentityCredential();
            var accessTokenRequest = await credential.GetTokenAsync(
                new TokenRequestContext(
                    scopes: new string[] { "https://management.core.windows.net" + "/.default" }
                    )
                );
            ServiceClientCredentials credentials = new TokenCredentials(accessTokenRequest.Token, "Bearer");

            var subscriptionId = "00000000-0000-0000-000000000000";                 // Update
            var resourceGroup = "<your-resource-group-name>";                       // Update
            var mediaServicesAccountName = "<your-media-services-account-name>";    // Update

            var mediaServices = new AzureMediaServicesClient(credentials)
            {
                SubscriptionId = subscriptionId
            };

            var liveEvent = await mediaServices.LiveEvents.GetAsync(resourceGroup, mediaServicesAccountName, name);

            if (liveEvent == null)
            {
                return new NotFoundResult();
            }

            return new OkObjectResult(liveEvent.ResourceState == LiveEventResourceState.Running ? "On air" : "Off air");
        }
    }
}

Create the Function App

Create the Function App to host the function. The name is the same as the one that you downloaded earlier, MediaServicesLiveMonitorApp.


az functionapp create --resource-group <your-resource-group-name> --consumption-plan-location your-region --runtime dotnet --functions-version 3 --name MediaServicesLiveMonitorApp --storage-account mediatest3store --assign-identity "[system]"

Look for principalId in the JSON response:

{
...
"identity": {
//Note the principalId value for the following step
    "principalId": "00000000-0000-0000-000000000000",
    "tenantId": "00000000-0000-0000-000000000000",
    "type": "SystemAssigned",
    "userAssignedIdentities": null
  }
...

Grant the function app access to the Media Services account resource

For this request:

  • assignee is the principalId that is in the JSON response from az functionapp create
  • scope is the id that is in the JSON response from az ams account create. See the example JSON response above.
az role assignment create --assignee 00000000-0000-0000-000000000000 --role "Media Services Account Administrator" --scope "/subscriptions/<the-subscription-id>/resourceGroups/<your-resource-group>/providers/Microsoft.Media/mediaservices/<your-media-services-account-name>"

Publish the function

func azure functionapp publish MediaServicesLiveMonitorApp

Validation

In a browser, go to the function URL, for example:

https://mediaserviceslivemonitorapp.azurewebsites.net/api/onair?name=live1

This should return a 404 (Not Found) error as the Live Event does not exist yet.

Create a Live Event

az ams live-event create --resource-group test3 --account-name mediatest3 --name live1 --streaming-protocol RTMP

In a browser, go to the function URL, for example:

https://mediaserviceslivemonitorapp.azurewebsites.net/api/onair?name=live1

This should now show “Off Air”.

Start the live event

If you start the Live Event, the function should return “On Air”.

az ams live-event start live1

This function allows access to anyone. Securing access to the Azure Function and wiring up an “On Air” light are out of scope for this document.

Clean up resources

If you aren't planning to use the resources you created, delete the resource group.

Delete a resource group with the CLI

az group delete --name <your-resource-group-name>

Get help and support

You can contact Media Services with questions or follow our updates by one of the following methods: