지원 지원 문의 | 시스템 상태 시스템 상태
페이지 내용

    동적 인출 요청 상태 가져 오기

    귀하가 Dynamic Ingest API 동영상을 내 동영상에 추가하려면 Video Cloud 계정을 가장 잘 알고 싶은 것은 비디오가 처리 된 시점과 변환이 성공적으로 만들어 졌는지 여부입니다.

    소개

    이 문서에서는 상태 요청을 CMS API 또는 Dynamic Ingest API 알림. 또한 프로세스를 자동화하는 샘플 대시 보드 앱을 제공합니다.

    인제 스 작업의 상태는 지난 7 일 동안 제출 된 작업에서만 사용할 수 있습니다.

    요청 상태

    다음을 사용하여 동적 인제 스트 작업 상태 (가져 오기, 바꾸기 또는 다시 코드)를 얻습니다. 이들 CMS API 엔드 포인트 -이 끝점은 동적 배달 작업 전용:

    모든 작업에 대한 상태 가져 오기

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

    응답은 다음과 같이 보입니다.

         [
          {
            "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"
          }
        ]

    특정 작업에 대한 상태 가져 오기

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

    응답은 다음과 같이 보입니다.

        {
            "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"
          }

    가능한 값은 다음과 같습니다. state 위치 :

    • processing: 처리 중, 비디오를 아직 재생할 수 없습니다.
    • publishing: 재생 가능한 변환이 하나 이상 만들어졌으며 재생을 위해 비디오를 준비 중입니다.
    • published: 적어도 하나의 렌 디션을 재생에 사용할 수 있습니다.
    • finished: 모든 처리가 완료되었습니다.
    • failed: 처리가 실패했습니다. 무엇이 잘못되었는지 파악할 수없는 경우 지원부에 문의하십시오.

    알림 받기

    위에 설명 된 요청 상태 방법이 작동하는 동안 특정 상태 (예 :published or finished)를 찾는 경우 원하는 응답을 얻을 때까지 상태를 계속 묻지 않고 이러한 이벤트가 발생하면 Brightcove에 알리는 것이 좋습니다. 이제 알림 처리와 관련하여 앱을 빌드하는 방법을 살펴 보겠습니다.

    다이내믹 인게 스트 알림은 비디오 준비가 완료되었을 때 알아야 할 모든 정보를 제공합니다. 뭘 찾아야할지 알려주고 시스템에 어떤 의미가 있는지를 정의해야합니다. 이 다이어그램은 워크 플로를 요약합니다.

    인게 스트 상태 워크 플로
    인게 스트 상태 워크 플로

    동적 인게이션 알림

    Dynamic Ingest 알림 서비스는 몇 가지 종류의 이벤트에 대한 알림을 보냅니다. 비디오가 "준비"상태 일 때 알아내는 데 가장 유용한 두 가지는 특정 표현이 만들어 졌음을 나타내는 것과 모든 처리가 완료되었음을 나타내는 것입니다. 다음은 각각의 예입니다.

    동적 렌더링 생성 알림

        {
          "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"
        }
        
        
    생성 된 렌 디션에 대한 알림

    이 예제의 참고 사항 :

    • 그리고, videoId 값을 사용하면 렌 디션이 어떤 비디오인지 알 수 있습니다 (여러 인제 스트 작업이 실행중인 경우)
    • 그리고, entity 값은 생성 된 동적 렌 디션 유형입니다.
    • 경우 status 값이 "SUCCESS"이면 렌 디션이 성공적으로 작성되었습니다.

    처리 완료 통지

        {
          "entity": "5660367449001",
          "entityType": "TITLE",
          "version": "1",
          "action": "CREATE",
          "jobId": "d3ef8751-2b88-4141-95d5-83f0393aca07",
          "videoId": "5660367449001",
          "accountId": "57838016001",
          "status": "SUCCESS"
        }
        
        
    처리 완료 알림

    이 예제의 참고 사항 :

    • 그리고, videoId jobId 값을 사용하여 어떤 비디오인지를 알 수 있습니다 (여러 인제 스트 작업이 실행중인 경우)
    • 경우 status 값이 "SUCCESS"이면 동영상이 성공적으로 처리되었습니다.

    알림을 받으려면 '콜백'입력란을 포함해야합니다. Dynamic Ingest API 하나 이상의 콜백 주소를 가리키는 요청 :

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

    샘플 대시 보드

    이 섹션에서는 알림을 결합하여 간단한 대시 보드를 작성하는 방법에 대해 설명합니다. Dynamic Ingest API. 알림 처리기는 Dynamic Ingest API 처리 완료 알림을 식별합니다. 그런 다음 비디오 알림을 JSON 파일의 각 비디오에 대한 객체 배열에 추가합니다. 대시 보드 자체는 JSON 파일을 가져 와서 알림 데이터를 가져 오는 HTML 페이지입니다. ID를 사용하여 CMS API 동영상 메타 데이터를 가져옵니다.

    다음은 앱의 고수준 아키텍처입니다.

    수집 대시 보드 아키텍처
    수집 대시 보드 아키텍처

    앱 부품

    알림 처리기는 PHP로 작성되었습니다. 완전한 알림 처리를 찾고 비디오 ID를 별도의 JavaScript 파일에 배열에 추가합니다.

        <?php
          // POST won't work for JSON data
          $problem = "No errors";
          try {
            $json    = file_get_contents('php://input');
            $decoded = json_decode($json, true);
          } catch (Exception $e) {
            $problem = $e->getMessage();
            echo $problem;
          }
        
          // full notification
          $notification = json_encode($decoded, JSON_PRETTY_PRINT);
        
          // Begin by extracting the useful parts of the notification
          // for Dynamic Delivery, look for 'videoId'
          // for the legacy ingest system, the video id is the 'entity'
        
          if (isset($decoded["videoId"])) {
            $videoId = $decoded["videoId"];
          } elseif (isset($decoded["entity"])) {
            $videoId = $decoded["entity"];
          } else {
            $videoId = null;
          }
        
          if (isset($decoded["entityType"])) {
            $entityType = $decoded["entityType"];
          } else {
            $entityType = null;
          }
        
          if (isset($decoded["status"])) {
            $status = $decoded["status"];
          } else {
            $status = null;
          }
        
          if (isset($decoded["action"])) {
            $action = $decoded["action"];
          } else {
            $action = null;
          }
        
          // if notification is for completed title, act
        
          if (($entityType == 'TITLE') && ($action == 'CREATE')) {
            if (($status == 'SUCCESS') || ($status == 'FAILED')) {
              $newLine = "\nvideoIdArray.unshift(".$videoId.");";
              // Tell PHP where it can find the log file and tell PHP to open it
              // and add the string we created earlier to it.
              $logFileLocation = "video-ids.js";
              $fileHandle      = fopen($logFileLocation, 'a') or die("-1");
              chmod($logFileLocation, 0777);
              fwrite($fileHandle, $newLine);
              fclose($fileHandle);
            }
          }
        
          // save full notification for audit trail
          $logEntry = $notification.",\n";
        
          $logFileLocation = "full-log.txt";
          $fileHandle      = fopen($logFileLocation, 'a') or die("-1");
          chmod($logFileLocation, 0777);
          fwrite($fileHandle, $logEntry);
          fclose($fileHandle);
        
        
          echo "Dynamic Ingest callback app is running";
          ?>
          
          

    JSON 파일 :

    JSON 파일은 처음에는 빈 배열입니다 ( [] ) - 데이터는 알림 처리기에 의해 추가됩니다.

    대시보드

    대시 보드에는 알림 데이터 및 추가 비디오 데이터를 가져 오는 HTML과 JavaScript가 포함되어 있습니다. 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>
        
        

    대리

        <?php
        /**
        * brightcove-learning-proxy.php - proxy for Brightcove RESTful APIs
        * gets an access token, makes the request, and returns the response
        * Accessing:
        *     URL: https://solutions.brightcove.com/bcls/bcls-proxy/bcsl-proxy.php
        *         (note you should *always* access the proxy via HTTPS)
        *     Method: POST
        *
        * @post {string} url - the URL for the API request
        * @post {string} [requestType=GET] - HTTP method for the request
        * @post {string} [requestBody=null] - JSON data to be sent with write requests
        *
        * @returns {string} $response - JSON response received from the API
        */
        // CORS entablement
        header("Access-Control-Allow-Origin: *");
        // set up request for access token
        $data = array();
        //
        // change the values below to use this proxy with a different account
        //
        $client_id     = "YOUR_CLIENT_ID_HERE";
        $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($request);
        curl_setopt_array($ch, array(
        CURLOPT_POST           => TRUE,
        CURLOPT_RETURNTRANSFER => TRUE,
        CURLOPT_SSL_VERIFYPEER => FALSE,
        CURLOPT_USERPWD        => $auth_string,
        CURLOPT_HTTPHEADER     => array(
        'Content-type: application/x-www-form-urlencoded',
        ),
        CURLOPT_POSTFIELDS => $data
        ));
        $response = curl_exec($ch);
        curl_close($ch);
        // Check for errors
        if ($response === FALSE) {
        die(curl_error($ch));
        }
        // Decode the response
        $responseData = json_decode($response, TRUE);
        $access_token = $responseData["access_token"];
        // set up the API call
        // get data
        if ($_POST["requestBody"]) {
        $data = json_decode($_POST["requestBody"]);
        } else {
        $data = array();
        }
        // get request type or default to GET
        if ($_POST["requestType"]) {
        $method = $_POST["requestType"];
        } else {
        $method = "GET";
        }
        // get the URL and authorization info from the form data
        $request = $_POST["url"];
        //send the http request
        $ch = curl_init($request);
        curl_setopt_array($ch, array(
        CURLOPT_CUSTOMREQUEST  => $method,
        CURLOPT_RETURNTRANSFER => TRUE,
        CURLOPT_SSL_VERIFYPEER => FALSE,
        CURLOPT_HTTPHEADER     => array(
        'Content-type: application/json',
        "Authorization: Bearer {$access_token}",
        ),
        CURLOPT_POSTFIELDS => json_encode($data)
        ));
        $response = curl_exec($ch);
        curl_close($ch);
        // Check for errors
        if ($response === FALSE) {
        echo "Error: "+$response;
        die(curl_error($ch));
        }
        // Decode the response
        // $responseData = json_decode($response, TRUE);
        // return the response to the AJAX caller
        echo $response;
        ?>
        
        

    로그 지우기

    이 간단한 PHP 응용 프로그램은 JavaScript 파일을 원래 상태로 복원하여 이전 비디오 ID를 지 웁니다.

        <?php
        $logFileLocation = "di.json";
        $freshContent = array ();
        $encodedContent = json_encode($freshContent);
        file_put_contents($logFileLocation, $encodedContent);
        echo 'Log file cleared - <a href="di-log.html">go back to the dashboard</a>';
        ?>
        
        

    19 년 2020 월 XNUMX 일에 마지막으로 업데이트 된 페이지