LoginSignup
1
1

【Vonage】Video API スタートアップガイド「ビデオ通話が簡単に出来ちゃうAPIがあるんですか!?」

Last updated at Posted at 2023-12-25

皆さんこんにちは!
筆が遅すぎて、アドベントカレンダーに代わりに投稿されてしまったPOTIです ^__^

今年は、Vonage Advent Calendar 2023 に参加してみました!
ということで今回は、

Vonage様 から提供されている 沢山のコミュニケーションAPI の中から個人開発者の方にも比較的需要がありそうな、「簡単にビデオ通話が実装できちゃうAPI」 こと Vonage - Video API(以下 Video API)について解説していくことにします!

はじめに

本記事では、

  • Video API のことはよく知らないけど、簡単にビデオ通話が実装できるって聞いたの、、、」
  • 「公式ガイドとかチュートリアルとか見てきたけど、いまいちよく分からなくて、、、」
  • 「軽くデモを試してみたんだけど、もっとこんな機能を 実装 してみたいな、、、」

といった Video API をこれから使い始める方々に、Video API について 噛み砕いて 解説していきます。

  • Video APIの仕組み」では、ビデオ通話の最中、内部でナニが行われているのか、公式ガイドを元に分かりやすく解説しています。
  • 実践してみよう」では、実際に Webで動く簡易的なデモ を詳しい手順とともに作成していきます。
  • さらにカスタマイズ」では、Video API で簡単に実装できる、より高度なカスタマイズオプション をサクッと紹介しています。
  • 参考にしたい記事の紹介」では、Video API を活用した さらに高度な実装 を解説されている記事を 厳選して 紹介しています。

Video API 初学者から中級者を主な対象に、「参考になるかな?」と精一杯書いてみました。

対象読者

  • Vonage Video API についてもっとよく知りたいと思っている方
  • Video API で理想のビデオ通話を作ってみたいと思っている方

実践編では、別途これらが必要です。

  • JavaScript の基本的な知識
  • Webページの仕組み(フロントエンド・バックエンド)について大体理解している

Vonage Video API とは

Vonage - Video API(旧 TokBox OpenTok)

アメリカの Vonage社 が提供する Video API は、高品質なビデオ・音声・メッセージング・画面共有を Webページやモバイルアプリに簡単に実装することができる API です。
Video API では、たくさんのプラットフォーム・言語に向けてSDKが提供されており、ネイティブコードから直接使用することが出来ます。

Vonage Video API では、これらのプラットフォーム・言語に提供されています。

プラットフォーム:Web / Android / Windows / macOS / iOS / Linux / React Native
言語:.NET / Java / Node / PHP / Python / Ruby

Vonage Video API 公式サイトのトップ.png

Video API の仕組み

解説を始める前に、出てくる単語について定義をしておきます。

単語 意味
Vonageサーバー Vonage側のサーバー
アプリサーバー ページのバックエンド
クライアント ページのフロントエンド

↓ ここで解説する内容は公式ガイドにも詳しく載っています(ただし英語のみ)↓

それでは、Video API がどのように通話を実現しているのか、解説していきます。

1. セッションの作成

通話を行うには、参加者全員を格納しておくための、個別の、いわゆる 部屋 が必要ですね。
部屋を作成するためには、Vonageへ、リクエストを行います。

Vonage のダッシュボードから手動で作成することも出来ますが、
毎回手動でやるわけにもいかないじゃないですか、、、
なのでここでは、クライアントから自動で作成できるようにします。
(そっちの方が実用的ですしね)

まず、アプリケーションサーバーが起動すると、Vonageへセッションの作成をリクエストします。
Vonageがセッションの作成に成功した場合、リクエストの返答として、セッションのIDを返します
(失敗した場合はエラーの詳細が返されます)

このセッションIDは、後でVonage側のセッションに接続する際に使用するため、サーバー側で保存しておきます。

セッションについて詳しく

セッションは、一意のセッション ID に関連付けられ、クライアントがリアルタイムで相互に対話できる「ルーム」と考えることができます。

つまり、
Zoomでいう一つの会議、YouTubeでいう一つの配信、Discordでいう一つのボイスチャンネル・・・
といった具合の、いわゆる 互いにビデオ通話を行うための部屋 を表したものです。

一つのセッションには、それを表す一意のIDが紐付けられます。
また、セッションには有効期限がなく、明示的に破棄することも出来ません。
(代わりにトークンで管理)
あくまで、一つの部屋を表したもの であることに注意です。

2. トークンの取得

さて、セッションに接続するためには、セッションIDともうひとつ、認証情報を表す一意のトークンが必要です。
このトークンの生成は、Vonageへのリクエストはせず、アプリケーションサーバーがSDKを通してセッションIDから生成します。

※ トークンについて詳しく

【公式ガイドの訳】

トークンは、クライアントがセッションに参加できるようにする一意の認証「キー」です。
クライアントがセッションに参加しようとすると、アプリサーバーは一意のトークンを生成し、それをセッション ID とともにクライアントに送信します。
トークンには、パブリッシャー、サブスクライバー、モデレーターなどの役割を割り当てることもできます。
これにより、セッション内のストリームの公開やストリームのサブスクライブなど、クライアントの権限が決まります。

トークンには有効期限が設定でき、最大で30日、デフォルトでは24時間となっています。
また、トークンには有効期限がありますが、セッションには有効期限がないことに注意です。

トークンの生成時には、VonageサーバーへのAPI呼び出しはなく、ハッシュ関数とシークレットキーさえあれば自由に生成できます。
また、公式では、トークンを使用する際のある程度のベストプラクティスが紹介されています。

  • クライアントが接続しようとしたときに、クライアント毎の新しいトークンを生成する
  • トークンには有効期限を設定する(デフォルトでは24時間)
  • トークンを保存したり、再利用したりしない
  • トークンに含まれた接続データを使用してユーザーを識別する

3. セッションへ接続

やっとこさ、用意されたセッションへ接続することが出来ます。
Vonageに向けて先程用意した、"セッションID""認証トークン" を送信し、

Video API の接続は WebSocket で行われています。

WebSocketってなぁに?

調べてみたら、意外と高度な技術なんですね。
↓ こちらは5年前の記事ですが細かい部分までしっかり解説されています。興味のある方はぜひ ↓

WebSocketについて調べてみた。- Qiita

4. 二人目登場

さて、このままボッチでビデオを配信し続けていてもいいのですが、第2者が居ないとビデオ通話は成立しません!
ということで、お友達を連れてみましょう。
※ お友達が居ない方はスルーしてください()

2人目以降の参加にも、セッションIDと認証トークンが必要です。
これらの情報はアプリケーションサーバーに保存してあるんでしたね。

2人目がアクセスすると、サーバーは以前に生成したセッションIDとトークンを使用して、セッションに参加させます。

セッションに居るクライアントが、それぞれ自身の映像をVonageに 送信(パブリッシュ) し、他の参加者の映像を 受信(サブスクライブ) することで、ビデオ通話が実現します。

映像の通信にも WebSocket が使われています。

実践してみよう

さて、Video API について大方理解できましたか?
ここからは、いよいよ本番です!
先程の流れをもとに、実際に動作する簡易的なデモを作ってみましょう!

実装する機能

  • サーバーサイドでの動的トークン発行
  • ビデオ・音声通話(ホスト)
  • ビデオ・音声通話(クライアント)

使用する技術

実際の動作の流れ

図が大きくて一見複雑そうに見えますが、準備さえすればあとはVideo APIさんが自動で継続的に通信してくださります。

新規プロジェクト作成

まずはVideo APIのダッシュボードにアクセスして、新しいプロジェクトを作成します。
(ログインしていない場合はログインしましょう)
↓↓
Vonage Video API Account

ログイン出来たら、サイドバー(左側)にある Create Project からプロジェクトの作成を行います。

vivaldi_JAfno8EOcg.png


すると、プロジェクトの種類を訊かれるポップアップが表示されます。

vivaldi_hyTOZ4jAJa.png

今回は、右側の Vonage Video API の下にある Create Custom Project を押して、作成を始めます。


vivaldi_mZJ3PlcW7s.png

プロジェクト名(上)は自由に決められます。センスが問われますね。
コーデック(下)には、安定の VP8 を使用します。

もうひとつ、H.264 の選択も出来ますが、VP8 の方が推奨されるようです。
選択しようとすると、このような注意書きが出ます。

H.264 は大規模なセッションには推奨されず、古い Android デバイスではサポートされない可能性があります。スケーラブルビデオはサポートされていません。


vivaldi_GldsbJDUVY.png

Congulation!!!

無事、プロジェクト作成が完了し、専用の API KeySECRET Key が発行されました!
これらは、実際に Video API を使う際に必要となります。
(※ 画像のキーはフェイクです)

このデモは一つのページ上に作成することが出来ます。(ルーティングはお好みで)

  • ビデオ通話(クライアント) /vonage/lobby

フレームワークに SvelteKit を使用すると、フロントエンドとバックエンドを手軽に連携できます。(唐突な布教)

ダッシュボードから必要な情報を確認する

こちらは、Video APIダッシュボードで確認できる、プロジェクト設定画面のトップです。
(画像のキーは参考のためのフェイクです)

Video APIダッシュボードのトップ

下の欄にある、PROJECT API KEYPROJECT SECRET がセッションの作成に必要な項目です。

特に、PROJECT SECRET は絶対に外部に公開しないで ください。
悪用される危険性があります。
(2度いいますが、この参考画像はフェイクです)

ビデオ通話の準備をする

ビデオ通話を開始するためには、トークンを発行して、ホストとクライアントの双方に適用しなければなりません。
これらを、サーバーサイド(Node.js)で専用のSDKを通して行っていきます。
Vonageとの通信には TokBox SDK というのを使います。

まずは、npmからOpenToK SDKをインストールしましょう。

$ npm install opentok || yarn add opentok || pnpm add opentok

続いて、SDKをプロジェクトにインポートし、SDKのインスタンスを作成します。

インスタンスの作成では、引数にAPI KeyとProject Secretが必要になります。
これらはVonageのプロジェクトダッシュボードからコピーし、プロジェクトに合わせて、環境変数などからインポートしてください。

import OpenTok from "opentok";

// SDKのインスタンスを作成
const openToK = new OpenTok (API_KEY, PROJECT_SECRET);

これで、SDKを使用する順位が整いました!

セッションIDの生成

トークンを発行するにはまず、セッションを作成する必要があります。
これには、OpenToK.createSession() 引数のコールバック内でごにゃごにゃします。

app.ts
+ openToK.createSession ((error, session) => {
+     if (error) throw error;

+     const sessionID = session?.sessionId; // セッションからIDを取得
+     console.log (`ID: ${sessionID}`);
+ });
"session"の後にある"?"ってなぁに?

? はTypeScriptで使える記号です。
いわゆる "nullチェック" をインラインで記述できます。

sessionはエラーが起きた場合、中身が渡されないので、
その時にnullエラーが出ないよう、これでチェックを行っています。

TypeScriptでよく見る「?」「!」と仲良くしたい - オプショナルチェイニング(?.) - Zenn

はい、これだけです!
実行すると、生成されたセッションIDがコンソールに表示されます。

console
ID: 1_MX40NzgzNzMyMX5-MTcwMzMyNDMyNjcyM354anBaTUVkQ2NGN0NmMnpoRC95MUR3amN-UH5-

異なるクライアント間で同じセッションIDを使用する

最初にアクセスしたクライアントがVonageサーバーからセッションIDを受け取った後、
別のクライアントが同じ部屋に入室するためには、同じセッションIDを使用していなければなりません。
そのため、後にアクセスしたユーザーが 既に生成されたセッションID を使えるように、外部のデータベースに保存して、別のクライアントから読み出せるようにします。

データベースと聞いて拒否反応が出てしまった方、安心してください。
私もデータベースアレルギーです。
ですが、使用するのは値の格納・取り出しだけですのでほんのちょびっとです。

とはいいましたが、この記事はあくまで Video API の実装例の解説ですので、データベースを使用した詳しい実装は他の記事に譲ります。
値の格納・取り出しが出来ればOKです。
機能としては、

  1. 最初のクライアントがセッションIDを取得と同時にデータベースへ格納
  2. 別のクライアントがアクセスした際、データベースにセッションIDが既に存在したらそれを使用。
  3. 各々トークンを生成して入室

という感じのものを実装してください。
これで、「同じセッションID、異なるトークン」 で同じ部屋にそれぞれ入室できたら完了です。

今回、私はデータベースに Supabase というSaaSを使用しましたが、ここは、ご自身の使い慣れたものを使用してください。

追加で応用的な実装をいくつか

  • セッションIDと一緒に有効期限を設定して保存する
  • クライアントが全員退出したらセッションIDを破棄する(= セッションの破棄)

セッションIDからトークンを発行

続いて、このIDを使用してトークンの発行を行います。
発行には Session.generateToken を使用します。
Session は、先程作成したセッションのオブジェクトです。
コールバック関数で引数にとったやつですね。

app.ts
openToK.createSession ((error, session) => {
    if (error) throw error;

    const sessionID = session?.sessionId;
-   console.log (`"ID": ${sessionID}`);
+   const token = session?.generateToken(); // トークンを生成する関数
+   console.log (`Token: ${token}`);
});

たった1行!
いやぁ、ホントにコストが少なくて便利ですねぇ(感激)

てことで、生成されたトークンはこんな感じです。

console
Token: T1==cGFydG5lcl9pZD00NzgzNzMyMSZzaWc9YzcwMDA4YzllMTBmODZmNGEwYzk3ZTZhNzJiMDZmNDE0ZTljNTllODpzZXNzaW9uX2lkPTJfTVg0ME56Z3pOek15TVg1LU1UY3dNek15TXpNM01qY3hNWDVDYUhGMmVWWlVNbVpoUzJaMFpGSnNSVzFuUWxnMWJHZC1VSDUtJmNyZWF0ZV90aW1lPTE3MDMzMjMzNzImbm9uY2U9MC4xNDczMjAxNjg5MDMyMTA0MiZyb2xlPXB1Ymxpc2hlciZleHBpcmVfdGltZT0xNzAzNDA5NzcyJmluaXRpYWxfbGF5b3V0X2NsYXNzX2xpc3Q9

クライアントに映像を表示させる

HTMLに <script> タグを使用して、Video API のクライアントSDK を読み込みます。

index.html
<head>
    <!-- titleとかmetaとか -->
+   <script async src="https://static.opentok.com/v2/js/opentok.min.js"></script>
</head>

これで、ページ内でSDKが使えるようになりました。
SDKからは、OTOpenTokの略)というオブジェクトが提供されており、ここから関数を呼び出して操作を行います。

セッションの作成

まずは、セッションを作成します。
OT.initSession() は、アプリケーションIDとセッションIDを使用してセッションを作成します。
返り値として、セッションを表すオブジェクトが返されるので、変数にしまっておきましょう。

const session = OT.initSession (APP_ID, SESSION_ID); // セッションを作成

セッションを作成するときには、オプションで次の項目が設定できます。

  • メディアモード
    クライアントが映像を送信する方法を指定します。
    RelayedRouted の2つが指定できます。
  • 自動アーカイブ
    ビデオ通話が開始された時に、自動的に記録を開始するかを指定します。
    デフォルトでは、自動的には行われません。
  • ロケーション
    接続するサーバーの地域に影響します。(東京サーバーやシンガポールサーバー等)
    基本的には、クライアントに基づいて自動で決定されるため、指定せずに大丈夫です。

パブリッシャーの作成

次に、パブリッシャーを作成します。
このオブジェクトが映像をVonageサーバーに送信します。
返り値として、パブリッシャーを表すオブジェクトが返されるので、同じように変数にしまっておきましょう。

const publisher = OT.initPublisher(); // パブリッシャーを作成

パブリッシャーを接続

パブリッシャーをVonageサーバーと接続します。
Session.connect() を使用し、第一引数に生成したトークン、第二引数にコールバック関数を渡します。
そして、コールバック関数内で Session.publish() を使用して、映像をパブリッシュします。
引数には、先ほど作成したパブリッシャーのオブジェクトを渡します。

session.connect (TOKEN, error => {
    if (error) throw error; // エラーハンドリング

    session.publish (publisher); // パブリッシュ
});

サブスクライバーの作成

サブスクライバーの作成は、パブリッシャーとはちょっと異なり、このようになります。
というかどちらかというと、「登録」といったほうが良いですかね。

session.on ("streamCreated", event => {
    session.subscribe (event.stream); // サブスクライバーを作成
});

Session.on (event, callback) はイベントハンドラーです。
第一引数で指定したイベントが発行された時に、第二引数のコールバック関数を呼び出します。

今回では、"streamCreated" というイベントが発行されたときを刺します。


ということで、完成したクライアント側の全体像がこちらです。

index.ts
const session = OT.initSession (APP_ID, SESSION_ID); // セッションに接続
const publisher = OT.initPublisher(); // パブリッシャーを作成

session.connect (token, error => {
    if (error) throw error; // エラーハンドリング

    session.publish(publisher); // パブリッシュ
});

session.on ('streamCreated', event => {
    session.subscribe (event.stream); // サブスクライバーを作成
});

Congratulations!!!

これだけで、映像・音声のパブリッシュとサブスクライブが完了します。
後は、カメラやマイクで遊んでみてください。

インターネットに公開してURLを共有すれば、お友達を連れ込むことを出来るでしょう。

↓ より詳しいチュートリアルは公式ガイドをお読みください ↓

↓ また、実際にコードを書いてリアルタイムで体験する場も用意されています ↓

Set up a simple browser-based audio-video chat with Vonage Video API in a few minutes

さらにカスタマイズ

Video API で出来るのはただのビデオ通話だけではありません!
知る人ぞ知るあんなサービスやこんなサービスにも利用されている、一見複雑そうな便利機能・・・
そいつらも、パパッと簡単に組み込むことが出来ちゃう。そう、Vonageならね

ビデオ通話をアーカイブ(記録)する

Video API では、ビデオ通話の録音・録画がサポートされています。

1つの記録ごとに最大4時間の録画が可能で、ビデオ通話がそれ以上行われる場合は、自動で4時間毎に区切られながら記録されることになります。
つまり、9時間のビデオ通話を録画する場合、4時間の記録が2つと1時間の記録が1つできるわけです。

Video API のサーバーサイドSDKには、アーカイブのための関数が揃っています。

  • アーカイブの開始 OpenTok.startArchive (sessionId, options, callback)
  • アーカイブの停止 OpenTok.stopArchive (archiveId, callback)
  • アーカイブのリストアップ OpenTok.listArchives (options, callback)
  • アーカイブのメタ情報を取得 OpenTok.getArchive (archiveId, callback)
  • アーカイブの削除 OpenTok.deleteArchive (archiveId, callback)

また、あらかじめアーカイブを自動で行うようにすることも可能です。
自動的に記録を行いたい場合は、セッションを作成する際、引数にオプションとして指定する必要があります。

アーカイブを行えるのは、メディアモードがroutedに指定されているセッションだけです。
そのため、オプションで同時にメディアモードも指定してあげる必要があります。

- openToK.createSession ((error, session) => {
+ openToK.createSession ({ mediaMode: "routed", archiveMode: "always" }, (error, session) => {
    if (error) throw error;

    /* ... */

  });

この、{ mediaMode: "routed", archiveMode: "always" } オプションを OpenToK.createSession() の第1引数に渡すことで、ルーティングモードと自動アーカイブの設定を行っています。

Congratulations!!!

ビデオ通話を開始すると自動でアーカイブが始まり、ビデオ通話を終了した段階で、一連の記録がVonageに保存されます。

接続にIP制限をかける

IP制限の機能はエンタープライズ版のみの機能となります。

プライベートな会話をしてる最中、見ず知らずの人がいきなり割り込んできたら、、、
大半の人は、嫌でしょう。
特に、大事な会議なんかに入ってこられたら、、、ゾワッとしますね。

そこで便利なのが、IPアドレスによるアクセスの制限です。
これを組み込むと、ビデオ通話に参加できる端末を限定することが出来ます。

インターネットは広いですから、そのままでは誰でもセッションにアクセスし放題です。
会議なんかを想像していただけるとわかりやすいと思います。
Zoomなんかの会議中、見知らぬ人がいきなり入ってきて、、、

?「(ピコンッ)」
部長「誰だ貴様!」
?「地獄からの使者、スパイダーマ(ry」
部長「警備員!!!」

なんてことが起こりかねません。なんと恐ろしい。

こうならないようにも、プライベートな場には事前にセッションにIP制限をかけて、参加者を限定しておくことができます。
近代的ですね。

私は個人アカウントなので、設定方法の詳しい解説は出来ませんが(そもそもアクセス権がないため)
試してみたい方は ↓公式ガイド↓ をお読みください(ただし英語)

まとめ

  • Vonage Video API を使えば、簡単にビデオ通話が実装できる!
  • なんといっても多機能!

以上、私の知識を絞り出して書かせていただきました!
(ごちゃごちゃ詰め込みすぎて読みにくくなっちゃったかな?と少し心配ですが、、、)
参考になりましたら幸いです 🙏🙏🙏

また、不明な点、間違った点がございましたら、コメント等で気軽にご指摘ください。
随時更新して参ります!💪

【おまけ】参考にしたい記事の紹介

今回紹介したものの他にも、いろんな方々がいろんな活用例を解説してくださっています。
ぜひ参考にして、いっぱいインスピレーションを浴びてみてください。🚿

Vonage 公式ガイド

  • たくさんのチュートリアルが紹介されています。
    公式なので安心感も 👍

2023年の参考記事

  • ブラウザの Canvas API を利用して、AI画像認識を実装するというなんともツヨツヨ!
    高度なことをしていらっしゃるので、腕に自身のある方は挑戦してみては・・・

  • こちらでは、iOSのネイティブアプリ(Swift)内でARの実装をされています

2022年の参考記事

  • こちら、かなり実践的な内容となっています。
    Video API の活用例として非常に参考になります。

おわりに

執筆時点でアドベントカレンダーもいよいよ終盤・・・
隙間がどんどん埋まっていくのを視界の端に「早く仕上げなきゃ」と、
焦燥感がダバダバ溢れ、せっせとやる気に変換している今日この頃、、、
私は家で独りです ¬_¬

さて、ケ◯タッキーでも食べますか

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1