はじめに
リモートワークが当たり前になった今、ビデオ会議機能を自分のアプリに組み込みたいというニーズは増えている。個人的には「Zoom APIを使えばいいのでは」と思っていたんですが、料金体系やプライバシーの観点から、オープンソースの選択肢を探していた時に出会ったのがJitsi Meetだった。
Jitsi Meetは、GitHubで27,800以上のスターを獲得している、完全オープンソースのビデオ会議プラットフォームです。Apache 2.0ライセンスなので、商用利用も問題なし。521人以上のコントリビューターによって12年以上開発が続けられていて、これだけ実績があると安心感がある。
正直なところ、「オープンソースのビデオ会議」と聞くと品質が心配になるかもしれない。でも実際に触ってみると、ZoomやGoogle Meetと比べても遜色ないレベルなんですよね。
特徴・メリット
完全オープンソースで商用利用可能
これが一番のポイントです。Apache 2.0ライセンスなので、自社サービスに組み込んでも、ソースコードを公開する義務がない。SaaSに組み込む場合、ライセンスの問題は避けて通れないので、この点は大きい。
自前サーバーでの運用が可能
meet.jit.siという公式サーバーを無料で使えるんですが、プライバシーを重視するなら自前サーバーを立てることもできる。Dockerイメージも用意されているので、環境構築のハードルは低い。
医療系や金融系のアプリだと、データの所在地が問題になることがある。自前サーバーなら、日本国内のインフラで完結させることができるので、コンプライアンス的にも安心です。
豊富な機能
- HD音声・ビデオ通信
- 画面共有
- バーチャル背景
- チャット機能
- 挙手・リアクション
- ポーリング(投票)機能
- 録画対応
正直、これだけあれば大抵のユースケースはカバーできるんじゃないかと思う。
複数の統合方法
IFrame API、React SDK、モバイルSDK(iOS/Android)と、組み込み方法が複数用意されている。Webアプリならどれかは使えるはずです。
インストール方法
IFrame APIを使う場合
最もシンプルな方法です。HTMLファイルにスクリプトを追加するだけで使える。
<!DOCTYPE html>
<html>
<head>
<title>ビデオ会議</title>
<script src="https://meet.jit.si/external_api.js"></script>
</head>
<body>
<div id="meet" style="height: 600px;"></div>
<script>
const domain = 'meet.jit.si';
const options = {
roomName: 'MyMeetingRoom',
width: '100%',
height: '100%',
parentNode: document.querySelector('#meet'),
userInfo: {
displayName: '山田太郎'
}
};
const api = new JitsiMeetExternalAPI(domain, options);
</script>
</body>
</html>
これだけで動く。個人的には、この手軽さがJitsi Meetの魅力だと思っている。
React SDKを使う場合
Reactアプリに組み込むなら、公式のReact SDKが便利です。
npm install @jitsi/react-sdk
React 16以上が必要です。Next.jsやViteで作ったプロジェクトでも問題なく動作する。
基本的な使い方
React SDKでの実装例
import { JitsiMeeting } from '@jitsi/react-sdk';
const VideoConference = () => {
const handleApiReady = (api: any) => {
// APIが準備完了したときの処理
console.log('Jitsi Meet API ready');
// イベントリスナーの登録
api.addListener('participantJoined', (participant: any) => {
console.log('参加者が入室:', participant.displayName);
});
api.addListener('participantLeft', (participant: any) => {
console.log('参加者が退室:', participant.id);
});
};
const handleReadyToClose = () => {
console.log('会議が終了しました');
// 終了後の処理(リダイレクトなど)
};
return (
<JitsiMeeting
domain="meet.jit.si"
roomName="MyProjectMeeting"
configOverwrite={{
startWithAudioMuted: true,
startWithVideoMuted: false,
disableModeratorIndicator: true,
enableEmailInStats: false,
}}
interfaceConfigOverwrite={{
TOOLBAR_BUTTONS: [
'microphone', 'camera', 'desktop',
'fullscreen', 'hangup', 'chat',
'raisehand', 'tileview'
],
SHOW_JITSI_WATERMARK: false,
}}
userInfo={{
displayName: '山田太郎',
email: 'yamada@example.com'
}}
onApiReady={handleApiReady}
onReadyToClose={handleReadyToClose}
getIFrameRef={(iframeRef) => {
iframeRef.style.height = '600px';
}}
/>
);
};
export default VideoConference;
主要なAPI機能
JitsiMeetExternalAPIには便利なメソッドが揃っている。
// ミュート制御
api.executeCommand('toggleAudio');
api.executeCommand('toggleVideo');
// 画面共有
api.executeCommand('toggleShareScreen');
// 会議を終了
api.executeCommand('hangup');
// 参加者一覧を取得
api.getParticipantsInfo().then((participants) => {
console.log('現在の参加者:', participants);
});
// 会議室の情報を取得
api.getRoomsInfo().then((rooms) => {
console.log('会議室情報:', rooms);
});
設定のカスタマイズ
configOverwriteで細かい設定を変更できる。
const config = {
// 入室時の設定
startWithAudioMuted: true, // 音声ミュートで開始
startWithVideoMuted: false, // ビデオはONで開始
// 機能の制限
disableDeepLinking: true, // アプリへの誘導を無効化
enableWelcomePage: false, // ウェルカムページを非表示
// UIのカスタマイズ
prejoinPageEnabled: false, // プレジョインページを無効化
// セキュリティ
enableLobby: true, // ロビー機能を有効化
requireDisplayName: true, // 表示名を必須に
};
実践的なユースケース
オンライン診療システム
医療系のアプリに組み込むなら、自前サーバーでの運用がおすすめです。患者の個人情報を扱うので、データの流れを完全にコントロールできるのは大きい。
const TelemedicineRoom = ({ patientId, doctorId }) => {
const roomName = `consultation-${patientId}-${Date.now()}`;
return (
<JitsiMeeting
domain="your-jitsi-server.example.com"
roomName={roomName}
jwt={generateJWT(patientId, doctorId)} // 認証トークン
configOverwrite={{
startWithAudioMuted: false,
startWithVideoMuted: false,
enableLobby: true,
// 録画を有効化(同意を得た上で)
fileRecordingsEnabled: true,
}}
/>
);
};
教育プラットフォーム
オンライン授業やセミナーにも使える。挙手機能やチャットがあるので、双方向のコミュニケーションが取りやすい。
const ClassRoom = ({ classId, isTeacher }) => {
return (
<JitsiMeeting
domain="meet.jit.si"
roomName={`class-${classId}`}
configOverwrite={{
// 生徒は音声ミュートで入室
startWithAudioMuted: !isTeacher,
startWithVideoMuted: !isTeacher,
// 先生以外は画面共有不可
disableScreensharing: !isTeacher,
}}
interfaceConfigOverwrite={{
// 必要なボタンだけ表示
TOOLBAR_BUTTONS: isTeacher
? ['microphone', 'camera', 'desktop', 'chat', 'raisehand', 'hangup']
: ['microphone', 'camera', 'chat', 'raisehand', 'hangup'],
}}
/>
);
};
カスタマーサポート
問い合わせ対応にビデオ通話を導入するケース。待機室(ロビー)機能を使えば、サポート担当者が準備できてから顧客を入室させることができる。
const SupportRoom = ({ ticketId }) => {
const handleApiReady = (api) => {
// 通話開始時刻を記録
api.addListener('videoConferenceJoined', () => {
recordCallStart(ticketId);
});
// 通話終了時刻を記録
api.addListener('videoConferenceLeft', () => {
recordCallEnd(ticketId);
});
};
return (
<JitsiMeeting
domain="meet.jit.si"
roomName={`support-${ticketId}`}
configOverwrite={{
enableLobby: true,
lobbyMode: true,
}}
onApiReady={handleApiReady}
/>
);
};
自前サーバーの構築
本番環境で使うなら、自前サーバーの構築を検討した方がいい。Dockerを使えば比較的簡単に立てられる。
# リポジトリのクローン
git clone https://github.com/jitsi/docker-jitsi-meet.git
cd docker-jitsi-meet
# 環境変数の設定
cp env.example .env
./gen-passwords.sh
# 起動
docker-compose up -d
本格的に運用するなら、公式のハンドブックを一読することをおすすめする。負荷分散やSTUN/TURNサーバーの設定など、スケールさせるためのノウハウが詰まっている。
まとめ
Jitsi Meetは、オープンソースでありながら商用レベルの品質を持つビデオ会議プラットフォームです。
- Apache 2.0ライセンスで商用利用OK
- IFrame APIとReact SDKで簡単に組み込める
- 自前サーバーでプライバシーを確保できる
- 12年以上の開発実績と27,800以上のGitHubスター
「自分のアプリにビデオ通話機能を入れたい」という場合、コスパ的にも機能的にもJitsi Meetは有力な選択肢だと思う。特に、プライバシーやコンプライアンスを重視する場合、自前サーバーで運用できるのは大きなメリットです。
まずはmeet.jit.siで試してみて、感触を掴んでから本格的に検討するのがいいんじゃないかと思います。
