サポート サポートへのお問い合わせ | システムステータス システムステータス
ページコンテンツ

    動的取り込み要求のステータスを取得する

    を使用して Video Cloud アカウントにビデオを追加する場合、ビデオが処理された日時、およびレンディションが正常に作成されたかどうかについて知っておきたいことがあります。Dynamic Ingest API

    はじめに

    このドキュメントでは、にステータスリクエストを送信することで、ジョブのステータスを追跡する方法について説明します。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:少なくとも1つの再生可能なレンディションが作成され、ビデオを再生する準備ができています
    • published:少なくとも1つのレンディションが再生可能です
    • finished:少なくとも1つのオーディオ/ビデオレンディションが処理されました
    • failed:処理に失敗しました。何が悪かったのかわからない場合は、サポートに連絡してください

    通知を受け取る

    上記のリクエストステータスメソッドは機能しますが、特定の状態を待機している場合(publishedまたはfinished)、探している答えが得られるまでステータスを尋ね続けるよりも、これらのイベントが発生したときにBrightcoveに通知させる方がよいでしょう。次に、通知の処理を中心にアプリを構築する方法を見ていきます。

    動的取り込み通知は、動画の準備ができたときに知っておく必要があるすべての情報を提供します。必要な情報を把握し、システムの「準備完了」の意味を定義する必要があります。次の図に、ワークフローの概要を示します。

    取り込みステータスのワークフロー
    取り込みステータスのワークフロー

    動的取り込み通知

    動的取り込み通知サービスは、いくつかの種類のイベントについて通知を送信します。ビデオが「準備完了」であるかどうかを判断するのに最も役立つ2つは、特定のレンディションが作成されたことを示すものと、すべての処理が完了したことを示すものです。それぞれの例を次に示します。

    動的レンディション作成通知

        {
          "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リクエストに「コールバック」フィールドを含めて、1つ以上のコールバックアドレスを指す必要があります。

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

    サンプルダッシュボード

    このセクションでは、通知をまとめてDynamic IngestAPIのシンプルなダッシュボードを構築する方法について説明します。通知のハンドラは、Dynamic Ingest APIからの通知を解析して、処理が完了した通知を識別します。次に、JSON ファイルの各動画のオブジェクトの配列にビデオ通知を追加します。ダッシュボード自体は、JSON ファイルをインポートして通知データを取得する HTML ページです。この ID を使用して CMS API にリクエストを行い、ビデオのメタデータを取得します。

    アプリの高レベルのアーキテクチャは次のとおりです。

    ダッシュボードアーキテクチャを取り込み
    ダッシュボードアーキテクチャを取り込み

    アプリのパーツ

    通知のハンドラは、PHPに組み込まれています-それは完全な通知を処理し、別のJavaScriptファイル内の配列にビデオIDを追加します。

         <?php
          //POST は JSON データでは機能しません
          $problem = "No errors";
          try {
            $json    = file_get_contents('php://input');
            $decoded = json_decode($json, true);
          } キャッチ(例外 $e){
            $problem = $e->getMessage();
            エコー$問題;
          }
    
          //完全な通知
          $notification = json_encode($decoded, JSON_PRETTY_PRINT);
    
          //通知の有用な部分を抽出することから始めます
          //動的配信の場合は、「videoId」を探します
          //レガシー取り込みシステムの場合、ビデオIDは「エンティティ」です
    
          if(isset($ decode ["videoId"])){
            $ videoId = $ decode ["videoId"];
          } elseif(isset($ decode ["entity"])){
            $ videoId = $ decode ["entity"];
          } else {
            $ videoId = null;
          }
    
          (isset ($デコード ["entityType"])) {
            $entityType = $decoded["entityType"];
          } else {
            $ entityType = null;
          }
    
          if(isset($ decode ["status"])){
            $ status = $ decode ["status"];
          } else {
            $ status = null;
          }
    
          if(isset($ decode ["action"])){
            $ action = $ decode ["action"];
          } else {
            $ action = null;
          }
    
          //完了したタイトルに関する通知の場合は、行動します
    
          if(($ entityType == 'TITLE')&&($ action == 'CREATE')){
            if(($ status == 'SUCCESS')||($ status == 'FAILED')){
              $ newLine = "\\ nvideoIdArray.unshift("。$ videoId。 ");";
              //PHPにログファイルがある場所を指示し、PHPにそれを開くように指示する
              //先ほど作成した文字列をそれに追加します。
              $ logFileLocation = "video-ids.js";
              $fileHandle      = fopen($logFileLocation, 'a') or die("-1");
              chmod ($logfileLocation, 0777);
              fwrite($ fileHandle、$ newLine);
              fclose ($fileHandle);
            }
          }
    
          //監査証跡の完全な通知を保存します
          $ logEntry = $ notification。 "、\\ n";
    
          $ logFileLocation = "full-log.txt";
          $fileHandle      = fopen($logFileLocation, 'a') or die("-1");
          chmod ($logfileLocation, 0777);
          fwrite ($fileHandle, $logEntry);
          fclose ($fileHandle);
    
    
          echo「動的取り込みコールバックアプリが実行されています」;
          ?>
          
          

    JSON ファイル:

    JSONファイルは最初は空の配列です([] )-データは通知ハンドラーによって追加されます。

    ダッシュボード

    ダッシュボードには、から通知データと追加のビデオデータを取得し、結果をテーブルに書き込むための HTML CMS APIと JavaScript が含まれています。

          <!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-Brightcove ブ RESTful API 用プロキシ
        * アクセストークンを取得し、リクエストを行い、レスポンスを返す
        * アクセス:
        * URL: https://solutions.brightcove.com/bcls/bcls-proxy/bcsl-proxy.php
        *(HTTPS経由でプロキシにアクセスする必要があることに注意してください)
        * 方法:役職
        *
        * @post {文字列} url-APIリクエストのURL
        * @post {文字列} [requestType=Get]-リクエストのHTTPメソッド
        * @post {文字列} [requestBody=Null]-書き込みリクエストで送信されるJSONデータ
        *
        * @returns {文字列} $response-APIから受け取ったJSONレスポンス
        */
        // CORSエンタブラチュア
        ヘッダー (「アクセス制御許可オリジン:*」);
        //アクセストークンのリクエストを設定する
        $data = array();
        //
        //別のアカウントでこのプロキシを使用するには、以下の値を変更します
        //
        $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, 配列 (
        CURLOPT_POST = > 真、
        CURLOPT_RETURNTRANSFER = > 真、
        CURLOPT_SSL_VERIFYPEER = > 偽、
        CURLOPT_USERPWD = > $auth_string、
        CURLOPT_HTTPHEADER = > 配列 (
        'コンテンツタイプ:アプリケーション/X-www-form-urlencoded',
        )、
        CURLOPT_POSTFIELDS = > $データ
        )));
        $response = curl_exec($ch);
        curl_close ($ch);
        //エラーをチェックする
        ($応答=== 偽) {
        死ぬ (curl_error ($ch));
        }
        //レスポンスをデコードする
        $responseData = json_decode($response, TRUE);
        $access_token = $responseData["access_token"];
        //API 呼び出しを設定する
        //データを取得する
        ($_POST ["requestBody"]) {
        $data = json_decode($_POST["requestBody"]);
        } else {
        $data = array();
        }
        //リクエストタイプを取得するか、デフォルトで GET
        ($_POST ["requestType"]) {
        $method = $_POST["requestType"];
        } else {
        $method = "GET";
        }
        //フォームデータから URL と認証情報を取得
        $request = $_POST["url"];
        //httpリクエストを送る
        $ch = curl_init($request);
        curl_setopt_array ($ch, 配列 (
        CURLOPT_CUSTOMREQUEST = > $メソッド、
        CURLOPT_RETURNTRANSFER = > 真、
        CURLOPT_SSL_VERIFYPEER = > 偽、
        CURLOPT_HTTPHEADER = > 配列 (
        'コンテンツタイプ:アプリケーション/JSON ',
        「認証:ベアラー {$access_token}」,
        )、
        >CURLOPT_POSTFIELDS = json_encode ($データ)
        )));
        $response = curl_exec($ch);
        curl_close ($ch);
        //エラーをチェックする
        ($応答=== 偽) {
        エコー「エラー:「+$応答;
        死ぬ (curl_error ($ch));
        }
        //レスポンスをデコードする
        //$responseData = json_decode ($レスポンス、真);
        //AJAX 呼び出し元にレスポンスを返す
        エコー$レスポンス;
        ?>
        
        

    ログをクリアする

    この単純なPHPアプリは、JavaScriptファイルを元の状態に復元し、古い動画IDをクリアするだけです:

         <?php
        $logFileLocation = "di.json";
        $freshContent = array ();
        $encodedContent = json_encode($freshContent);
        ファイル_put_contents ($logfileLocation, $encodedContent);
        エコー 'ログファイルがクリアされました-< href=」di-log.html「> ダッシュボードに戻る < /a > ';
        ?>