Agora.ioを使用した完全なビデオ通話アプリケーションの実装チュートリアル

こんにちは、チャリセです!
最近Agora.ioを使ってメタバース空間にビデオ通話の実装作業をしています。
今回は、Agora.ioを使用して、ウェブブラウザ上で動作する完全なビデオ通話アプリケーションを作成する方法を説明します。このアプリケーションには、基本的なビデオ通話機能に加えて、音声とビデオのミュート機能も含まれています。
1. 準備
まず始めに、以下の準備が必要です:
- Agora.ioのウェブサイトでアカウントを作成します。
- ダッシュボードから新しいプロジェクトを作成します。
- プロジェクトの App ID と一時的なトークン(テスト用)を取得します。
2. プロジェクトの構造
プロジェクトは以下の2つのファイルで構成されます:
index.html: アプリケーションのユーザーインターフェースapp.js: ビデオ通話機能の実装
3. HTML (index.html)
以下の内容で index.html ファイルを作成します:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Agora ビデオ通話デモ</title>
<style>
.video-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.video-player {
width: 320px;
height: 240px;
margin: 10px;
background-color: #f0f0f0;
border: 1px solid #ccc;
}
</style>
</head>
<body>
<h1>Agora ビデオ通話デモ</h1>
<div>
<button id="join">通話に参加</button>
<button id="leave">通話を終了</button>
<button id="toggleAudio">音声ミュート切替</button>
<button id="toggleVideo">ビデオミュート切替</button>
</div>
<div id="video-container" class="video-container"></div>
<script src="https://download.agora.io/sdk/release/AgoraRTC_N-4.17.2.js"></script>
<script src="app.js"></script>
</body>
</html>
4. JavaScript (app.js)
以下の内容で app.js ファイルを作成します:
import AgoraRTC from "agora-rtc-sdk-ng";
let rtc = {
localAudioTrack: null,
localVideoTrack: null,
client: null,
};
let options = {
appId: "あなたのApp ID",
channel: "test",
token: "あなたの一時トークン",
uid: Math.floor(Math.random() * 1000000),
audioMuted: false,
videoMuted: false,
};
async function startBasicCall() {
rtc.client = AgoraRTC.createClient({mode: "rtc", codec: "vp8"});
rtc.client.on("user-published", async (user, mediaType) => {
await rtc.client.subscribe(user, mediaType);
if (mediaType === "video") {
const remoteVideoTrack = user.videoTrack;
const remotePlayerContainer = document.createElement("div");
remotePlayerContainer.id = user.uid.toString();
remotePlayerContainer.className = "video-player";
remotePlayerContainer.textContent = "リモートユーザー " + user.uid.toString();
document.getElementById("video-container").append(remotePlayerContainer);
remoteVideoTrack.play(remotePlayerContainer);
}
if (mediaType === "audio") {
const remoteAudioTrack = user.audioTrack;
remoteAudioTrack.play();
}
});
rtc.client.on("user-unpublished", user => {
const remotePlayerContainer = document.getElementById(user.uid);
remotePlayerContainer.remove();
});
document.getElementById("join").onclick = async function () {
await rtc.client.join(options.appId, options.channel, options.token, options.uid);
rtc.localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack();
rtc.localVideoTrack = await AgoraRTC.createCameraVideoTrack();
await rtc.client.publish([rtc.localAudioTrack, rtc.localVideoTrack]);
const localPlayerContainer = document.createElement("div");
localPlayerContainer.id = options.uid;
localPlayerContainer.className = "video-player";
localPlayerContainer.textContent = "ローカルユーザー " + options.uid;
document.getElementById("video-container").append(localPlayerContainer);
rtc.localVideoTrack.play(localPlayerContainer);
console.log("ローカルトラックの公開成功");
};
document.getElementById("leave").onclick = async function () {
rtc.localAudioTrack.close();
rtc.localVideoTrack.close();
document.getElementById(options.uid).remove();
rtc.client.remoteUsers.forEach(user => {
const playerContainer = document.getElementById(user.uid);
playerContainer && playerContainer.remove();
});
await rtc.client.leave();
console.log("チャンネルから退出しました");
};
document.getElementById("toggleAudio").onclick = async function () {
if (rtc.localAudioTrack) {
if (options.audioMuted) {
await rtc.localAudioTrack.setEnabled(true);
options.audioMuted = false;
this.textContent = "音声ミュート";
} else {
await rtc.localAudioTrack.setEnabled(false);
options.audioMuted = true;
this.textContent = "音声ミュート解除";
}
}
};
document.getElementById("toggleVideo").onclick = async function () {
if (rtc.localVideoTrack) {
if (options.videoMuted) {
await rtc.localVideoTrack.setEnabled(true);
options.videoMuted = false;
this.textContent = "ビデオミュート";
} else {
await rtc.localVideoTrack.setEnabled(false);
options.videoMuted = true;
this.textContent = "ビデオミュート解除";
}
}
};
}
startBasicCall();
5. アプリケーションの機能説明
このアプリケーションは以下の機能を提供します:
- 通話への参加: 「通話に参加」ボタンをクリックすると、ユーザーはAgoraのチャンネルに接続し、ローカルの音声とビデオをストリーミングし始めます。
- 通話からの退出: 「通話を終了」ボタンをクリックすると、ユーザーはチャンネルから退出し、すべてのトラックを閉じます。
- 音声ミュート切替: 「音声ミュート切替」ボタンをクリックすると、ローカルの音声トラックのミュート状態を切り替えます。
- ビデオミュート切替: 「ビデオミュート切替」ボタンをクリックすると、ローカルのビデオトラックのミュート状態を切り替えます。
- リモートユーザーの表示: 他のユーザーが同じチャンネルに参加すると、そのユーザーのビデオが自動的に表示されます。
6. セキュリティに関する注意
このデモでは、App IDとトークンをクライアントサイドのコードに直接記述していますが、実際のアプリケーションではこれは安全ではありません。本番環境では、以下の対策を講じることをお勧めします:
- トークンの生成と管理をサーバーサイドで行う。
- クライアントはサーバーAPIを介してトークンを取得する。
- トークンに有効期限を設定し、定期的に更新する。
7. 発展的な実装のアイデア
このベーシックな実装をさらに改善するためのアイデアをいくつか紹介します:
- 視覚的フィードバック: ミュート状態を示すアイコンやオーバーレイをビデオプレイヤーに追加する。
- キーボードショートカット: 一般的なビデオ会議アプリのように、キーボードショートカット(例:Mキーで音声ミュート、Vキーでビデオミュート)を実装する。
- 参加者リスト: 各参加者の音声・ビデオ状態を表示する参加者リストを実装する。
- 画面共有: Agora SDKの画面共有機能を利用して、ユーザーが自分の画面を共有できるようにする。
- チャット機能: テキストベースのチャット機能を追加して、ビデオ通話中にメッセージを交換できるようにする。
- 録画機能: 通話の録画機能を実装して、後で再生や共有ができるようにする。
8. まとめ
このチュートリアルでは、Agora.ioを使用して基本的なビデオ通話アプリケーションを作成する方法を紹介しました。HTMLとJavaScriptを使用して、ビデオ通話への参加、退出、音声・ビデオのミュート機能を実装しました。
この基本的な実装を土台として、さらに多くの機能を追加し、ユーザーのニーズに合わせてカスタマイズしていくことができます。Agora.ioのSDKは非常に柔軟で強力なので、創造力次第で様々な機能を実現できます。
ビデオ通話アプリケーションの開発を楽しんでください!
Happy coding!
現在
株式会社チョモランマ
株式会社シェルパ
3Dmodeljapan株式会社
ではスタッフを大募集しております!!
Unreal Engine4、AI、プログラミングや建築パースに興味がある方!
ぜひご応募下さい!!
初心者の方、未経験の方やインターンを受けてみたい方々でも大歓迎です!!









