soporte Contactar con Soporte | Estadoestado del sistema del sistema
Contenido de la página

    Obtener el estado de las solicitudes de ingesta dinámica

    Cuando utiliza para agregar vídeos a su cuenta de Video Cloud, lo que más desea saber es cuándo se ha procesado el vídeo y si las copias se han creado correctamente o no.Dynamic Ingest API

    Introducción

    En este documento se explica cómo puede realizar un seguimiento del estado de los trabajos mediante la realización de solicitudes de estado a la CMS API o mediante Dynamic Ingest API notificaciones. También ofrecemos una aplicación de panel de muestra que automatiza el proceso

    Tenga en cuenta que el estado de los trabajos de ingesta sólo está disponible para trabajos enviados en los últimos 7 días.

    Estado de solicitud

    Obtiene el estado de los trabajos de ingesta dinámica (ingesta, reemplazo o retranscodificación) utilizando estos CMS API extremos . Tenga en cuenta que estos extremos funcionan sólo para trabajos de entrega dinámica:

    Obtener el estado de todos los trabajos

        https://cms.api.brightcove.com/v1/accounts/{account_id}/videos/{video_id}/ingest_jobs

    La respuesta se verá algo como esto:

         [
          {
            "id": "ac49b1db-e6e1-477f-a2c1-70b9cd3107cb",
            "state": "finished",
            "account_id": "57838016001",
            "video_id": "5636411346001",
            "error_code": null,
            "error_message": null,
            "updated_at": "2017-11-07T13:56:51.505Z",
            "started_at": "2017-11-07T13:56:12.510Z",
            "priority": "normal",
            "submitted_at": "2017-11-07T13:56:12.435Z"
          },
          {
            "id": "10605652-8b6f-4f22-b190-01bd1938677b",
            "state": "processing",
            "account_id": "57838016001",
            "video_id": "5636411346001",
            "error_code": null,
            "error_message": null,
            "updated_at": null,
            "started_at": null,
            "priority": "low",
            "submitted_at": "2017-11-07T14:06:35.000Z"
          }
        ]

    Obtener el estado de un trabajo específico

        https://cms.api.brightcove.com/v1/accounts/{account_id}/videos/{video_id}/ingest_jobs/{job_id}

    La respuesta se verá algo como esto:

        {
            "id": "ac49b1db-e6e1-477f-a2c1-70b9cd3107cb",
            "state": "finished",
            "account_id": "57838016001",
            "video_id": "5636411346001",
            "error_code": null,
            "error_message": null,
            "updated_at": "2017-11-07T13:56:51.505Z",
            "started_at": "2017-11-07T13:56:12.510Z",
            "priority": "normal",
            "submitted_at": "2017-11-07T13:56:12.435Z"
          }

    Los valores posibles para state son:

    • processing: procesamiento, el vídeo aún no se puede reproducir
    • publishing: se ha creado al menos una copia reproducible y el vídeo se está preparando para su reproducción
    • published: al menos una copia está disponible para su reproducción
    • finished: se ha procesado al menos una copia de audio/vídeo
    • failed: error en el procesamiento; si no es capaz de averiguar qué salió mal, póngase en contacto con el Soporte

    Recibir notificaciones

    Si bien el método de estado de solicitud descrito anteriormente funciona, si está esperando un estado particular (published o finished), es mejor dejar que Brightcove le notifique cuándo ocurren estos eventos en lugar de tener que seguir pidiendo el hasta que obtenga la respuesta que está buscando. Ahora veremos cómo puede crear una aplicación sobre el manejo de notificaciones.

    Las notificaciones de ingesta dinámica le proporcionan toda la información que necesita saber cuando el vídeo está listo - sólo necesita saber qué buscar... y definir qué significa «listo» para sus sistemas. Este diagrama resume el flujo de trabajo:

    Flujo de trabajo Estado de ingesta
    Flujo de trabajo Estado de ingesta

    Notificaciones de ingesta dinámica

    El servicio de notificaciones de ingesta dinámica le envía notificaciones para varios tipos de eventos. Los dos que son más útiles para averiguar cuándo el vídeo está «listo» son aquellos que indican que se han creado copias particulares y la que indica que todo el procesamiento está completo. Aquí hay ejemplos de cada uno:

    Notificación creada por representación dinámica

        {
          "entity": "default/video3800",
          "entityType": "DYNAMIC_RENDITION",
          "version": "1",
          "action": "CREATE",
          "jobId": "d3ef8751-2b88-4141-95d5-83f0393aca07",
          "videoId": "5660367449001",
          "dynamicRenditionId": "default\/video3800",
          "bitrate": 3804,
          "width": 1920,
          "height": 1080,
          "accountId": "57838016001",
          "status": "SUCCESS"
        }
        
        
    Notificación de copia creada

    Tenga en cuenta en este ejemplo:

    • El valor le permite saber para qué video es la copia (en caso de que tenga varios trabajos de ingesta ejecutándose)videoId
    • El entity valor es el tipo de copia dinámica creado
    • si el status valor es «SUCCESS», la copia se creó correctamente

    Procesando notificación completa

        {
          "entity": "5660367449001",
          "entityType": "TITLE",
          "version": "1",
          "action": "CREATE",
          "jobId": "d3ef8751-2b88-4141-95d5-83f0393aca07",
          "videoId": "5660367449001",
          "accountId": "57838016001",
          "status": "SUCCESS"
        }
        
        
    Notificación para el procesamiento completado

    Tenga en cuenta en este ejemplo:

    • los videoId y jobId los valores le permiten saber para qué video es esto (en caso de que tenga varios trabajos de ingesta en ejecución)
    • Si el status valor es «SUCCESS», el vídeo se procesó correctamente

    Para recibir notificaciones, debe incluir un campo de «devoluciones de llamada» en sus solicitudes, apuntando a una o más direcciones de devolución de llamada:Dynamic Ingest API

        {
          "master": {
          "url": "https://s3.amazonaws.com/bucket/mysourcevideo.mp4"
          }, "profile": "multi-platform-extended-static",
          "callbacks": ["http://host1/path1”, “http://host2/path2”]
        }
        
        

    Panel de ejemplo

    En esta sección se explica cómo se pueden juntar las notificaciones para crear un panel simple para la API de ingesta dinámica. El controlador de notificaciones analiza las notificaciones del para identificar el procesamiento de notificaciones completas.Dynamic Ingest API A continuación, agrega las notificaciones de vídeo en una matriz de objetos para cada vídeo en un archivo JSON. El tablero en sí es una página HTML que importa el archivo JSON para obtener los datos de notificación. Utiliza los identificadores para realizar una solicitud a la API de CMS para obtener los metadatos de vídeo.

    Aquí está la arquitectura de alto nivel de la aplicación:

    Arquitectura de tablero de
    Arquitectura de tablero de

    Las partes de la aplicación

    El controlador de notificaciones está construido en PHP - busca procesar notificaciones completas y agrega el id de video a una matriz en un archivo JavaScript separado:

        <?PHP
          //POST no funcionará para los datos JSON
          $problem = «Sin errores»;
          probar {
            $json = file_get_contents ('php: //input');
            $decodificado = json_decode ($json, true);
          } captura (Excepción $e) {
            $problema = $e- > getMessage ();
            echo $problema;
          }
    
          //notificación completa
          $notification = json_encode ($decodificado, JSON_PRETTY_PRINT);
    
          //Empezar por extraer las partes útiles de la notificación
          //para Entrega dinámica, busque 'VideoID'
          //para el sistema de ingesta heredado, el id de vídeo es la 'entidad'
    
          if (isset ($decodificado ["VideoID"])) {
            $videoID = $decodificado ["VideoID"];
          } elseif (isset ($decodificado ["entidad"]) {
            $VideoID = $decodificado ["entidad"];
          } else {
            $videoID = nulo;
          }
    
          if (isset ($decodificado ["EntityType"])) {
            $entityType = $decodificado ["EntityType"];
          } else {
            $entityType = nulo;
          }
    
          if (isset ($decodificado ["status"]) {
            $status = $decodificado ["estado"];
          } else {
            $status = nulo;
          }
    
          if (isset ($decodificado ["acción"])) {
            $action = $decodificado ["acción"];
          } else {
            $action = nulo;
          }
    
          //si la notificación es para el título completado, actúe
    
          if (($entityType == 'TITLE') && ($action == 'CREATE')) {
            if (($status == 'SUCCESS') || ($status == 'FAILED')) {
              $newLine = «\ nVideoIDarray.unShift (».$VideoID.«);»;
              //Dile a PHP dónde puede encontrar el archivo de registro y decirle a PHP que lo abra
              //y añadimos la cadena que creamos anteriormente.
              $LogFileLocation = "video-ids.js «;
              $fileHandle = fopen ($logFileLocation, 'a') o die («-1");
              chmod ($LogFileLocation, 0777);
              fwrite ($FileHandle, $NewLine);
              fclose ($FileHandle);
            }
          }
    
          //guardar la notificación completa para la pista de auditoría
          $LogEntry = $notificación.»,\ n»;
    
          $LogFileLocation = "full-log.txt «;
          $fileHandle = fopen ($logFileLocation, 'a') o die («-1");
          chmod ($LogFileLocation, 0777);
          fwrite ($FileHandle, $LogEntry);
          fclose ($FileHandle);
    
    
          echo «La aplicación de devolución de llamada de ingesta dinámica se está ejecutando»;
          ?>
          
          

    Archivo JSON:

    El archivo JSON es inicialmente una matriz vacía ( [] ) : los datos son agregados por el controlador de notificaciones.

    Panel de control

    El panel incluye el HTML y JavaScript para obtener los datos de notificación y datos de vídeo adicionales de la y escribir los resultados en una tabla:CMS API

          <!DOCTYPE html>
          <html>
          <head>
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
            <title>Dynamic Ingest Log</title>
            <style>
            body {
            font-family: sans-serif;
            margin: 5em;
            }
            .hide {
            display: none;
            }
            .show {
            display: block;
            }
            table {
            border-collapse: collapse;
            border: 1px #999999 solid;
            }
            th {
            background-color: #666666;
            color: #f5f5f5;
            padding: .5em;
            font-size: .7em;
            }
            td {
            border: 1px #999999 solid;
            font-size: .7em;
            padding: .5em
            }
            .hidden {
            display: none;
            }
            </style>
          </head>
          <body>
            <h1>Dynamic Ingest Log</h1>
            <h2>Account: Brightcove Learning (57838016001)</h2>
            <p style="width:70%">
              Videos are listed in order of processing completion time, newest to oldest. The reference id (generated by the <a href="./di-tester.html">Dynamic Ingest tester</a>) is a combination of the date/time that the Dynamic Ingest job was initiated and the ingest profile that was used. You can add additional videos using the <a href="./di-tester.html">Dynamic Ingest tester</a>. New videos will appear in this log after processing is complete.
            </p>
            <p>
              <button id="clearLogBtn">Clear the log</button>
            </p>
            <div id="videoLogBlock">
              <table>
                <thead>
                  <tr>
                    <th>Video ID</th>
                    <th>Name</th>
                    <th>Reference ID</th>
                    <th>Renditions Created</th>
                    <th>Processing Complete</th>
                  </tr>
                </thead>
                <tbody id="logBody"></tbody>
              </table>
              <h4 id="loadingMessage">Loading data, please wait...</h4>
            </div>
            <script>
            var BCLS = ( function (window, document) {
              // to use another account, set the account_id value appropriately
              // the client_id and client_secret will also need to be changed in the proxy
              var my_account_id = 57838016001,
                account_id = my_account_id,
                logBody = document.getElementById('logBody'),
                loadingMessage = document.getElementById('loadingMessage'),
                clearLogBtn = document.getElementById('clearLogBtn'),
                i = 0,
                iMax,
                // set the proxyURL to the location of the proxy app that makes Brightcove API requests
                proxyURL = './brightcove-learning-proxy.php',
                dataFileURL = './di.json',
                videoDataArray = [],
                requestOptions = {},
                currentVideo,
                currentIndex = 0;
              /**
              * tests for all the ways a variable might be undefined or not have a value
              * @param {*} x the variable to test
              * @return {Boolean} true if variable is defined and has a value
              */
              function isDefined(x) {
                if ( x === '' || x === null || x === undefined || x === NaN) {
                return false;
              }
              return true;
              }
              /**
              * find index of an object in array of objects
              * based on some property value
              *
              * @param {array} targetArray - array to search
              * @param {string} objProperty - object property to search
              * @param {string|number} value - value of the property to search for
              * @return {integer} index of first instance if found, otherwise returns null
              */
              function findObjectInArray(targetArray, objProperty, value) {
                var i, totalItems = targetArray.length, objFound = false;
                for (i = 0; i < totalItems; i++) {
                  if (targetArray[i][objProperty] === value) {
                    objFound = true;
                    return i;
                  }
                }
                if (objFound === false) {
                  return null;
                }
              }
              /**
              * factory for new video objects
              * @param {String} videoId the video id
              * @return {object} the new object
              */
              function makeVideoDataObject(videoId) {
                var obj = {};
                obj.id = videoId;
                obj.name = '';
                obj.reference_id = '';
                obj.renditions = 0;
                obj.complete = 'no';
                return obj;
              }
              /**
              * processes notification objects
              * creates a new object in the videoDataArray if it doesn't exist
              * and updates the videoDataArray object based on the notification
              * @param {Object} notificationObj the raw notification object
              */
              function processNotification(notificationObj) {
                var objIndex, videoObj;
                // if notification object contains a video id, find the corresponding
                // object in the videoDataArray or create it if it's not there
                if (isDefined(notificationObj) && isDefined(notificationObj.videoId)) {
                  objIndex = findObjectInArray(videoDataArray, 'id', notificationObj.videoId);
                  // if not found, create one
                  if (!isDefined(objIndex)) {
                    videoObj = makeVideoDataObject(notificationObj.videoId);
                    videoDataArray.push(videoObj);
                    objIndex = videoDataArray.length - 1;
                  }
                  // now update properties based on what's in the notification
                  if (notificationObj.entityType === 'DYNAMIC_RENDITION') {
                    // increment the renditions account
                    videoDataArray[objIndex].renditions++;
                  }
                } else if (notificationObj.entityType === 'TITLE') {
                  // overall processing notification - checked for SUCCESS / FAILED
                  if (notificationObj.status === 'SUCCESS') {
                    // mark complete
                    videoDataArray[objIndex].complete = 'yes';
                  } else if (notificationObj.status === 'FAILED') {
                    // mark failed
                    videoDataArray[objIndex].complete = 'failed';
                  }
                }
                return;
              }
              /**
              * creates the dashboard table body
              */
              function writeReport() {
                var j,
                  jMax = videoDataArray.length,
                  item,
                  t;
                loadingMessage.textContent = 'This page will refresh in 1 minute...';
                for (j = 0; j < jMax; j++) {
                  item = videoDataArray[j];
                  if (item.id !== undefined) {
                    logBody.innerHTML += '<tr><td>' + item.id + '</td><td>' + item.name + '</td><td>' + item.reference_id + '</td><td>' + item.renditions + '</td><td>' + item.complete + '</td></tr>';
                  }
                }
                // set timeout for refresh
                t = window.setTimeout(init, 60000);
              };
              // function to set up the notification data request
              function setJSONRequestOptions() {
                submitRequest(null, dataFileURL, 'notificationData');
              }
              // function to set up video data request
              function setVideoRequestOptions() {
                requestOptions = {};
                requestOptions.url = 'https://cms.api.brightcove.com/v1/accounts/' + account_id + '/videos/' + currentVideo.id;
                submitRequest(requestOptions, proxyURL, 'video');
              }
              /**
              * initiates the CMS API requests
              */
              function getVideoInfo() {
                iMax = videoDataArray.length;
                if (currentIndex < iMax) {
                  currentVideo = videoDataArray[currentIndex];
                  setVideoRequestOptions();
                } else {
                  loadingMessage.innerHTML = 'No videos have been ingested - you can add some using the <a href="./di-tester.html">Dynamic Ingest tester</a>';
                }
              }
              /**
              * make the CMS API requests
              * @param {Object} options request options
              * @param (String) url URL to send request to
              * @param (String) type the request type
              */
              function submitRequest(options, url, type) {
                var httpRequest = new XMLHttpRequest(),
                  requestData,
                  responseData,
                  videoDataObject,
                  parsedData,
                  getResponse = function () {
                  try {
                    if (httpRequest.readyState === 4) {
                      if (httpRequest.status === 200) {
                        responseData = httpRequest.responseText;
                        switch (type) {
                          case 'notificationData':
                              var k, kMax, dataArray;
                              dataArray = JSON.parse(responseData);
                              // process the notifications
                              kMax = dataArray.length;
                              for (k = 0; k < kMax; k++) {
                              processNotification(dataArray[k]);
                            }
                            getVideoInfo();
                            break;
                          case 'video':
                            parsedData = JSON.parse(responseData);
                            videoDataArray[currentIndex].reference_id = parsedData.reference_id;
                            videoDataArray[currentIndex].name = parsedData.name;
                            currentIndex++;
                            if (currentIndex < iMax) {
                            currentVideo = videoDataArray[currentIndex];
                            setVideoRequestOptions();
                            } else {
                            writeReport();
                            }
                            break;
                        }
                      } else {
                        console.log('There was a problem with the request. Request returned '', httpRequest.status);
                        if (type === 'video') {
                          setVideoRequestOptions();
                        } else {
                          setSourcesRequestOptions();
                        }
                      }
                    }
                  }
                  catch(e) {
                  console.log('Caught Exception: ', e);
                  }
                };
                // notifications data is a special case
                if (type === 'notificationData') {
                  // set response handler
                  httpRequest.onreadystatechange = getResponse;
                  // open the request
                  httpRequest.open("GET", url);
                  // set headers
                  httpRequest.setRequestHeader("Content-Type", "application/json");
                  // open and send request
                  httpRequest.send();
                } else {
                  // requests via proxy
                  // set up request data
                  requestData = "url=" + encodeURIComponent(options.url) + "&requestType=GET";
                  // set response handler
                  httpRequest.onreadystatechange = getResponse;
                  // open the request
                  httpRequest.open("POST", url);
                  // set headers
                  httpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
                  // open and send request
                  httpRequest.send(requestData);
                }
              };
              // event handlers
              clearLogBtn.addEventListener('click', function () {
                if (window.confirm('Are you sure? This action cannot be undone!')) {
                // if your clear-log app resides in another location, change the URL
                window.location.href = 'clear-log.php';
                }
              });
              // get things started
              function init() {
                // clear table and the video data array
                logBody.innerHTML = "";
                videoDataArray = [];
                setJSONRequestOptions();
              }
              // kick off the app
              init();
            })(window, document);
            </script>
          </body>
        </html>
        
        

    Proxy

        <?PHP
        /**
        * brightcove-learning-proxy.php - proxy para las API RESTful de Brightcove
        * obtiene un token de acceso, hace la solicitud y devuelve la respuesta
        * Accediendo a:
        * URL: https://solutions.brightcove.com/bcls/bcls-proxy/bcsl-proxy.php
        * (tenga en cuenta que debe *siempre* acceder al proxy a través de HTTPS)
        * Método: PUBLICAR
        *
        * @post {string} url - la URL para la solicitud de API
        * @post {string} [requestType=Get] - Método HTTP para la solicitud
        * @post {string} [requestBody=NULL] - Datos JSON que se enviarán con solicitudes de escritura
        *
        * @returns {string} $response - respuesta JSON recibida de la API
        */
        //Cors entablement
        encabezado («Access-Control-Allow-Origin: *»);
        //configuramos la solicitud de token de acceso
        $data = array ();
        //
        //cambiar los valores a continuación para usar este proxy con una cuenta diferente
        //
        $client_id = «YOUR_CLIENT_ID_AQUÍ»;
        $client_secret = «YOUR_CLIENT_SECRET_HERE»;
        $auth_string = «{$client_id}: {$client_secret}»;
        $request = "https://oauth.brightcove.com/v4/access_token?grant_type=client_credentials «;
        $ch = curl_init ($solicitud);
        curl_setopt_array($ch, array(
        CURLOPT_POST           => TRUE,
        CURLOPT_RETURNTRANSFER => TRUE,
        CURLOPT_SSL_VERIFYPEER => FALSE,
        CURLOPT_USERPWD        => $auth_string,
        CURLOPT_HTTPHEADER     => array(
        'Tipo de contenido: application/x-www-form-urlencoded',
        ),
        CURLOPT_POSTFIELDS => $data
        ));
        $ respuesta = curl_exec ($ch);
        curl_close($ch);
        //Comprobación de errores
        if ($response === FALSE) {
        die (curl_error ($ch));
        }
        //Decodificar la respuesta
        $responseData = json_decode ($respuesta, TRUE);
        $access_token = $responseData ["access_token"];
        //configuramos la llamada API
        //obtener datos
        if ($_POST ["requestBody"]) {
        $data = json_decode ($_POST ["requestBody"]);
        } else {
        $data = array ();
        }
        //obtener el tipo de solicitud o por defecto a GET
        if ($_POST ["RequestType"]) {
        $method = $_POST ["RequestType"];
        } else {
        $método = «GET»;
        }
        //obtener la URL y la información de autorización de los datos del formulario
        $request = $_POST ["url"];
        //enviar la solicitud http
        $ch = curl_init ($solicitud);
        curl_setopt_array($ch, array(
        CURLOPT_CUSTOMREQUEST  => $method,
        CURLOPT_RETURNTRANSFER => TRUE,
        CURLOPT_SSL_VERIFYPEER => FALSE,
        CURLOPT_HTTPHEADER     => array(
        «Tipo de contenido: application/json»,
        «Autorización: Portador {$access_token}»,
        ),
        CURLOPT_POSTFIELDS => json_encode($data)
        ));
        $ respuesta = curl_exec ($ch);
        curl_close($ch);
        //Comprobación de errores
        if ($response === FALSE) {
        echo «Error: «+$response;
        die (curl_error ($ch));
        }
        //Decodificar la respuesta
        //$responseData = json_decode ($response, TRUE);
        //devuelve la respuesta al llamador AJAX
        echo $respuesta;
        ?>
        
        

    Borrar el registro

    Esta sencilla aplicación PHP simplemente restaura el archivo JavaScript a su estado original, eliminando los identificadores de video antiguos:

        <?PHP
        $logFileLocation = «di.json»;
        $FreshContent = array ();
        $encodedContent = json_encode ($FreshContent);
        file_put_contents ($LogFileLocation, $EncodedContent);
        echo 'Archivo de registro borrado - < a href=» di-log.html "> volver al tablero < /a > ';
        ?>
        
        

    Última actualización de la página el 22 oct 2020