Getting Started with Azure Video Indexer and PowerShell
Tags: azure, powershell, videoindexer
Published: 2021-01-14 19:16:03

> _If you like this article, be sure to check out [more Azure articles and other how-to posts on cloud computing, system administration, IT, and DevOps on adamtheautomator.com](https://adamtheautomator.com)!_

<!-- wp:paragraph -->
<p>After building my Pluralsight course <a href="https://pluralsight.pxf.io/Eg4MD">Microsoft Azure Cognitive Services: Custom Text to Speech</a>, I've been playing around more with Azure's various APIs. I recently found myself using the Azure Video Indexer and decided to begin poking at it with PowerShell. Here's a brief rundown.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>To get started, you either first have to <a href="https://vi.microsoft.com/en-us/">sign up for a trial account</a> which includes 2,400 minutes of free indexed usage via the API or <a href="https://docs.microsoft.com/en-us/azure/media-services/video-indexer/connect-to-azure">create a Video Indexer account</a> in your Azure subscription. For now, I decided to just use the free trial since I was just testing it out.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 id="subscribing-to-the-authorization-product-api">Subscribing to the Authorization Product API</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The first task is authenticating to the Azure Video Indexer. To do this, you first need to subscribe to the Authorization Product API. You'll do that by logging into the Video Indexer developer portal, clicking on the <a href="https://api-portal.videoindexer.ai/products/authorization">Products section</a> and clicking <em>Subscribe</em>. For a full rundown, check out the Microsoft tutorial <a href="https://docs.microsoft.com/en-us/azure/media-services/video-indexer/video-indexer-use-apis#subscribe-to-the-api">Use the Video Indexer API</a>.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 id="finding-your-account-id">Finding Your Account ID</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Once you've subscribed to the Authorization Product, you'll then need your account ID. There are a few ways to get this but the easiest is by heading to your <a href="https://www.videoindexer.ai/settings/account">Azure Video Indexer service page</a>. If this link doesn't bring you directly to your <em>Account</em> section on the <em>Settings</em> page, click on your user profile in the upper-right corner of the page and choose <em>Settings</em> as shown below then once there, click on <em>Account</em>.</p>
<!-- /wp:paragraph -->

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ocl8nsd6a4f8fevxkpkf.png)

<!-- wp:paragraph -->
<p>Once on the <em>Account</em> section, copy your <em>Account ID</em> as shown below.</p>
<!-- /wp:paragraph -->

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/050iv1zprclqlk7atuf6.png)

<!-- wp:paragraph -->
<p></p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 id="finding-your-api-key">Finding Your API Key</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Next, you'll need to find your API key. Your API key can be found in on your <a href="https://api-portal.videoindexer.ai/products/authorization">Authorization product subscription in the Video Indexer Developer Portal</a>. If this link doesn't bring you directly there, navigate to the <a href="https://api-portal.videoindexer.ai/">Video Indexer Developer Portal home page</a>, click on Products --&gt; Authorization and then on the Authorization product you've already subscribed to as shown below.</p>
<!-- /wp:paragraph -->

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/zt8m7whkeelyo79azoza.png)

<!-- wp:paragraph -->
<p>Once in the Authorization product, you should see your primary and secondary key. You just need your primary one for now.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Click on <em>Show</em> next to your primary key to see your personal API key then copy the key to your clipboard.</p>
<!-- /wp:paragraph -->

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/r5i0biup0f5qu21gadik.png)

<!-- wp:heading -->
<h2 id="setting-up-powershell-variables">Setting up PowerShell Variables</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Let's now start building the PowerShell script. I like to define values in variables that I'll be using throughout my script. I'll do that now. Notice that I'm also using TLS1.2. This is required.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code lang="powershell" class="language-powershell">[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$apiUrl = 'https://api.videoindexer.ai'
$apiKey = 'XXXXXX'
$accountId = 'XXXXXXXX'
$location = 'trial'

## eastus2, westus2, etc
$accountUrl = "$apiUrl/$location/Accounts/$accountId"</code></pre>
<!-- /wp:code -->

<!-- wp:heading -->
<h2 id="getting-an-access-token">Getting an Access Token</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>By now, you should have two critical pieces of information; your account ID and your API key. If so, you can now get an access token. The endpoint URI to grab an access token is required in the form of:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code lang="powershell" class="language-powershell">https://api.videoindexer.ai/auth/&lt;Location&gt;/Accounts/&lt;AccountID&gt;/AccessToken</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>You already have your account ID but the location can be tricky to find. Since we're using a trial key, the location is <code>trial</code>.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Also, the authentication URI has an optional query parameter called <code>allowEdit</code>. This query parameter defines if the token you're getting here will be able to modify resources when it's used. That means if you'll be able to use HTTP methods like POST and PUT rather than just GET requests. In this article, we will be uploading a video, so we need to have this capability with the access token. The authentication URI then ends up looking like this:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code lang="powershell" class="language-powershell">$tokenUri = "https://api.videoindexer.ai/auth/$location/Accounts/$accountId/AccessToken?allowEdit=True"</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>You'll need to pass the API key to the access token request via headers using the <code>Ocp-Apim-Subscription-Key</code> key. Below you'll see the way you can run the <code>Invoke-RestMethod</code> command to make the API call. Once this runs, you should have a shiny new access token stored in the <code>$token</code> variable.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code lang="powershell" class="language-powershell">$headers = @{
	'Ocp-Apim-Subscription-Key' = $apiKey
}

$params = @{
    'Uri' = $tokenUri
    'Headers' = $headers
    'Method'  = 'GET'
}

$token = Invoke-RestMethod @params</code></pre>
<!-- /wp:code -->

<!-- wp:heading -->
<h2 id="uploading-a-video">Uploading a Video</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Once you've got a token, let's upload a sample video to test it out. You can upload a video two ways either via uploading a video on your own or using a URL. I'll use a URL. To do that, you'll use the Videos API passing the name of the video that will be displayed in the Video Indexer console, the <code>videoUrl</code> query parameter specifying the URL to the video to upload and since my video is in English, I'm using the <code>language</code> parameter although is not required.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Also notice below that the URL must be URL-encoded so I'm using the <code>UrlEncode()</code> method to make that happen then passing that URL to the <code>Invoke-RestMethod</code> command.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code lang="powershell" class="language-powershell">$videoName = 'testing'
$videoUrl = ''
$encUrl = [System.Web.HttpUtility]::UrlEncode($videoUrl)
$uploadVideoUrl = "$accountUrl/Videos?name=$videoName&amp;accessToken=$token&amp;videoUrl=$encUrl&amp;language=en-US"  

$params = @{
    'Uri' = $uploadVideoUrl
    'Method' = 'POST'
}

$uploadedVideo = Invoke-RestMethod @params</code></pre>
<!-- /wp:code -->

<!-- wp:heading -->
<h2 id="wait-for-indexing">Wait for Indexing</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>This will upload the video to Azure Video Indexer and indexing will immediately start. You could stop here but there are so many other things to do! Just for fun, let's download the transcription that's created. Before we can do that, we'll need to wait for the transcription to finish.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>To wait for the indexing to complete, we'll make another API call to the Videos endpoint and this time query the <a href="https://api-portal.videoindexer.ai/docs/services/Operations/operations/Get-Video-Index">Index</a> path of the video we just uploaded. Since API result was captured in the <code>$uploadedVideo</code> variable, we can reference the <code>id</code> property building the correct URI.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>We'll then build a <code>while</code> loop which continually checks the <code>state</code> property. When the <code>state</code> property value is no longer <code>Uploaded</code> or <code>Processing</code>, it's done!</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code lang="powershell" class="language-powershell">$videoUri = "$accountUrl/Videos/$($uploadedVideo.id)/Index?accessToken=$token"

while ((Invoke-RestMethod -Uri $videoUri -Method 'GET').state -in @('Uploaded', 'Processing')) {
	Write-Host "Waiting for video to index..."
    <a class="wpil_keyword_link" href="https://adamtheautomator.com/start-sleep-powershell/" title="Start-Sleep" data-wpil-keyword-link="linked">Start-Sleep</a> -Seconds 5
}</code></pre>
<!-- /wp:code -->

<!-- wp:heading -->
<h2 id="getting-a-video-transcript">Getting a Video Transcript</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>At this point, we can do just about anything but I personally needed to pull video transcripts. I create a small code snippet to make that happen using the <a href="https://api-portal.videoindexer.ai/docs/services/Operations/operations/Get-Video-Captions">Captions endpoint</a> as shown below.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code lang="powershell" class="language-powershell">## Allowed values: Vtt/Ttml/Srt/Txt/Csv
$captionUri = "$accountUrl/Videos/$($uploadedVideo.id)/Captions?accessToken=$token&amp;format=Txt"
$captions = Invoke-RestMethod -Uri $captionUri -Method 'GET'</code></pre>
<!-- /wp:code -->

<!-- wp:heading -->
<h2 id="summary">Summary</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The code covered in this article works but it's not useful on it's own if you intend to use Azure Video Indexer in production or even seriously in a test environment. I recommend building a <a class="wpil_keyword_link" href="https://adamtheautomator.com/powershell-modules/" title="PowerShell module" data-wpil-keyword-link="linked">PowerShell module</a> which gives you the ability to compartmentalize a lot of this code into functions.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>For an example, check out my <a href="https://github.com/adbertram/AzTextToSpeech/tree/master">AzTextToSpeech module</a> for inspiration. It'd require quite a bit of modification but does have some similarities.</p>
<!-- /wp:paragraph -->