API(Application Programming Interface)は、アプリケーションやデバイス同士がどのように接続し通信するかを定義する一連のルールです。REST(REpresentational State Transfer)API は、特定の設計原則に準拠した API です。REST API は RESTful API と呼ばれることもあります。以下の図はその詳細を示しています:
Brightcove には多数のプラットフォーム RESTful API があり、Video Cloud や Brightcove プレーヤーのほぼすべての機能にプログラム的にアクセスすることができます。通常、これらの API は CMS や他のシステムとの統合を作成したり、ユーザーの特定のニーズに合わせたカスタム アプリを構築するために使用されます。
このドキュメントでは、最初の例として Analytics API を使用し、現在プレーヤー内で再生されている動画の再生回数を Brightcove プレーヤーのコントロールバーに表示する方法を紹介します。2つ目の、やや複雑な例では、Analytics API と Brightcove プレーヤーのカタログを組み合わせて、アカウント内で最も人気のある動画を取得し、プレイリストとして表示します。このドキュメント内のコード解説では、目的のデータを正しい REST API から取得する方法に焦点を当てます。
概要
Brightcove REST API を使用するには、いくつかの要素を準備する必要があります。概要は以下の通りです。
- クライアント コード:クライアント コードは特定のデータを要求し、アプリケーションの要件に従ってそれを表示します。このドキュメントでは、最も頻繁に作成する必要があるこのクライアント コードについて詳しく説明します。
- プロキシ サーバー:セキュリティ上の理由から、REST API はクライアントからのデータ要求を直接受け付けません。これは、クライアント認証情報などの機密情報を送信することを防ぐためです。そのため、プロキシがクライアントと REST API の仲介役を務めます。例で使用されるプロキシは PHP で記述されており、このドキュメントの後半で説明します。プロキシは自分の管理下にあるサーバー上に設定する必要があり、任意の言語で記述できます。推奨される構成では、プロキシを一度作成すればすべての API で使用できるようにします。
- REST API:Brightcove は、Brightcove プラットフォームをカスタマイズ、拡張、統合するための包括的な API セットを提供しています。詳細については、概要:Video Cloud API のドキュメントをご覧ください。
以下の図は、Brightcove の REST API の 1 つからデータを取得する際に、3 つの主要な要素がどのように連携するかを示しています。

クライアント機能の概要
クライアント側のコードは、どの API からデータを取得するかによって大きく変わります。前述のように、プロキシは一度作成すれば変更の必要がないコードであり、API は Brightcove によって管理されています。したがって、このドキュメントでは、特定の API から必要なデータを取得するためにクライアント コードをどのように変更するかを学ぶことに重点を置きます。
以下の図は、クライアント コードの主要な部分に焦点を当てています。
- プロキシへの
HTTPRequestを実行する関数。この関数は曖昧さを避けるためmakeRequest()と名付けられています。図の右側に示されています。 - リクエストに必要な情報を収集するコード。図の左上に示されています。このコードは通常、非常にシンプルで、初心者プログラマーでもよく理解できる概念を使用します。
- 前述の
makeRequest()関数を実行する呼び出し。図の左下に示されています。この呼び出しでは、makeRequest()に関数をパラメーターとして渡します。その後、makeRequest()内でその関数が呼び出されます。これは匿名で定義されたコールバック関数の例です。
図の中で 非同期処理 とラベル付けされた 2 つの部分があります。図上では異なる場所に描かれていますが、実際には同じ非同期処理であり、次の一連の処理にかかる時間が不確定であることを示しています。
- クライアントがプロキシにリクエストを送信する。
- プロキシが API にデータを要求する。
- API が結果セットを生成し、プロキシに返す。
- プロキシがクライアントにデータを返す。
makeRequest() を呼び出すボックス(左下のボックス)から伸びる矢印は、コードが2つの異なるタイミングで実行されることを示しています。実際その通りで、関数の呼び出しは行われますが、コールバック関数は makeRequest() が処理を完了するまで実行されません。そしてコールバック関数が実行されると、リクエストされたデータが関数呼び出し元に返されます。

コード例の解説
コード全体をひとつの塊として見るのではなく、セクションごとに提示し解説します。いくつかのセクションは前述の図と関連します。
標準のプレーヤーコード
このコード セクションには、基本的な Brightcove Player のインページ埋め込みコードが含まれます。
- 11〜21行目:標準的な Brightcove Player のコードに加えて、
id属性を追加しています。
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Untitled Document</title>
</head>
<body>
<video-js id="myPlayerID"
data-video-id="3851380732001"
data-account="1752604059001"
data-player="HkAzSmB0l"
data-embed="default"
data-application-id
controls
width="640"
height="360"></video-js>
<script src="https://players.brightcove.net/1752604059001/HkAzSmB0l_default/index.min.js"></script>
呼び出しの準備
このコード セクションでは、変数を初期化し、makeRequest() を呼び出す準備を行います。一般に、読み取りリクエストでは次の情報を指定する必要があります。
- 使用するプロキシへの URL(もちろん、あなたの管理下にあるプロキシである必要があります):
https://solutions.brightcove.com/bcls/bcls-proxy/doc-samples-proxy-v2.php - 実際のリクエストに必要な URL(通常は動的に構築):
https://analytics.api.brightcove.com/v1/alltime/accounts/1752604059001/videos/4825279519001 - HTTP メソッド(例:
GET)。
以下は例です。
- 1行目:プレーヤーが操作可能になるまで待機するための標準コード。
- 2〜4行目:後続コードで必要となる変数を作成/設定します。
- 7〜12行目:
loadstartイベントを待機してmediainfoオブジェクトが用意されるのを待ちます。Analytics API のエンドポイントに必要な値を保持する変数を割り当てます。 - 13行目:呼び出しの HTTP メソッドを設定します。
videojs.getPlayer('myPlayerID').ready(function() {
var myPlayer = this,
accountId = myPlayer.bcinfo.accountId,
options = {};
// +++ Wait for loadstart event so can use mediainfo object +++
myPlayer.on('loadstart', function() {
var videoId = myPlayer.mediainfo.id,
baseURL = 'https://analytics.api.brightcove.com/v1/alltime/accounts/',
endPoint = accountId + '/videos/' + videoId;
options.proxyURL = "https://solutions.brightcove.com/bcls/bcls-proxy/doc-samples-proxy-v2.php";
options.url = baseURL + endPoint;
options.requestType = "GET";
makeRequest() の呼び出し
このコード セクションでは、makeRequest() 関数を呼び出します。2 つのパラメーターを渡す点に注意してください。1 つ目はエンドポイント情報を保持する options オブジェクト、2 つ目はコールバック関数です。これは非同期呼び出しであるため、REST API から makeRequest() にデータが返ってくるまで、匿名で定義したコールバック関数は呼び出されません。
- 1行目:
makeRequest()関数を呼び出し、optionsオブジェクトで必要な値を渡します。今回のオブジェクトの内容は以下の通りです。
- 3〜13行目:コールバック関数は匿名関数として定義されています(黄色で強調)。この関数はパラメーターであり、ここでは呼ばれず、後続の処理で実行されることを覚えておいてください。
- 6、8、10行目:
console.log()で次を表示します。- API 呼び出しから返される生の JSON 文字列。
- 文字列をオブジェクトに変換する
JSON.parse()により生成された JSON オブジェクト。 - 単純な
object.property記法でオブジェクトから抽出した実際の視聴回数。
- 12行目:コントロールバーに視聴回数を表示する関数を呼び出します。
以下のコンソールのスクリーンショットは、console.log の出力として実際に表示されるデータを示しています。

// +++ Make the request to the Analytics API +++
// Extract views from data returned by Analytics API
makeRequest(options, function(viewsRaw) {
var viewsCount;
// Remove console.log command for production code
console.log('viewsRaw', viewsRaw);
viewsObject = JSON.parse(viewsRaw);
console.log('viewsObject', viewsObject);
viewsCount = viewsObject.alltime_video_views;
console.log('views', viewsCount);
// Call function to place data in controlbar
placeCountInControlbar(viewsCount);
});
実際の makeRequest() 関数
このセクションでは、makeRequest() 関数を定義しているコードを確認します。この関数の定義は、基本的に変更せずに繰り返し使用できるように書かれています。例外的なケースがあるかもしれませんが、ほとんどの用途では修正は不要です。
以下、コードを行単位で解説します。
- 1〜6行目:関数定義と変数作成。重要なポイントは、新しい
XMLHttpRequestオブジェクトを作成している点です。 - 8、26行目:
readyStateの変化に対するイベント ハンドラー関数を定義します。 - 9、23、25行目:高レベルでリクエストが失敗した場合に備え、
try-catchを使用します。 - 10、11行目:
readyStateが 4(完了)で、かつステータスが 200 台であることをif文で確認します。以下はイベント ハンドラー定義内でreadyStateとstatusをコンソールに記録する例です。
- 18行目:コールバック関数を実行します。これにより、API から返却されたデータが、makeRequest() を呼び出す セクションで説明したとおり、コールバック関数へ渡されます。
- 33行目:
XMLHttpRequest.onreadystatechangeイベントのハンドラーを設定します。 - 35行目:プロキシへのリクエストを初期化します。
- 38行目:非同期でリクエストを送信します。
function makeRequest(options, callback) {
var httpRequest = new XMLHttpRequest(),
response,
requestParams,
dataString,
proxyURL = options.proxyURL,
// response handler
getResponse = function() {
try {
if (httpRequest.readyState === 4) {
if (httpRequest.status >= 200 && httpRequest.status < 300) {
response = httpRequest.responseText;
// some API requests return '{null}' for empty responses - breaks JSON.parse
if (response === '{null}') {
response = null;
}
// return the response
callback(response);
} else {
alert('There was a problem with the request. Request returned ' + httpRequest.status);
}
}
} catch (e) {
alert('Caught Exception: ' + e);
}
};
/**
* set up request data
* the proxy used here takes the following request body:
* JSON.stringify(options)
*/
// set response handler
httpRequest.onreadystatechange = getResponse;
// open the request
httpRequest.open('POST', proxyURL);
// set headers if there is a set header line, remove it
// open and send request
httpRequest.send(JSON.stringify(options));
}
返却データの表示
このコードは、返却されたデータをコントロールバーに配置する方法を示します。この関数は、上記の makeRequest() を呼び出す セクションのコールバック関数の末尾で呼び出されます。
- 5、16行目:関数を定義します。
- 6行目:コントロールバー内の
spacer要素用の変数を作成します。 - 7行目:
div要素を動的に作成します。 - 9行目:新しく作成した
div要素にラベルと視聴回数の値を設定します。 - 11行目:JavaScript の
document.getElementsByClassName()を使用して、コントロールバーのspacer要素を取得します。 - 13行目:
spacerをスタイリングし、合計視聴回数を右寄せで、かつspacerの上端から 10px 下に表示します。 - 15行目:新規作成・データ設定・スタイル適用済みの要素を
spacerに追加します。
/**
* Dynamically build a div that is then
* placed in the controlbar's spacer element
*/
function placeCountInControlbar(viewsCount) {
var spacer,
newElement = document.createElement('div');
//Place data in div
newElement.innerHTML = "Total Views: " + viewsCount;
//Get the spacer in the controlbar
spacer = document.getElementsByClassName('vjs-spacer')[0];
//Right justify content in the spacer and add top margin
spacer.setAttribute('style', 'justify-content: flex-end; margin-top: 10px');
//Add the dynamically built div to the spacer in the controlbar
spacer.appendChild(newElement);
}
完全なコード一覧
完全で動作するコードは、次の GitHub リポジトリにあります:display-views-in-controlbar.html。
シンプルなデバッグ
ご覧のとおり、REST API を使用する際には複数の要素が関わります。これにより、アプリが正しく動作しない場合に課題が生じることがあります。どこからデバッグを始めればよいでしょうか?
このセクションでは、いくつかの簡単な提案を紹介します。デバッグを始めるのに最適な出発点です。続く 2 つのセクションでは、呼び出し時に渡される内容と、返される内容という、必要となる最も基本的な情報を確認する方法を示します。
呼び出しオプションの確認
このドキュメントで説明しているクライアント側コードは、基本的にプロキシ、ひいては実際の API で使用する正しいオプションを指定することに関するものです。したがって、オプションが正しいことを把握することは、コードを正しく動作させるために不可欠です。簡単な方法として、makeRequest 関数にオプションが渡される直前に、options オブジェクトをコンソールにログ出力します。

options オブジェクトに含まれる内容は、実行しようとしている処理によって異なりますが、常に含まれる基本事項としては次のようなものがあります。
- アカウント ID。これは独立したプロパティでも、API エンドポイント URL の一部でも構いません。
- プロキシへの URL。これはプロキシをどこに配置しているかによって異なります。
- HTTP メソッドの種類(例:
GET、POST、PATCH)。 - プロキシが実際に API へリクエストを行う際に使用する API エンドポイント URL。例:
https://players.api.brightcove.com/v2/accounts/57838016001/players https://edge.api.brightcove.com/playback/v1/accounts/1752604059001/videos/5842800655001 https://analytics.api.brightcove.com/v1/alltime/accounts/1752604059001/videos/4093643993001
API リクエストによっては、options オブジェクトに他のプロパティが必要になる場合もあります。次は、特定のアカウント内のすべてのプレーヤーを取得するリクエストのために options オブジェクトをログ出力した際に、コンソールで確認できる例です。

次は、プレーヤーを更新する際に使用する、より複雑な options オブジェクトのログ例です。

返却データの確認
返却内容は、要求したデータやエラーの有無によって異なります。ただし、いずれの場合でも、返されたデータを確認したくなるでしょう。簡単な方法として、makeRequest 関数の呼び出し直後に、生の response データをコンソールにログ出力します。

返却される可能性はほぼ無限ですが、いくつか例を示します。最初の例は、アカウント内のすべてのプレーヤーを要求した際のレスポンスの冒頭です。

次は、PATCH メソッドを使用してプレーヤーを更新した後のレスポンスです。

最初のレスポンスに含まれるデータを、より見やすい形式で示すと次のようになります。
{
"id": "1OHQdsTAr",
"preview_url": "http://preview-players.brightcove.net/v2/accounts/.../master/index.html",
"preview_embed_in_page": "http://preview-players.brightcove.net/v2/accounts/.../master/in_page.embed",
"preview_embed_code": "<iframe src='//preview-players.brightcove.net/v2/accounts/.../master/index.html' ...></iframe>"
}
最後に、エラー発生時に返ってきた非常に重要なレスポンスの例を示します。このケースでは、適切な認証情報がない状態でアカウントを使用していました。

その他のトラブルシューティングのヒント
問題が発生している場合は、次の点も確認してください。
- レスポンスがない
- 空のレスポンスしか返ってこない場合、以下を確認します。
- API リファレンスを確認し、リクエストがレスポンスを返すことを確認してください。中にはコンテンツを伴わない 201 または 204 を返すものもあります(特に、ただし DELETE リクエストに限りません)。このケースに対応できるよう、コードを調整する必要があります。
- ブラウザーのデベロッパーツールの Network セクションで、プロキシへの呼び出しが成功しているかを確認してください(そのサーバーが一時的に利用できない可能性があります)。
デベロッパーツールの Network セクション
- レスポンスは見えるが、
JSON.parse()を実行すると例外が発生する - 考えられる原因は次のとおりです。
- 前項を参照してください。空の文字列をパースしようとすると JSON の例外が発生します。
-
レスポンスを確認し、
{または[で始まる JSON 文字列であることを確認してください。JSON が返らないケースもいくつかあります。たとえば、Analytics API 呼び出しでformatパラメーターをcsvまたはxlxsに設定した場合などです。これらの種類のリクエストを行う場合は、非 JSON レスポンスを処理できるようコードを調整する必要があります。 - 多くの場合、API から返されるエラーも JSON 形式ですが、プレーンテキストや HTML で返される例外もあります。
プロキシ コード
前述のとおり、プロキシは任意の言語で記述できます。Brightcove の API ドキュメントの例では PHP で書かれたプロキシを使用しています。プロキシの実装は言語への依存度が高いため、本ドキュメントでは以下の PHP コードの詳細な分析は行いません。
プロキシが提供すべき基本機能は次のとおりです。
- クライアント リクエストを受け付ける。
- OAuth API から認証トークンを取得する。
- 認証トークンとデータ リクエスト(エンドポイント)を対象の API に送信する。
- API からデータを受け取る。
- データをクライアントに返す。
<?php
/**
* proxy for Brightcove RESTful APIs
* gets an access token, makes the request, and returns the response
* Accessing:
* (note you should **always** access the proxy via HTTPS)
* Method: POST
* request body (accessed via php://input) is a JSON object with the following properties
*
* {string} url - the URL for the API request
* {string} [requestType=GET] - HTTP method for the request
* {string} [requestBody] - JSON data to be sent with write requests
* {string} [client_id] - OAuth2 client id with sufficient permissions for the request
* {string} [client_secret] - OAuth2 client secret with sufficient permissions for the request
*
* Example:
* {
* "url": "https://cms.api.brightcove.com/v1/accounts/57838016001/video",
* "requestType": "PATCH",
* "client_id": "0072bebf-0616-442c-84de-7215bb176061",
* "client_secret": "7M0vMete8vP_Dmb9oIRdUN1S5lrqTvgtVvdfsasd",
* "requestBody": "{\"description\":\"Updated video description\"}"
* }
*
* if client_id and client_secret are not included in the request, default values will be used
*
* @returns {string} $response - JSON response received from the API
*/
// security checks
// if you want to do some basic security checks, such as checking the origin of the
// the request against some white list, this would be a good place to do it
// CORS enablement and other headers
header("Access-Control-Allow-Origin: *");
header("Content-type: application/json");
header("X-Content-Type-Options: nosniff");
header("X-XSS-Protection");
// default account values
// if you work on one Brightcove account, put in the values below
// if you do not provide defaults, the client id, and client secret must
// be sent in the request body for each request
$default_client_id = 'YOUR_CLIENT_ID';
$default_client_secret = 'YOUR_CLIENT_SECRET';
// get request body
$requestData = json_decode(file_get_contents('php://input'));
// set up access token request
// check to see if client id and secret were passed with the request
// and if so, use them instead of defaults
if (isset($requestData->client_id)) {
$client_id = $requestData->client_id;
}
if (isset($requestData->client_secret)) {
$client_secret = $requestData->client_secret;
}
$auth_string = "{$client_id}:{$client_secret}";
// make the request to get an access token
$request = "https://oauth.brightcove.com/v4/access_token?grant_type=client_credentials";
$curl = curl_init($request);
curl_setopt($curl, CURLOPT_USERPWD, $auth_string);
curl_setopt($curl, CURLOPT_POST, TRUE);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Content-type: application/x-www-form-urlencoded',
));
$response = curl_exec($curl);
$curl_info = curl_getinfo($curl);
$php_log = array(
"php_error_info" => $curl_info
);
$curl_error = curl_error($curl);
curl_close($curl);
// Check for errors
// it's useful to log as much info as possible for debugging
if ($response === FALSE) {
log_error($php_log, $curl_error);
}
// Decode the response and get access token
$responseData = json_decode($response, TRUE);
$access_token = $responseData["access_token"];
// get request type or default to GET
$method = "GET";
if ($requestData->requestType) {
$method = $requestData->requestType;
}
// get the URL and authorization info from the form data
$request = $requestData->url;
// check for a request body sent with the request
if (isset($requestData->requestBody)) {
$data = $requestData->requestBody;
}
$curl = curl_init($request);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Content-type: application/json',
"Authorization: Bearer {$access_token}"
));
switch ($method)
{
case "POST":
curl_setopt($curl, CURLOPT_POST, TRUE);
if ($requestData->requestBody) {
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
break;
case "PUT":
// don't use CURLOPT_PUT; it is not reliable
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
if ($requestData->requestBody) {
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
break;
case "PATCH":
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
if ($requestData->requestBody) {
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
break;
case "DELETE":
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
if ($requestData->requestBody) {
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
break;
default:
// GET request, nothing to do;
}
$response = curl_exec($curl);
$curl_info = curl_getinfo($curl);
$php_log = array(
"php_error_info" => $curl_info
);
$curl_error = curl_error($curl);
curl_close($curl);
// Check for errors and log them if any
// note that logging will fail unless
// the file log.txt exists in the same
// directory as the proxy and is writable
if ($response === FALSE) {
log_error($php_log, $curl_error);
}
function log_error($php_log, $curl_error) {
$logEntry = "\nError:\n". "\n".date("Y-m-d H:i:s"). " UTC \n" .$curl_error. "\n".json_encode($php_log, JSON_PRETTY_PRINT);
$logFileLocation = "log.txt";
$fileHandle = fopen($logFileLocation, 'a') or die("-1");
fwrite($fileHandle, $logEntry);
fclose($fileHandle);
echo "Error: there was a problem with your API call"+
die(json_encode($php_log, JSON_PRETTY_PRINT));
}
// return the response to the AJAX caller
echo $response;
?>
上記にプロキシ サーバーのコード全体を示しましたが、GitHub リポジトリ sample-proxy-apps の php フォルダーにもあります。
例 2
2 つ目の例は前述のものよりも複雑です。アカウント内で最も人気のある動画 10 本をプレイリストに表示します。コードの主な手順は次のとおりです。
- Analytics API にリクエストし、アカウント内で視聴数が最も多い 10 本の動画を取得します。この手順では、コールバック関数を用いた非同期呼び出しを行います。
- 返却された Analytics API のデータから動画 ID のみを抽出し、配列に格納します。返却データから ID を抽出するヘルパー関数を作成します。
- 配列内の ID リストに対して、それぞれの動画の完全なビデオ オブジェクトを要求します。この手順では配列をループし、
player.catalog.getVideo()を使用してビデオ オブジェクトを取得します。もちろん、catalogを使用する複数の非同期呼び出しが発生します。ID に基づいてビデオオブジェクトを取得し、配列に格納するヘルパー関数を作成します。 - ビデオ オブジェクトの配列を、プレイリスト対応のプレーヤーのプレイリストに設定します。
ここまでで API 呼び出しの多くの概念や具体的なコードに慣れてきたと思いますので、ここでは makeRequest() 関数を呼び出すコードのみを詳しく説明します。
- 2 行目:REST API 呼び出しに必要なオプションと、匿名で定義したコールバック関数(黄色で強調)を引数にして
makeRequest()関数を呼び出します。ここは上で説明したとおりです。重要な点として、ここで呼び出しているmakeRequest()は前の例で使用したものとまったく同じ関数です。あなたのコードでも同様に再利用できます。makeRequest()は Brightcove の REST API への呼び出しで再利用できるように作られています。 - 3 行目:JSON をパースした返却データを保持する変数を作成します。
- 5 行目:返却データをパースし、文字列からオブジェクトに変換します。
- 7 行目:ヘルパー関数を使用して返却データから動画 ID を抽出します。残念ながら、Analytics API は完全なビデオ オブジェクトを返さないため、完全なオブジェクトにアクセスするには ID が必要です。
- 9〜12 行目:コールバック関数を使用する
getVideoDataヘルパー関数を呼び出し、渡した ID に基づいてvideoObjects配列を構築します。 - 11 行目:ビデオ オブジェクトの配列でプレイリストを設定します。
// +++ Make the CMS API request to get matching video IDs +++
makeRequest(options, function(mostWatchedVideos) {
var JSONmostWatchedVideos;
// Convert response string into JSON
JSONmostWatchedVideos = JSON.parse(mostWatchedVideos);
// Extract the needed video IDs into an array
videoData = extractVideoData(JSONmostWatchedVideos);
// Get video objects based on array of video IDs
getVideoData(videoData, function(videoObjects) {
// Add the most watched videos list to the player as a playlist
myPlayer.playlist(videoObjects);
});
});
完全なコード一覧
完全で動作するサンプルは次の CodePen にあります:Most Watched Videos in a Playlist。