Grooming VOS Video Input Source through an I-Frame Window for inclusion in your own application

  • 3
  • Idea
  • Updated 1 year ago
  • Implemented
  • (Edited)
This article describes the requirements and steps to integrate the VOS Input Sources Grooming window (through an I-Frame) to a 3rd party application.

1.   Introduction

The VOS Configuration App provides Grooming User Interface provides an interface for the end user to configure the Video input source for Video/Audio/Data streams to either added metadata or to exclude those streams from processing. For third Party Application integration, this user interface can’t be expose to their users because cross-origin resource sharing is not allowed in browsers by default.

To work around this limitation, Third Party application developers can use a special remote grooming request through an I-Frame Window in the browser to expose the VOS Grooming User Interface to user. This should greatly ease integration as the grooming of the source is one of the most complex tasks a Third Party developer has to undertake. However it requires third party application to use cross-window messaging to safely enable cross-origin communication. 

2.   Requirements
  • Third Party Application developer must implement a Web Application/UI to expose cross-origin grooming user interface through an I-Frame in a browser.
  • Java Script will be used by the Third Party Client Application to send and listen to cross-window messaging for the communication between it and VOS Server.
  • The Cross-origin grooming request will only be allowed to the following URL by VOS Server through “X-Frame-Option” http response header - https://{vos-server}/groom/source
  • The Third Party Application must acquire OAuthAccess Token from VOS Server, and send it to VOS Server through cross-window message for Authentication. This topic is covered in another post.
  • The Third Party Application must specify the Video input source in JSON format to be groomed, and send it to VOS Server through a cross-window message.
The following is a screen capture of sample integration application to use cross-origin grooming feature of VOS Server.

3.   References  The following are reference links for cross-origin x-frameoption and “postMessage” method in browser.

4.   Workflow The workflow diagram for cross-origin grooming is as shown in the following digram and further clarified in the detailed steps. For reference the Third Party Application/UI will be displayed in “Main Window” and the VOS Grooming User Interface served by VOS will be displayed in I-Frame “GroomingWindow”.


Detailed Steps 

  1. Acquire OAuth Access Token from VOS Server
  2. Get the JSON for the Video Input Section by either:
      - Getting the existing Video Input Source Data using the VOS API
      - Discover raw Video InputSource through VOS API
  3. The Third Party UI is displayed in Main Window and the I-Frame Grooming window is hidden. 
  4. The Third Party UI Client builds cross-origin grooming request URL, and sets it as an I-Frame
      Source URL - https://{VOS-Server}/groom/source
  5. The Third Party UI Client in main Window and waits for 'GROOM_AUTHENTICATE' message from
      I-Frame Grooming Window before sending a reply containing the OAuth Access Token.
  6. The Third Party UI Client in main Window waits for 'GROOM_READY' message from I-Frame
      Grooming Window and then unhides the I-Frame window, sending back a 'GROOM_NEW_INPUT'
      message with Video Input Source Data.
  7. The Third Party UI Client in main Window must then listen for the following messages from I-Frame
      to save or discard the Groomed Input Source, or resize I-Frame Window.
  • 'GROOM_ERROR' - Server not able to handle Groom request 
  • 'GROOM_CANCEL_INPUT' - User discards the groom result.
  • 'GROOM_UPDATE_INPUT' - User accepts the groom result.
  • 'GROOM_SIZE_CHANGE' - Groom Window size is changed.

5. Sample Java Script code to handle cross window messages

Java Script to handle Window Message in Angular JS Controller

var demoInput = {"id": "ba805030-e630-9e8b-dfd9-2c6d4eb7a0ba",...} //Input Source Data
scope.groomReady = false; = {command:'GROOM_NEW_INPUT', content:demoInput};
scope.authentication = {command:'GROOM_AUTHENTICATE', token:scope.accessToken};
scope.url = undefined;
window.addEventListener('message', function(e) {
     if ( == 'GROOM_AUTHENTICATE') {
         scope.url = e.origin;
         scope.eFrame = angular.element($rootElement).find('#iGrooming')[0];
             scope.url.replace( /([^:]+:\/\/[^\/]+).*/, '$1' )
     }else if ( == 'GROOM_READY') {
         scope.groomReady = true;
         scope.url = e.origin;
         scope.eFrame = angular.element($rootElement).find('#iGrooming')[0];
         scope.inputJSON = JSON.stringify(, undefined, 4);
     else if ( == 'GROOM_ERROR') {
     else if ( == 'GROOM_CANCEL_INPUT') {
         VOSLOGGER.log('grooming GROOM_CANCEL_INPUT');
     else if ( == 'GROOM_UPDATE_INPUT') {
         scope.inputJSON = JSON.stringify(, undefined, 4);
         VOSLOGGER.log('grooming GROOM_UPDATE_INPUT');
     else if ( == 'GROOM_SIZE_CHANGE') { ='px'; ='px';
         VOSLOGGER.log('grooming GROOM_SIZE_CHANGE: width='',height=';
}, false);
         scope.groom = {show:false};
         scope.updateInput = function () {
    = JSON.parse(scope.inputJSON);
         scope.openGroom = function(eid) {
             if (scope.avModal== undefined) {
             scope.avModal = angular.element($rootElement).find('#'+eid);
    = true;
             angular.element(scope.avModal).one('', function(event) {
        = false;
             if (scope.groomReady == true) {
                     scope.url.replace( /([^:]+:\/\/[^\/]+).*/, '$1' )
Test HTML Template Angular JS Controller

 <div class="spacer">
    <div ng-disabled="!groomReady"class="btn btn-primary btn-lg pull-right"ng-click="openGroom('remote-groom')">Groom</div>
    <div class="form-grouppull-left">
        <labelclass="form-label-alt">Remote Server</label>
        <input type="text"class="form-control input-sm" ng-model="host"style="width:400px;">
        <labelclass="form-label-alt">OAuth Token</label>
        <input type="text"class="form-control input-sm" ng-model="accessToken"style="width:300px;">
        <br clear="all">
        <button class="btn btn-defaultbtn-sm" ng-click="applyToken()">Connect</button>
        <br clear="all">
        <textareang-model="inputJSON" style="width: 800px; height: 400px"rows="20" ng-change="updateInput()"></textarea>
    <div class="modal fade"id="remote-groom" tabindex="-1" role="dialog"aria-labelledby="groom" aria-hidden="true"data-backdrop="static" data-keyboard="false">
            <iframe ng-if="IfUrl"id="iGrooming" ng-src="{{IfUrl}}" scrolling="no"height="650" width="600"frameBorder="0"></iframe>

Enjoy grooming....

Photo of Moore

Moore, Product Architect

  • 400 Points 250 badge 2x thumb

Posted 1 year ago

  • 3

Be the first to post a reply!