Vonage Video APIによるマルチパーティビデオ

Vonage Video APIは、あなたが望むビデオ体験のほとんどを作成することができます。開発者が持つ一般的なユースケースは、チームとのミーティングのように、一つの部屋に複数のユーザがいることです。多くの場合、これらのビデオセッションは録画される必要があります。Vonage Video API を使えば、その両方を簡単に行うことができます。

このチュートリアルでは

Vonage Video APIを使えば、すぐに部屋を作って参加者を中に入れることができます。私たちは、あなたがコードを書く必要がないように、私たちの既存のデモを立ち上げて実行する方法を説明しますが、我々はまた、コードがバックグラウンドで何をやっているかを説明します。

  1. デモを見る - コードを書かずにデモをチェックする
  2. デモの仕組み - クライアント側 - クライアント側のコードが行っていること
  3. デモの仕組み - サーバー・サイド - サーバーサイドのコードが行っていること

前提条件

チュートリアルを完了するには

デモを見る

コードを書く前にデモをチェックしたい場合は、基本的なビデオ通話がどのように見えるかを試すためのサンプルウェブサーバーとJavaScriptコードを用意しています。すべてのコードはオープンソースで公開されているので、デモを試してみてから、そのコードを使って独自の修正を加えることができます。

Node.jsサーバーの起動

ビデオ・デモでは、認証のためのクライアント・トークンの作成や一般的なセッション管理などを行うバックエンド・サーバーが必要です。好きな言語でこれを構築することができますが、私たちは事前に構築したサーバーを用意しています。 Vonage ビデオ学習サーバー (Node.js) on Code Hub.より 開発者向けドキュメント一番上のナビゲーション・バーで "Code Hub "をクリックし、下にスクロールして "Vonage Video Learning Server (Node.js) "のカードを見つける。それをクリックして開いてください。

このプロジェクトが何をするのかの説明が表示される。とりあえず、"Get code "をクリックして、Code Hubオンライン・エディターに読み込ませてみよう。Create a new development environment "をクリックしてください。ワークスペースに "Vonage Video Demo "という名前を付ける。学習サーバーはSIP経由の電話をサポートしているため、このデモには番号を割り当てる必要がある。このデモでは番号を使用しませんが、先に進み、"Assign a number "をクリックして、Vonageから既存の番号を割り当てるか、後のデモで使用するために新しい番号を購入してください。

Creating a new workspace

Code Hubがアプリケーションを自動的に作成し、アプリケーションが使用する公開鍵と秘密鍵の設定も行います。ワークスペースが作成されると、Visual Studio Codeのオンライン版であるコードエディターにドロップされます。このデモの後の部分でコードを見ることができますので、ご自身のプロジェクトに合わせてこのコードを編集してください。

Code editor

アプリケーションを実行するには、エディター上部の "View "をクリックし、次に "Terminal "をクリックする。これでコマンドラインを開き、コマンドを実行することができる。必要なのは vcr deploy するとコードがデプロイされます。コードがパッケージ化され、Vonage Code Hubサーバー上で実行されるため、しばらく時間がかかります。最後に出力される "インスタンスホストアドレス "をメモしておこう。

Deploying the project

すべてが正常に機能していれば、「インスタンス・ホスト・アドレス」にアクセスし、以下のページが表示されるはずだ:

Learning Server homepage

フロントエンドのテスト

バックエンドサーバーは、この1対1のデモを含む、私たちのすべてのビルド済みデモで直接動作します。次のサイトにアクセスしてください。 https://github.com/Vonage-Community/video-api-web-samples/tree/main/Archivingこれはこのデモのフロントエンド部分のソースコードです。このサンプルでは、URLを持つ複数のユーザーが音声チャットに参加し、Archivesと呼ばれるセッションの録音を作成することができます。

このデモを実行する最も簡単な方法は、READMEにある「Stackblitzで開く」ボタンをクリックすることだ。

Basic Video Chat README

これでStackblitzでプロジェクトが開きます。バックエンドサーバーと同じように、コードを閲覧したり修正したりすることができます。このデモで必要なのは js/config.js ファイルを開き、Code HubインスタンスのURLを SAMPLE_SERVER_BASE_URL 変数である:

Stackblitz Demo Config

ファイルを保存したら、Stackblitzの右側にあるデモ・ビューを更新し、ブラウザがマイクとカメラの許可を求めるはずです。許可すると、サイドバーの下隅にあなたの画像が表示されるはずです。デモ・ペインの上にあるStackblitzのURLをコピーして、モバイル・デバイスや別のコンピューターで閲覧したり、友人に教えたりすれば、誰でもあなたのデモに接続できるはずです!

デモの仕組み

Vonageアプリケーションの設定

ビデオ・アプリケーションを動作させるには、クライアントとサーバーがVonageサーバーと通信する方法が必要です。Code Hub がこれを設定してくれますが、ローカルでコードを実行する場合や、Video API がどのようなものか知りたい場合は、他の API と同じように設定します。Vonageアプリケーションをセットアップして、アプリケーションのすべての設定を行い、認証に必要な項目を生成する必要があります。

に向かう。 Vonageカスタマーダッシュボード にログインしてください。ログインしたら

  1. "ビルド "の下にある "アプリケーション "をクリックする。
  2. "Create a new application "をクリックする。
  3. アプリケーションに "Basic Video Demo "のような名前をつけます。
  4. Generate public and private key(公開鍵と秘密鍵の生成)」をクリックし、ファイルをダウンロードする。 private.key.このファイルは後々のために記録しておくこと。
  5. 下にスクロールし、"Video "をオンに切り替えます。今はこれらの値を空にしておきます。
  6. Generate new application "をクリックしてアプリケーションを作成します。

アプリケーションを作成したら、アプリケーションIDを控えておいてください。ローカルでコードを実行する場合は、バックエンドを設定するためにこれが必要になります。Code Hubを使用している場合、サーバーコードはすでにアプリケーションIDと秘密鍵にアクセスしています。

クライアント側

デモのクライアント側部分は、2つの異なる部分から構成されている。ビデオ・フィードを配置するためのいくつかのHTML要素と、ログイン情報を取得し、Vonage Videoサーバーと通信するためのJavaScriptである。

これはブラウザのデモなので、次の場所にあるJavaScript SDKを使用します。 https://unpkg.com/@vonage/client-sdk-video@latest/dist/js/opentok.jsで、それをHTMLのscriptタグに含める。 index.html.

ルームに人を追加するには、2つの要素だけが必要です。例えば、現在のユーザー、あなたを "パブリッシャー "と呼びます。そして、あなたが "subscribe "する他の参加者を入れる場所が必要です。それらを "subscriber "要素に入れます。

私たちは、以下の2つを作成する。 div のIDを1つ与える。 publisher もう一方のIDは subscriber.ページが訪問されたときや、他のユーザーがビデオ通話に参加したことを検出したときに、JavaScriptでこれらの要素を参照します。

また、アーカイブの開始と停止を処理するための2つのボタンと、アーカイブのレンダリングが完了したらアーカイブのURLを記入するプレースホルダも作成しました。

ハンドリング・ビデオ

JavaScript側では、まずビデオ通話自体の情報を取得する。ビデオ通話に接続するには、アプリケーションID、セッションID、トークンが必要です。

  • について アプリケーションID は、クライアントSDKがVonage側のビデオアプリのさまざまな設定を参照するために使用する識別子です。
  • について セッションID は、接続したい特定のビデオセッションです。1つのApplicationsは、同時に複数のビデオセッションを持つことができるからです。
  • について トークン は、特定のセッションに特定の権限で参加できるようにするJWT認証トークンです。

セッション ID とトークンを前もって生成することもできますが、現実の世界ではオンデマンドで生成することにな ります。このコードはその方法を表しています。この情報がどのように生成されるかは後ほど説明しますが、ここではデプロイしたバックエンドサーバから情報を取得します。

// src/app.js

// ...
} else if (SAMPLE_SERVER_BASE_URL) {
  // Make a GET request to get the Vonage Video Application ID, session ID, and token from the server
  fetch(SAMPLE_SERVER_BASE_URL + '/session')
  .then((response) => response.json())
  .then((json) => {
    applicationId = json.applicationId;
    sessionId = json.sessionId;
    token = json.token;
    // Initialize a Vonage Video Session object
    initializeSession();
  }).catch((error) => {
    handleError(error);
    alert('Failed to get Vonage Video sessionId and token. Make sure you have updated the config.js file.');
  });
}

接続情報がすべて揃ったら、Vonage Video JavaScript SDK を呼び出す。この SDK は、フロントエンドで Vonage Video API に接続するためのすべての処理を行う。まず OT.initSession().そして、私たちは streamCreated イベント session.on().これにより、他のパブリッシャーからのストリームが作成された時に実行されるコールバックを設定することができます。この場合 session.subscribe() にプッシュする。 subscriber HTMLで設定したdiv.また sessionDisconnected イベントで他のユーザーがいつ切断したかを知ることができるが、このデモでやっているのは、ユーザーが切断したことに気づいたというログを取ることだけだ。

そして publisher オブジェクトを OT.initPublisher().どの div にアタッチするかを指定します (publisher)、いくつかの基本的なフォーマット・オプションがあります。これは、カメラとマイクを Video API に接続します。

そして、次のように呼ぶ。 session.connect() で、サーバーから取得した接続JWTトークンを使ってセッションに接続します。これだけで、2人がルームに参加できる!

// src/app.js

function initializeSession() {
  const session = OT.initSession(applicationId, sessionId);

  // Subscribe to a newly created stream
  session.on('streamCreated', (event) => {
    const subscriberOptions = {
      insertMode: 'append',
      width: '100%',
      height: '100%'
    };
    session.subscribe(event.stream, 'subscriber', subscriberOptions, handleError);
  });

  session.on('sessionDisconnected', (event) => {
    console.log('You were disconnected from the session.', event.reason);
  });

  // initialize the publisher
  const publisherOptions = {
    insertMode: 'append',
    width: '100%',
    height: '100%',
    resolution: '1280x720'
  };
  const publisher = OT.initPublisher('publisher', publisherOptions, handleError);

  // Connect to the session
  session.connect(token, (error) => {
    if (error) {
      handleError(error);
    } else {
      // If the connection is successful, publish the publisher to the session
      session.publish(publisher, handleError);
    }
  });
}

取り扱いアーカイブ

実際のアーカイブ管理はアプリケーションのサーバー側で処理されるが、システムにアーカイブの開始と停止を指示する方法が必要だ。HTMLに追加したボタンと <span> にURLをダンプする。アーカイブを開始するまでは表示する必要がないので、ついでに "Stop "ボタンも非表示にしておこう。

// src/app.js
const archiveStartBtn = document.querySelector('#start');
const archiveStopBtn = document.querySelector('#stop');
const archiveLinkSpan = document.querySelector('#archiveLink');

archiveStopBtn.style.display = "none";

実際にアーカイブを開始したり停止したりするために、バックエンドサーバーにHTTPリクエストを発行します。開始ボタンと停止ボタンのクリックイベントに関数をアタッチします。サーバーアプリケーションには、Vonage Video API と通信してアーカイブ自体を操作するコードが含まれます。

// src/app.js

async function startArchiving(){
  console.log('start archiving');
  try {
    archive = await postData(SAMPLE_SERVER_BASE_URL +'/archive/start',{sessionId});
    console.log('archive started: ', archive);
    if (archive.status !== 'started'){
      handleError(archive.error);
    } else {
      console.log('successfully started archiving: ',archive);
    }
  }
  catch(error){
    handleError(error);
  }
}

async function stopArchiving(){
  console.log('stop archiving');
  try {
    archive = await postData(`${SAMPLE_SERVER_BASE_URL}/archive/${archive.id}/stop`,{});
    console.log('archive stopped: ', archive);
    if (archive.status !== 'stopped'){
      handleError(archive.error);
    } else {
      console.log('successfully stopped archiving: ',archive);
    }
  }
  catch(error){
    handleError(error);
  }
}

archiveStartBtn.addEventListener('click', startArchiving, false);
archiveStopBtn.addEventListener('click', stopArchiving, false);

最後に必要なのは、アーカイブに関するJavaScriptのイベントをリッスンすることだ。これらは archiveStarted イベントと archiveStopped イベントが発生します。これにより、SDKはこれらの操作が実行されていることを知ることができ、我々は何が起こっているかに基づいてUIを調整することができます。Vonage Video API 自体がアクションを実行したことがすぐに分かるので、上で作成したイベントリスナー関数とは対照的に、SDK でこれを処理する方が良いでしょう。

// src/app.js

session.on('archiveStarted', (event) => {
  archive = event;
  console.log('Archive started ' + archive.id);
  archiveStartBtn.style.display = 'none';
  archiveStopBtn.style.display = 'inline';
  archiveLinkSpan.innerHTML = '';
});

session.on('archiveStopped', (event) => {
  archive = event;
  console.log('Archive stopped ' + archive.id);
  archiveStartBtn.style.display = 'inline';
  archiveStopBtn.style.display = 'none';
  archiveLinkSpan.innerHTML = `<a href="${SAMPLE_SERVER_BASE_URL}/archive/${archive.id}/view" target="_blank">View Archive</a>`;
});

アーカイブが始まったら、「開始」ボタンを隠し、「停止」ボタンを表示します。アーカイブが停止したら、"Stop button "を非表示にし、"Stop button "内に <span> をアーカイブを表示するための URL に置き換えてください。このURLは以前に配置したバックエンドサーバーの一部であり、アーカイブ自体が保存されているURLではありません。そのため、サーバーサイドのイベントを見る必要があります。

サーバーサイド

Vonage Videoアプリケーションのサーバーサイド部分は、セッションの作成、認証トークンの生成、アーカイブの開始や停止などの管理タスクを処理するために使用されます。このデモでは、ユーザがルームに参加できるようにセッションとトークンを作成することだけを考えています。API 自体は REST API であり、どのように呼び出してもかまいません。 Vonage Node SDK これは、すべての認証とHTTPコールを処理します。これを自分のアプリケーションにインストールするには、次のようにする:

npm install -s @vonage/server-sdk

デモ・コードにはすでにプリインストールされています。コードをローカルで実行する場合は、以下を実行する必要がある:

npm install

をコピーして、すべての依存関係をダウンロードします。 .envcopy という名前の新しいファイルに .env.に必要事項を記入してください。 .env アプリケーションID、ディスク上の秘密鍵の場所、Vonage API Key and Secretなど。

セッションの作成とセッションへの参加

最初にすることは、生成する部屋のセッションがすでにあるかどうかを調べることです。メモリ内の辞書を roomToSessionIdDictionaryもしその部屋にすでにセッションがあれば、辞書からセッションを引き出します。次に、Vonage Video Node SDK を使用して、クライアントトークンを作成します。 vonage.video.generateClientToken()セッションIDと設定を持つオブジェクトを渡す。現時点では、ユーザーを moderator ロールを設定する。そして、設定されたアプリケーションID、セッションID、トークンをフロントエンドに返します。

セッションが存在しない場合は、次のように新しいセッションを作成します。 vonage.video.createSession().これはVonage APIにコンタクトし、ユーザーが接続できるセッションを作成する。このセッションに対する特別な設定はありませんが、ここでアーカイブルールや、ルーティングやピアツーピアのようにセッションをどのように扱うべきかを設定します。そして先ほどと同じようにトークンを作成し、すべての情報をブラウザに送り返す。

// routes/index.js

async function createSession(response, roomName, sessionProperties = {}, role = 'moderator') {
  let sessionId;
  let token;
  console.log(`Creating ${role} creds for ${roomName}`);

  if (roomToSessionIdDictionary[roomName]) {
    sessionId = roomToSessionIdDictionary[roomName];
    // generate token for user
    token = vonage.video.generateClientToken(sessionId, { role })
    response.setHeader('Content-Type', 'application/json');
    response.send({
      applicationId: appId,
      sessionId: sessionId,
      token: token
    });
  } else {
    try {
      // Create the session
      const session = await vonage.video.createSession(sessionProperties);
      roomToSessionIdDictionary[roomName] = session.sessionId;

      // generate token for user
      token = vonage.video.generateClientToken(session.sessionId, { role });
      response.setHeader('Content-Type', 'application/json');
      response.send({
        applicationId: appId,
        sessionId: session.sessionId,
        token: token
      });
    } catch(error) {
      console.error("Error creating session: ", error);
      response.status(500).send({ error: 'createSession error:' + error });
    }
  }
}

取り扱いアーカイブ

Vonage Video API のほとんどの管理機能と同様に、アーカイブの管理は REST API とサーバー SDK を通して行われます。アーカイブを開始および停止するためのクライアント側のリクエストを受け取り、バックエンドサーバのルートにマッピングし、次のように呼び出します。 vonage.video.startArchive() でアーカイブを開始し vonage.video.stopArchive() で実行中のアーカイブを停止する。

アーカイブを開始すると、生成されたアーカイブ情報をクライアントに返す。こうすることで、後でどのアーカイブを停止すればよいかを知ることができます。アーカイブを停止するときには、クライアント側で何か更新する必要がある場合に備えて、そのステータスも送り返します。

これらの呼び出しは最終的に archiveStarted そして archiveStopped SDKイベントをリッスンする。

// routes/index.js

router.post('/archive/start', async function (req, res) {
  console.log('attempting to start archive');
  const json = req.body;
  const sessionId = json.sessionId;
  try {
    const archive = await vonage.video.startArchive(sessionId, { name: findRoomFromSessionId(sessionId) });
    console.log("archive: ", archive);
    res.setHeader('Content-Type', 'application/json');
    res.send(archive);
  } catch (error){
    console.error("error starting archive: ",error);
    res.status(500).send({ error: 'startArchive error:' + error });
  }
});

router.post('/archive/:archiveId/stop', async function (req, res) {
  const archiveId = req.params.archiveId;
  console.log('attempting to stop archive: ' + archiveId);
  try {
    const archive = await vonage.video.stopArchive(archiveId);
    res.setHeader('Content-Type', 'application/json');
    res.send(archive);
  } catch (error){
    console.error("error stopping archive: ",error);
    res.status(500).send({ error: 'stopArchive error:', error });
  }
});

アーカイブを見るためには、アーカイブ自体が利用可能であることを確認する必要があります。ユーザがアーカイブを見るためにフロントエンドのリンクをクリックすると、バックエンドサーバのルートを通してフィルタリングされ、アーカイブが本当に準備できているかをチェックすることができます。ステータスが availableそして、動画の実際の保存 URL にリダイレクトします。ほとんどの主要ブラウザが MP4 フォーマットをサポートしているため、ブラウザにアーカイブされた動画をネイティブ表示させます。

// routes/index.js

router.get('/archive/:archiveId/view', async function (req, res) {
  const archiveId = req.params.archiveId;
  console.log('attempting to view archive: ' + archiveId);
  try {
    const archive = await vonage.video.getArchive(archiveId);
    if (archive.status === 'available') {
      res.redirect(archive.url);
    } else {
      res.render('view', { title: 'Archiving Pending' });
    }
  } catch (error){
    console.log("error viewing archive: ",error);
    res.status(500).send({ error: 'viewArchive error:' + error });
  }
});

結論

このチュートリアルでは、マルチパーティービデオセッションのバックエンドサーバーで何が行われるのか、ユーザーがセッションに参加し、お互いを見たり聞いたりするためのウェブクライアントを作成する方法、ビデオセッションを録画してそれを見る方法、そしてサンプルを素早くテストするためにVonage Code HubとStack Blitzを使用することがいかに簡単かを紹介しました。

さらに読む