Tutorial: Give an Azure Function app access to a Media Services account
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.
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, Premium_LRS.
- 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.chinacloudapi.cn" + "/.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 theprincipalId
that is in the JSON response fromaz functionapp create
scope
is theid
that is in the JSON response fromaz 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.chinacloudsites.cn/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.chinacloudsites.cn/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>