Index your videos stored on OneDrive

This article shows how to index videos stored on OneDrive by using the Azure Video Indexer website.

Supported file formats

For a list of file formats that you can use with Azure Video Indexer, see Standard Encoder formats and codecs.

Index a video by using the website

  1. Sign into the Azure Video Indexer website, and then select Upload.

    Screenshot that shows the Upload button.

  2. Click on enter a file URL button

    Screenshot that shows the enter file URL button.

  3. Next, go to your video/audio file located on your OneDrive using a web browser. Select the file you want to index, at the top select embed

    Screenshot that shows the embed code button.

  4. On the right click on Generate to generate an embed url.

    Screenshot that shows the embed code generate button.

  5. Copy the embed code and extract only the URL part including the key. For example:

    https://onedrive.live.com/embed?cid=5BC591B7C713B04F&resid=5DC518B6B713C40F%2110126&authkey=HnsodidN_50oA3lLfk

    Replace embed with download. You will now have a url that looks like this:

    https://onedrive.live.com/download?cid=5BC591B7C713B04F&resid=5DC518B6B713C40F%2110126&authkey=HnsodidN_50oA3lLfk

  6. Now enter this URL in the Azure Video Indexer website in the URL field.

    Screenshot that shows the onedrive url field.

After your video is downloaded from OneDrive, Azure Video Indexer starts indexing and analyzing the video.

Screenshot that shows the progress of an upload.

Once Azure Video Indexer is done analyzing, you will receive an email with a link to your indexed video. The email also includes a short description of what was found in your video (for example: people, topics, optical character recognition).

Upload and index a video by using the API

You can use the Upload Video API to upload and index your videos based on a URL. The code sample that follows includes the commented-out code that shows how to upload the byte array.

Configurations and parameters

This section describes some of the optional parameters and when to set them. For the most up-to-date info about parameters, see the Azure Video Indexer API developer portal.

externalID

Use this parameter to specify an ID that will be associated with the video. The ID can be applied to integration into an external video content management (VCM) system. The videos that are in the Azure Video Indexer website can be searched via the specified external ID.

callbackUrl

Use this parameter to specify a callback URL.

A callback URL is used to notify the customer (through a POST request) about the following events:

  • Indexing state change:

    • Properties:

      Name Description
      id The video ID
      state The video state
    • Example: https://test.com/notifyme?projectName=MyProject&id=1234abcd&state=Processed

  • Person identified in video:

    • Properties

      Name Description
      id The video ID
      faceId The face ID that appears in the video index
      knownPersonId The person ID that is unique within a face model
      personName The name of the person
    • Example: https://test.com/notifyme?projectName=MyProject&id=1234abcd&faceid=12&knownPersonId=CCA84350-89B7-4262-861C-3CAC796542A5&personName=Inigo_Montoya

Azure Video Indexer returns any existing parameters provided in the original URL. The URL must be encoded.

indexingPreset

Use this parameter to define an AI bundle that you want to apply on your audio or video file. This parameter is used to configure the indexing process. You can specify the following values:

  • AudioOnly: Index and extract insights by using audio only (ignoring video).

  • VideoOnly: Index and extract insights by using video only (ignoring audio).

  • Default: Index and extract insights by using both audio and video.

  • DefaultWithNoiseReduction: Index and extract insights from both audio and video, while applying noise reduction algorithms on the audio stream.

    The DefaultWithNoiseReduction value is now mapped to a default preset (deprecated).

  • BasicAudio: Index and extract insights by using audio only (ignoring video). Include only basic audio features (transcription, translation, formatting of output captions and subtitles).

  • AdvancedAudio: Index and extract insights by using audio only (ignoring video). Include advanced audio features (such as audio event detection) in addition to the standard audio analysis.

  • AdvancedVideo: Index and extract insights by using video only (ignoring audio). Include advanced video features (such as observed people tracing) in addition to the standard video analysis.

  • AdvancedVideoAndAudio: Index and extract insights by using both advanced audio and advanced video analysis.

Note

The preceding advanced presets include models that are in public preview. When these models reach general availability, there might be implications for the price.

Azure Video Indexer covers up to two tracks of audio. If the file has more audio tracks, they're treated as one track. If you want to index the tracks separately, you need to extract the relevant audio file and index it as AudioOnly.

Price depends on the selected indexing option. For more information, see Media Services pricing.

priority

Azure Video Indexer indexes videos according to their priority. Use the priority parameter to specify the index priority. The following values are valid: Low, Normal (default), and High.

This parameter is supported only for paid accounts.

streamingPreset

After your video is uploaded, Azure Video Indexer optionally encodes the video. It then proceeds to indexing and analyzing the video. When Azure Video Indexer is done analyzing, you get a notification with the video ID.

When you're using the Upload Video or Re-Index Video API, one of the optional parameters is streamingPreset. If you set streamingPreset to Default, SingleBitrate, or AdaptiveBitrate, the encoding process is triggered.

After the indexing and encoding jobs are done, the video is published so you can also stream your video. The streaming endpoint from which you want to stream the video must be in the Running state.

For SingleBitrate, the standard encoder cost will apply for the output. If the video height is greater than or equal to 720, Azure Video Indexer encodes it as 1280 x 720. Otherwise, it's encoded as 640 x 468. The default setting is content-aware encoding.

If you only want to index your video and not encode it, set streamingPreset to NoStreaming.

videoUrl

This parameter specifies the URL of the video or audio file to be indexed. If the videoUrl parameter is not specified, Azure Video Indexer expects you to pass the file as multipart/form body content.

Code sample

Note

The following sample is intended for Classic accounts only and isn't compatible with ARM accounts. For an updated sample for ARM, see this ARM sample repo.

The following C# code snippets demonstrate the usage of all the Azure Video Indexer APIs together.

After you copy the following code into your development platform, you'll need to provide two parameters:

  • API key (apiKey): Your personal API management subscription key. It allows you to get an access token in order to perform operations on your Azure Video Indexer account.

    To get your API key:

    1. Go to the Azure Video Indexer API developer portal.
    2. Sign in.
    3. Go to Products > Authorization > Authorization subscription.
    4. Copy the Primary key value.
  • Video URL (videoUrl): A URL of the video or audio file to be indexed. Here are the requirements:

    • The URL must point at a media file. (HTML pages are not supported.)
    • The file can be protected by an access token that's provided as part of the URI. The endpoint that serves the file must be secured with TLS 1.2 or later.
    • The URL must be encoded.

The result of successfully running the code sample includes an insight widget URL and a player widget URL. They allow you to examine the insights and the uploaded video, respectively.

public async Task Sample()
{
    var apiUrl = "https://api.videoindexer.ai";
    var apiKey = "..."; // Replace with API key taken from https://aka.ms/viapi

    System.Net.ServicePointManager.SecurityProtocol =
        System.Net.ServicePointManager.SecurityProtocol | System.Net.SecurityProtocolType.Tls12;

    // Create the HTTP client
    var handler = new HttpClientHandler();
    handler.AllowAutoRedirect = false;
    var client = new HttpClient(handler);
    client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", apiKey);

    // Obtain account information and access token
    string queryParams = CreateQueryString(
        new Dictionary<string, string>()
        {
            {"generateAccessTokens", "true"},
            {"allowEdit", "true"},
        });
    HttpResponseMessage result = await client.GetAsync($"{apiUrl}/auth/trial/Accounts?{queryParams}");
    var json = await result.Content.ReadAsStringAsync();
    var accounts = JsonConvert.DeserializeObject<AccountContractSlim[]>(json);

    // Take the relevant account. Here we simply take the first.
    // You can also get the account via accounts.First(account => account.Id == <GUID>);
    var accountInfo = accounts.First();

    // We'll use the access token from here on, so there's no need for the APIM key
    client.DefaultRequestHeaders.Remove("Ocp-Apim-Subscription-Key");

    // Upload a video
    var content = new MultipartFormDataContent();
    Console.WriteLine("Uploading...");
    // Get the video from URL
    var videoUrl = "VIDEO_URL"; // Replace with the video URL from OneDrive

    // As an alternative to specifying video URL, you can upload a file.
    // Remove the videoUrl parameter from the query parameters below and add the following lines:
    //FileStream video =File.OpenRead(Globals.VIDEOFILE_PATH);
    //byte[] buffer =new byte[video.Length];
    //video.Read(buffer, 0, buffer.Length);
    //content.Add(new ByteArrayContent(buffer));

    queryParams = CreateQueryString(
        new Dictionary<string, string>()
        {
            {"accessToken", accountInfo.AccessToken},
            {"name", "video_name"},
            {"description", "video_description"},
            {"privacy", "private"},
            {"partition", "partition"},
            {"videoUrl", videoUrl},
        });
    var uploadRequestResult = await client.PostAsync($"{apiUrl}/{accountInfo.Location}/Accounts/{accountInfo.Id}/Videos?{queryParams}", content);
    var uploadResult = await uploadRequestResult.Content.ReadAsStringAsync();

    // Get the video ID from the upload result
    string videoId = JsonConvert.DeserializeObject<dynamic>(uploadResult)["id"];
    Console.WriteLine("Uploaded");
    Console.WriteLine("Video ID:");
    Console.WriteLine(videoId);

    // Wait for the video index to finish
    while (true)
    {
        await Task.Delay(10000);

        queryParams = CreateQueryString(
            new Dictionary<string, string>()
            {
                {"accessToken", accountInfo.AccessToken},
                {"language", "English"},
            });

        var videoGetIndexRequestResult = await client.GetAsync($"{apiUrl}/{accountInfo.Location}/Accounts/{accountInfo.Id}/Videos/{videoId}/Index?{queryParams}");
        var videoGetIndexResult = await videoGetIndexRequestResult.Content.ReadAsStringAsync();

        string processingState = JsonConvert.DeserializeObject<dynamic>(videoGetIndexResult)["state"];

        Console.WriteLine("");
        Console.WriteLine("State:");
        Console.WriteLine(processingState);

        // Job is finished
        if (processingState != "Uploaded" && processingState != "Processing")
        {
            Console.WriteLine("");
            Console.WriteLine("Full JSON:");
            Console.WriteLine(videoGetIndexResult);
            break;
        }
    }

    // Search for the video
    queryParams = CreateQueryString(
        new Dictionary<string, string>()
        {
            {"accessToken", accountInfo.AccessToken},
            {"id", videoId},
        });

    var searchRequestResult = await client.GetAsync($"{apiUrl}/{accountInfo.Location}/Accounts/{accountInfo.Id}/Videos/Search?{queryParams}");
    var searchResult = await searchRequestResult.Content.ReadAsStringAsync();
    Console.WriteLine("");
    Console.WriteLine("Search:");
    Console.WriteLine(searchResult);

    // Generate video access token (used for get widget calls)
    client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", apiKey);
    var videoTokenRequestResult = await client.GetAsync($"{apiUrl}/auth/{accountInfo.Location}/Accounts/{accountInfo.Id}/Videos/{videoId}/AccessToken?allowEdit=true");
    var videoAccessToken = (await videoTokenRequestResult.Content.ReadAsStringAsync()).Replace("\"", "");
    client.DefaultRequestHeaders.Remove("Ocp-Apim-Subscription-Key");

    // Get insights widget URL
    queryParams = CreateQueryString(
        new Dictionary<string, string>()
        {
            {"accessToken", videoAccessToken},
            {"widgetType", "Keywords"},
            {"allowEdit", "true"},
        });
    var insightsWidgetRequestResult = await client.GetAsync($"{apiUrl}/{accountInfo.Location}/Accounts/{accountInfo.Id}/Videos/{videoId}/InsightsWidget?{queryParams}");
    var insightsWidgetLink = insightsWidgetRequestResult.Headers.Location;
    Console.WriteLine("Insights Widget url:");
    Console.WriteLine(insightsWidgetLink);

    // Get player widget URL
    queryParams = CreateQueryString(
        new Dictionary<string, string>()
        {
            {"accessToken", videoAccessToken},
        });
    var playerWidgetRequestResult = await client.GetAsync($"{apiUrl}/{accountInfo.Location}/Accounts/{accountInfo.Id}/Videos/{videoId}/PlayerWidget?{queryParams}");
    var playerWidgetLink = playerWidgetRequestResult.Headers.Location;
     Console.WriteLine("");
     Console.WriteLine("Player Widget url:");
     Console.WriteLine(playerWidgetLink);
     Console.WriteLine("\nPress Enter to exit...");
     String line = Console.ReadLine();
     if (line == "enter")
     {
         System.Environment.Exit(0);
     }

}

private string CreateQueryString(IDictionary<string, string> parameters)
{
    var queryParameters = HttpUtility.ParseQueryString(string.Empty);
    foreach (var parameter in parameters)
    {
        queryParameters[parameter.Key] = parameter.Value;
    }

    return queryParameters.ToString();
}

public class AccountContractSlim
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string Location { get; set; }
    public string AccountType { get; set; }
    public string Url { get; set; }
    public string AccessToken { get; set; }
}