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

    リクエストのステータスを取得

    を使用して Video Cloud アカウントにビデオを追加する場合、ビデオが処理された日時、およびレンディションが正常に作成されたかどうかについて知っておきたいことがあります。Dynamic Ingest APIこのドキュメントでは、を使用してそれを行う方法について説明しますDynamic Ingest API通知。また、プロセスを自動化するサンプルダッシュボードアプリも提供しています。このドキュメントは、従来の取り込みシステムにのみ適用されることに注意してください。動的配信については、を参照してください。動的取り込みリクエストのステータスを取得する

    データの取得

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

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

    動的取り込み通知

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

    レンディション作成通知

        {
            "entity": "5002412132001",
            "profileRefId": "ts7",
            "accountId": "57838016001",
            "entityType": "ASSET",
            "videoId": "5002361893001",
            "status": "SUCCESS",
            "version": "1",
            "action": "CREATE",
            "jobId": "bb316631-c58b-4bd4-a686-13c5f7a3a779"
        }
    レンディション作成の通知

    この例では、次の点に注意してください。

    • videoIdこの値により、レンディションがどのビデオ用であるかを知ることができます (複数のインジェストジョブを実行している場合)
    • ザ・profileRefId valueは、取り込みプロファイルで指定されたレンディションの参照IDです。
    • の場合status値は「SUCCESS」で、レンディションは正常に作成されました
    • HLSやMPEG-DASHのようなセグメント化されたタイプの場合、レンディションが存在しても再生可能にはなりません。適切なマニフェストも必要です(次の例を参照)。MP4レンディトンは、作成されるとすぐに再生できます。

    マニフェストが通知を作成

        {
            "jobId": "31f0b112-9890-4567-adb5-0f4ed1673701",
            "status": "SUCCESS",
            "version": "1",
            "action": "CREATE",
            "entityType": "ASSET",
            "entity": "5002412528001",
            "videoId": "5002361895001",
            "profileRefId": "HlsManifest",
            "accountId": "57838016001"
        }
    マニフェストの通知が作成されました

    この例では、次の点に注意してください。

    • videoIdこの値により、レンディションがどのビデオ用であるかを知ることができます (複数のインジェストジョブを実行している場合)
    • ザ・profileRefId valueは、作成されたアセットがHLSマニフェストであることを通知する特別なコードです(他の可能な値はHdsManifestDashManifest、およびSmoothIsmManifest
    • HLSとHDSの場合、1つのマニフェストが作成されるため、1つの通知が表示されます。DASHとSmoothIsmの場合、2つのマニフェストが作成されるため(1つはレガシーMedia APIで使用し、もう1つはCMS APIで使用します)、このタイプの2つの通知が表示されます。
    • の場合status値は「SUCCESS」で、マニフェストは正常に作成されました
    • HLSやMPEG-DASHのようなセグメント化されたタイプの場合、レンディションとマニフェストを作成するための明確な順序はありません。これらのレンディションは、両方が作成されるまで(または、ビデオが完全に処理されるまで、次の例を参照してください)再生できません。

    完全な通知を処理しています

        {
            "entityType": "TITLE",
            "status": "SUCCESS",
            "accountId": "57838016001",
            "entity": "5002412652001",
            "action": "CREATE",
            "jobId": "3e98b3a0-f624-4f2d-81c1-4e43e1d04a0f",
            "version": "1",
            "videoId": "5002412652001"
        }
    処理完了の通知

    この例では、次の点に注意してください。

    • videoIdこの値により、レンディションがどのビデオ用であるかを知ることができます (複数のインジェストジョブを実行している場合)
    • ザ・profileRefIdですないこの通知に含まれています
    • の場合status値は「SUCCESS」で、ビデオは正常に処理されました

    通知を受け取るには、Dynamic Ingest APIリクエストに「コールバック」フィールドを含めて、1つ以上のコールバックアドレスを指す必要があります。

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

    サンプルダッシュボード

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

    このアプリのすべてのファイルと、アカウント用に設定する手順は次のとおりです。このリポジトリ

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

    ダッシュボードアーキテクチャをインジェスト
    ダッシュボードアーキテクチャをインジェスト

    アプリのパーツ

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

         <?php
        //エラーがある場合はログに記録するvar
        $problem = "No errors";
        //現在のビデオインデックスを保存するvar
        $ videoIndex = -1;
        
        //入力データを取得します
        try {
            $json    = file_get_contents('php://input');
            $decoded = json_decode($json, true);
        } キャッチ(例外 $e){
            $problem = $e->getMessage();
            エコー$問題;
        }
        
        //データファイルの内容を取得して解析します
        try {
            $ notifyData = file_get_contents( 'di.json');
            $ notifyDataDecoded = json_decode($ notifyData、true);
        } キャッチ(例外 $e){
            $problem = $e->getMessage();
            エコー$問題;
        }
        
        
            (isset ($デコード ["entityType"])) {
                $entityType = $decoded["entityType"];
                //エンティティタイプがASSETまたはTITLEの場合、通知データ配列に追加します
                if($ entityType == "ASSET" || $ entityType == "TITLE"){
                    array_push($ notifyDataDecoded、$ decode);
                }
                //ここで、di.jsonの内容を現在の内容に置き換えます
                file_put_contents( 'di.json'、json_encode($ notifyDataDecoded));
        
            }
        
        echo「動的取り込みコールバックアプリが実行されています」;
        var_dump($ notifyData);
        
        ?>
        

    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>HLS Manifests Created</th>
                                <th>HLS Renditions Created</th>
                                <th>MP4 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;
        
                        /**
                         * Logging function - safe for IE
                         * @param  {string} context - description of the data
                         * @param  {*} message - the data to be logged by the console
                         * @return {}
                         */
                        function bclslog(context, message) {
                            if (window["console"] && console["log"]) {
                              console.log(context, message);
                            }
                            return;
                        }
        
                        /**
                         * 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.hlsManifests = 0;
                            obj.hlsRenditions = 0;
                            obj.mp4Renditions = 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 === 'ASSET') {
                                    // if it's a rendition or manifest, there will be a profileRefId
                                    if (isDefined(notificationObj.profileRefId)) {
                                        // see if it's an HLS manifest
                                        if (notificationObj.profileRefId === 'HlsManifest') {
                                            // increment the hls manifest count
                                            videoDataArray[objIndex].hlsManifests++;
                                        } else if (notificationObj.profileRefId.charAt(0) === 't') {
                                            // increment the hls rendition count
                                            videoDataArray[objIndex].hlsRenditions++;
                                        } else if (notificationObj.profileRefId.charAt(0) === 'm') {
                                            // increment the mp4 rendition count
                                            videoDataArray[objIndex].mp4Renditions++;
                                        }
                                    }
                                } 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...';
                            /* just showing HLS and MP4 renditions, because
                             * that's all that will be produced in this account,
                             * but you could modify the notification handler and
                             * this page to handle other formats
                             */
                            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.hlsManifests + '</td><td>' + item.hlsRenditions + '</td><td>' + item.mp4Renditions + '</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);
                                                bclslog('dataArray', dataArray);
                                                // process the notifications
                                                kMax = dataArray.length;
                                                for (k = 0; k < kMax; k++) {
                                                    processNotification(dataArray[k]);
                                                }
                                                getVideoInfo();
                                                break;
                                                case 'video':
                                                parsedData = JSON.parse(responseData);
                                                bclslog('parsedData', parsedData);
                                                videoDataArray[currentIndex].reference_id = parsedData.reference_id;
                                                videoDataArray[currentIndex].name = parsedData.name;
                                                currentIndex++;
                                                if (currentIndex < iMax) {
                                                    currentVideo = videoDataArray[currentIndex];
                                                    setVideoRequestOptions();
                                                } else {
                                                    writeReport();
                                                }
                                                break;
                                            }
                                          } else {
                                            bclslog("There was a problem with the request. Request returned " + httpRequest.status);
                                            if (type === 'video') {
                                                setVideoRequestOptions();
                                            } else {
                                                setSourcesRequestOptions();
                                            }
                                          }
                                        }
                                      }
                                      catch(e) {
                                        bclslog('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 > ';
        ?>