Embed and customize Azure Video Indexer widgets in your app using new package
Published Oct 21 2021 08:50 AM 5,469 Views
Microsoft

Azure Video Indexer provides a way to embed widgets into your business application.

If you're a solution developer, you can embed three types of widgets into your apps: Cognitive Insights, Player, and Editor.

More information is available here.

 

Using our new @azure/video-analyzer-for-media-widgets NPM package, you can add our insights widgets to your app and customize it according to your needs.

Instead of adding an iframe element to embed the insights widget, with this new package you can easily embed & communicate between our widgets. Customizing your widget is only supported in this package - all in one place! 

Colorschemas.jpg

 

We enhanced the insights widget customization with these capabilities -

  • Enable custom styling to meet your application's look and feel.
  • Set a custom configuration to bring your custom AI - insights/models (that isn’t generated by Azure Video Indexer) side-by-side with Azure Video Analyzer AI, and with that to enrich the insight widget with more insights.
  • Enrich your insights by integrating data from other data sources - for example you can build a custom model (e.g. for person detection and tracing) and get additional data from your own sources, like getting data from Active Directory on the person's org structure, and present that in the insight widget).

The package supports two types of insights widget:

  1. Standard Azure Video Indexer widget
  2. Customizable insights widget - allowing you full flexibility and customization to meet your business needs.

Installing the Azure Video Indexer widgets package

The widgets are distributed as an NPM package. There are a couple of ways to install the library:

 

Installation using NPM - For consuming the NPM package directly, you can install it using the npm command.

 

 

 

npm install /video-analyzer-for-media-widgets

 

 

 

Importing using CDN - You can import the latest version of the widget directly into your HTML file by using the following snippet:

 

 

 

        ...
        <script type="module" src="https://unpkg.com/@azure/video-analyzer-for-media-widgets"></script>
    </body>
</html>

 

 

 

Embed standard Azure Video Indexer insights widget

Instead of adding an iframe element to embed the insights widget, the package allows you to add and control it using JavaScript code. 

Here is an example showing how to create a widget at runtime with JavaScript code:

 

 

 

<script>
    function onPackageLoad() {
        // Create widget config
        const config = {
            accountId: '<ACCOUNT-ID>',
            videoId: '<VIDEO-ID>',
            accessToken: '' // Add access token only if your video is private
        };
        let widget = new window.avam.widgets.Insights(
            'widget-container',
            {
                height: 780,
                width: 580
            },
            config
        );

        widget.render();
    }
</script>
<script src="https://unpkg.com/@azure/video-analyzer-for-media-widgets@latest/dist/global.min.js" onload="onPackageLoad()"></script>
<body>
    <div id="widget-container"></div>
</body>

 

 

 

Once calling render() function, the widget will be added as a child element of the container you provided.

 

Let's move on to a more complex code, this time in typescript. 

In the following example, we create an insight widget, with Spanish localization.  The selected tab is the timeline, and the selected components are emotions, sentiments, transcript and keywords. 

 

 

 

import {
    IInsightsWidgetConfig,
    InsightsWidget
} from '@azure/video-analyzer-for-media-widgets';

const config: IInsightsWidgetConfig = {
    accountId: '<ACCOUNT-ID>',
    videoId: '<VIDEO-ID>',
    accessToken: '<ACCESS-TOKEN>',
    locale: 'es-es',
    tab: 'timeline',
    components: ['emotions', 'sentiments', 'transcript', 'keywords']
};

const insightsWidget = new InsightsWidget(
    'container',
    {
        height: 780,
        width: 580
    },
    config
);

insightsWidget.render();

 

 

 

The IInsightsWidgetConfig interface contains multiple options. You can review the class here

Embed Azure Video Indexer customizable insights widget

Embed Azure video Indexer insights widget with original data from the embedded video, combined with your own custom data and raw Azure Video Indexer data.

Adding your own custom insights data:

Custom insight widget supports 3 types of insights data, to be used individually or mixed:

  1. Data from Azure Video Indexer video: the option to bring data from a specific Azure Video Indexer video.
  2. Raw Azure Video Indexer insights: the option to add your own raw Azure Video Indexer insights data, without providing account ID, video ID, or an access token.
  3. Custom insight datathe option to bring your own insights/models and use our UI. You can render your data only with capsule or color map components.

Using capsule:

 Capture1.PNG

 Using color map:

Capture.PNG

Please review our official GitHub and package to find more information about the interfaces and classes involved. 

 

Here is a code sample showing how to create a custom insight widget at runtime with TypeScript code:

 

 

import {
    CustomInsightsWidget,
    ICustomInsightsWidgetConfig
} from '@azure/video-analyzer-for-media-widgets';

const insightsConfig: ICustomInsightsWidgetConfig = {
      duration: <duration>, 
      accountId: '<AVAM-ACCOUNT-ID>',
      videoId: '<AVAM-VIDEO-ID>',
      viInsightsKeys: <insights-key-list-array>,
      rawInsightsData: <raw-insights-data-array>,
      customData: <custom-data-array>
};

const customInsightsWidget = new CustomInsightsWidget(
      'custom-widget-container',
       {
         width: 800,
         height: 1000
       },
       insightsConfig
);

customInsightsWidget.render();

 

 

 

Let's move on to a more complex code.

In the following example, we create a custom insight widget at runtime using all the data types the widget supports.

  1. Video duration is 634 seconds
  2. The widget will show brands, keywords, scenes and blocks provided from Azure Video Indexer video (according to the account + video ID provided). The Video is public since no access token is provided.
  3. The widget will have 2 raw insights data: emotions and topics.
  4. The Widget will have 2 custom data components: one as capsule and the other color map.

 

 

import {
    ICustomInsightsWidgetConfig,
    CustomInsightsWidget,
    VIInsightsKey,
    IEmotion,
    ITopic,
    IVRawIInsightsData,
    ICustomElement,
    ICustomData,
    ICustomColorElement
} from '@azure/video-analyzer-for-media-widgets';

/**
*    Using data from azure video analyzer for media video parameters
**/
// AVAM account ID
const avamAccountID = '00000000-0000-0000-0000-000000000000'
// AVAM video ID
const avamVideoID = 'd9d4860279'
// AVAM insights key list.
const viInsightsKeys : VIInsightsKey[] =  ['brands', 'keywords', 'scenes', 'blocks'];


/**
*    Using raw azure video analyzer for media insights parameters
**/
// Using raw emotions data, with two emotions - one is Joy and other is Sad.
const emotionsList: IEmotion[] [
        {
            id: 1,
            type: 'Joy',
            instances: [
                {
                    adjustedEnd: '0:06:46.15',
                    adjustedStart: '0:06:42.086',
                    confidence: 0.6808,
                    end: '0:06:46.15',
                    start: '0:06:42.086'
                }
            ]
        },
        {
            id: 2,
            type: 'Sad',
            instances: [
                {
                    adjustedEnd: '0:10:18.957',
                    adjustedStart: '0:09:59.306',
                    confidence: 0.8383,
                    end: '0:10:18.957',
                    start: '0:09:59.306'
                }
            ]
        }
];

// Using raw topics data, with 3 topics.
const topicsList: ITopic[] = [
        {
            confidence: 0.7577,
            id: 1,
            name: 'Brand Audit',
            referenceId: 'Brand Audit',
            language: 'en-US',
            instances: [
                {
                    adjustedEnd: '0:01:52.838',
                    adjustedStart: '0:00:13.712',
                    end: '0:01:52.838',
                    start: '0:00:13.712'
                },
                {
                    adjustedEnd: '0:03:16.21',
                    adjustedStart: '0:02:08.093',
                    end: '0:03:16.21',
                    start: '0:02:08.093'
                }
            ]
        },
        {
            confidence: 0.4893,
            iabName: 'News and Politics',
            id: 23,
            instances: [
                {
                    adjustedEnd: '0:02:59.015',
                    adjustedStart: '0:00:08.421',
                    end: '0:02:59.015',
                    start: '0:00:08.421'
                }
            ],
            iptcName: 'Politics/election',
            language: 'en-US',
            name: 'Political Campaigns and Elections',
            referenceId: 'Politics and Government/Political Campaigns and Elections',
            referenceType: 'VideoIndexer'
        },
        {
            confidence: 0.6453,
            iabName: 'Business and Finance',
            id: 14,
            instances: [
                {
                    adjustedEnd: '0:02:37.644',
                    adjustedStart: '0:00:00',
                    end: '0:02:37.644',
                    start: '0:00:00'
                },
                {
                    adjustedEnd: '0:04:01.497',
                    adjustedStart: '0:03:39.322',
                    end: '0:04:01.497',
                    start: '0:03:39.322'
                },
                {
                    adjustedEnd: '0:05:00.968',
                    adjustedStart: '0:04:36.6',
                    end: '0:05:00.968',
                    start: '0:04:36.6'
                }
            ],
            iptcName: 'Economy, Business and Finance/business (general)',
            language: 'en-US',
            name: 'Brand Strategy',
            referenceId: 'Business/Product Development/Brand Strategy',
            referenceType: 'VideoIndexer'
        }
];

// Raw AVAM insights array.
const rawInsightsData: IVRawIInsightsData[] = [
    {
        rawInsightsKey: 'emotions',
        insightsItems: emotionsList
    },
    {
        rawInsightsKey: 'topics',
        insightsItems: topicsList
    }
];

/**
*    Using custom insights data
**/
// Create a custom data with UI as a capsule.

// Create a custom element with name 'custom element 2', that has 4 instances. 
const customElement2 : ICustomElement = {
    id: 1,
    text: 'Custom element 2',
    instances: [
        {
        adjustedEnd: '0:00:12.44',
        adjustedStart: '0:00:11.54',
        end: '0:00:12.44',
        start: '0:00:11.54'
        },
        {
        adjustedEnd: '0:05:27.96',
        adjustedStart: '0:05:19.89',
        end: '0:05:27.96',
        start: '0:05:19.89'
        },
        {
        adjustedEnd: '0:02:06.443',
        adjustedStart: '0:02:00.83',
        end: '0:02:06.443',
        start: '0:02:00.83'
        },
        {
        adjustedEnd: '0:03:45.44',
        adjustedStart: '0:03:43.21',
        end: '0:03:45.44',
        start: '0:03:43.21'
        }
    ]
    };

// Create a custom element with name 'custom element 1', that has 3 instances. 
    const customElement1 : ICustomElement = {
    id: 1,
    text: 'Custom Element 1',
    instances: [
        {
        adjustedEnd: '0:02:37.644',
        adjustedStart: '0:00:00',
        end: '0:02:37.644',
        start: '0:00:00'
        },
        {
        adjustedEnd: '0:04:01.497',
        adjustedStart: '0:03:39.322',
        end: '0:04:01.497',
        start: '0:03:39.322'
        },
        {
        adjustedEnd: '0:05:00.968',
        adjustedStart: '0:04:36.6',
        end: '0:05:00.968',
        start: '0:04:36.6'
        }
    ]
};

// Create the custom data element, with title 'My data', controlled by all and captioning presets, from type capsule, with 2 elements.
const customCapsuleData: ICustomData = {
    title: 'My Data',
    key: 'myData',
    presets: ['all', 'captioning'],
    type: 'capsule',
    items: [customElement, customElement2]
};

// Create custom color element, with text 'My Custom color Element!', with blue color and 3 instances.
const customColorElement : ICustomColorElement= {
    id: 1,
    text: 'My Custom color Element!',
    color: 'blue',
    instances: [
        {
        adjustedEnd: '0:02:37.644',
        adjustedStart: '0:00:00',
        end: '0:02:37.644',
        start: '0:00:00'
        },
        {
        adjustedEnd: '0:04:01.497',
        adjustedStart: '0:03:39.322',
        end: '0:04:01.497',
        start: '0:03:39.322'
        },
        {
        adjustedEnd: '0:05:00.968',
        adjustedStart: '0:04:36.6',
        end: '0:05:00.968',
        start: '0:04:36.6'
        }
    ]
};

// Create custom color element, with text 'Second custom Color Element', with darkmagenta color and 1 instance.
const customColorElement2 : ICustomColorElement = {
    id: 2,
    text: 'Second custom Color Element',
    color: 'darkmagenta',
    instances: [
        {
        adjustedEnd: '0:06:46.15',
        adjustedStart: '0:06:42.086',
        end: '0:06:46.15',
        start: '0:06:42.086'
        }
    ]
    };

// Create custom color element, with text 'customColorElement3', with #FFFFF color and 1 instance.
const customColorElement3 : ICustomColorElement = {
    id: 3,
    text: 'customColorElement3',
    color: '#FFFFF',
    instances: [
        {
        adjustedEnd: '0:10:18.957',
        adjustedStart: '0:09:59.306',
        confidence: 0.8383,
        end: '0:10:18.957',
        start: '0:09:59.306'
        }
    ]
    };

// Create the custom data element, with title 'My color', controlled by all and accessibility presets, from type color-map, with 3 elements.
const customColorData : ICustomData = {
    title: 'My Color',
    key: 'myColor',
    presets: ['all', 'accessibility'],
    type: 'color-map',
    items: [customColorElement, customColorElement2, customColorElement3]
    };

const customDataList : ICustomData[] = [customCapsuleData, customColorData];

const config : ICustomInsightsWidgetConfig = {
    duration: 634, // Video duration - mandatory parameter
    accountId: avamAccountID, // AVAM account ID. Should be provided only if using data from AVAM.
    videoId: avamVideoID,  // AVAM video ID. Should be provided only if using data from AVAM.
    viInsightsKeys: viInsightsKeys, // AVAM insights key list. Mandatory parameter. If you don't want to use data from AVAM, send an empty array.
    rawInsightsData: rawInsightsData, // raw AVAM insights array. Mandatory parameter. If you don't want to use raw data, send an empty array.
    customData: customDataList,  // custom data array. Mandatory parameter. If you don't want to use custom data, send an empty array.
    preset: 'all' // select preset 'All'
};

this.customInsightsWidget = new CustomInsightsWidget(
    'container',
    {
        width: 800,
        height: 1800
    },
    config
);

this.customInsightsWidget.render();

 

 

 

The final insight will be look like this:

135498863-4ae5b4ed-ba4a-462e-9805-70adbe178b6b.png

Enable custom styling to meet your application look and feel

Colorschemas.jpg

 

Both widgets supports customizing the UI color. You can send your own color palette, select one of Azure Video Analyzer for Media theme, or select a default theme and customize part of the colors.

The following typescript example creates a insight widget with 'Dark' theme, and changes two colors:

 

 

 

import {
    IVIInsightsWidgetConfig,
    VIInsightsWidget,
    IBaseStyleConfig,
    IWidgetStyle
} from '@azure/video-analyzer-for-media-widgets';

// Change two colors of the base style config
const insightsStyleConfig : IBaseStyleConfig = {
    primary: 'yellow',
    dividers: 'rgba(134,28,173,1)'
};

// Select dark mode theme and send new style
const style: IWidgetStyle = {
    customStyle: insightsStyleConfig,
    theme: 'Dark'
};
const config: IVIInsightsWidgetConfig = {
    accountId: '<ACCESS-TOKEN>',
    videoId: '<VIDEO-ID>',
    accessToken: '<ACCESS-TOKEN>',
    style: style
};

this.insightsWidget = new VIInsightsWidget(
    'container',
    {
        height: 780,
        width: 580
    },
    config
);

this.insightsWidget.render();

 

 

 

Looking to get your Feedback Today! 

We invite you to use our package and share your feedback with us! More widgets to be add in the future :smile:  Please find more implementation details in our package page and official GitHub! We are happy to receive your feedback.

For those of you who are new to our technology, we encourage you to get started today with these helpful resources:

1 Comment
Co-Authors
Version history
Last update:
‎May 02 2022 01:03 PM
Updated by: