2021年12月1日
プログラミング
SkyWayとA-Frameを組み合わせて360度WebVR会議システムを作る!


はじめに
新しい技術にチャレンジし続けるpalanのアドベントカレンダーDay1、初日です!
『WebXR』をテーマにしたアドベントカレンダー『WebXR ( WebVR/WebAR ) Advent Calendar 2021』の Day 4 でもあります!
前回はやのせん@VR/メタバース教育さんの前回は「VIVE FlowでWebXR」について手短にでした。
今日はWebでリアルタイムコミュニケーションを実現する、SkyWayというSDKを使用し、A-Frameと組み合わせWebVR上で360度会議をする方法をご紹介していきます!
このような複数人での360度会議ができるようになります。
SkyWayとは
SkyWayはNTTコミュニケーションズが提供するビデオ通話、音声通話をかんたんにアプリに実装できる、マルチプラットフォームなSDKです。
WebベースのJavaScript SDKはもちろん、iOSやAndroidのSDKも用意されており、またサンプルのコードも充実しており、エンジニアが簡単にWeb会議など通話を組み込むことが可能です。
このように一対一の通信通話はもちろん、多人数の通話など、有料機能であれば録音しクラウドストレージに保存する機能などがあります。
SkyWayのサンプルで多人数のオンライン通話をしてみる
それでは、サンプルベースで多人数のオンライン通話を実装してみましょう。
こちらのチュートリアルに従っていきましょう。
CDN、もしくはnpmからSkyWayのパッケージをインポートします。
$ npm install skyway-js
<script src="https://cdn.webrtc.ecl.ntt.com/skyway-4.4.3.js"></script>
次にアプリケーションを追加し、ドメインを追加します。
設定画面でAPIが確認できる他、ドメインはいつでも追加編集可能です。
ここでドメインホワイトリストを登録しないと使用することができません。
localhostやngrokを検証用、デプロイ用にs3などを登録しておくと試しやすいです。
また権限としてTURN、SFU、listAllPeers API、Peer認証などの利用可否を設定できます。
権限について
- TURN(Traversal Using Relays around NAT)サーバは、データを中継することで、企業ネットワークなどP2P通信が利用できない特定のネットワーク環境でのWebRTC利用を可能にします。(SkyWayドキュメントより)
- SFU(Selective Forwarding Unit)サーバは、多人数通話や映像配信を実現します。3人以上で通信する際に端末のエンコード負荷と上り帯域幅や通信量を削減できるため、Mesh方式より多人数での通信が可能になります。(SkyWayドキュメントより)
- listAllPeers APIは接続中のPeer(接続を管理するエージェント)一覧を表示させるAPIです。簡単に言ってしまうと接続中のユーザー一覧を見ることができます。
それでは設定が終わったらサンプルコードを実装していきます。
こちらの多人数通話のコードを参考にしていきます。
const Peer = window.Peer;
(async function main() {
// 自分のストリーミングエリア
const localVideo = document.getElementById('js-local-stream');
// ルームへの参加ボタン
const joinTrigger = document.getElementById('js-join-trigger');
const roomId = document.getElementById('js-room-id');
const getRoomModeByHash = () => (location.hash === '#sfu' ? 'sfu' : 'mesh');
// カメラや音声へのアクセス
const localStream = await navigator.mediaDevices
.getUserMedia({
audio: true,
video: true,
})
.catch(console.error);
// Render local stream
localVideo.muted = true;
localVideo.srcObject = localStream;
localVideo.playsInline = true;
await localVideo.play().catch(console.error);
const peer = (window.peer = new Peer({
key: "", // api keyの入力
debug: 3,
}));
joinTrigger.addEventListener('click', () => {
if (!peer.open) {
return;
}
const room = peer.joinRoom(roomId.value, {
mode: getRoomModeByHash(),
stream: localStream,
});
room.on('stream', async stream => {
// videoタグを追加しpeerIdを付与
const newVideo = document.createElement('video');
newVideo.srcObject = stream;
newVideo.playsInline = true;
newVideo.setAttribute('id', stream.peerId);
newVideo.setAttribute('data-peer-id', stream.peerId);
aAssets.append(newVideo);
});
});
peer.on('error', console.error);
})();
たったこれだけのコードで通話処理が可能です!
※サンプルからPeerの削除などは除外し、とてもシンプルな構成にしました。
A-Frameと組み合わせてみる
それでは、A-Frameと組み合わせてみます!
今回はWebVR空間上にビデオ通話エリアを表示させていきます。
index.html
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>SkyWay 360</title>
<link rel="stylesheet" href="./style.css">
<script src="https://aframe.io/releases/1.0.1/aframe.min.js"></script>
<a-scene>
<a-assets>
<img id="image1" src="./image1.jpg">
<video id="js-local-stream"></video>
</a-assets>
<a-sky id="image-360" radius="10" src="#image1"></a-sky>
<a-video src="#js-local-stream" width="1" height="1" position="0 2 -3"></a-video>
</a-scene>
<div class="container" style="position: absolute; top: 1px;">
<div id="header">
<h1 class="heading" style="color: white;">360度会議システム</h1>
<div class="room">
<div>
<input type="text" placeholder="Room Name" id="js-room-id">
<button id="js-join-trigger">Join</button></div>
</div>
</div>
</div>
<script src="//cdn.webrtc.ecl.ntt.com/skyway-4.4.3.js"></script>
<script src="./script.js"></script>
a-assetsに自分のストリーミング映像(video要素)を入れ、そこからa-videoで呼び出しています。
<a-video src="#js-local-stream" width="1" height="1" position="0 2 -3"></a-video>
またJS部分ではルームへの参加者が増えるごとにvideo要素とa-videoを追加しています。
room.on('stream', async stream => {
member += 1;
const newVideo = document.createElement('video');
newVideo.srcObject = stream;
newVideo.playsInline = true;
newVideo.setAttribute('id', stream.peerId);
newVideo.setAttribute('data-peer-id', stream.peerId);
aAssets.append(newVideo);
const newAVideo = document.createElement('a-video');
newAVideo.setAttribute('src', '#' + stream.peerId);
newAVideo.setAttribute('width', 1);
newAVideo.setAttribute('height', 1);
newAVideo.setAttribute("position", {x:member * 1.75, y:2, z:-3});
aScene.append(newAVideo);
await newVideo.play().catch(console.error);
});
positionだけではなく本来rotationで角度も動的に変更する、など対処が必要ですが今回は簡易版なのでpositionのx軸のみ動的座標にしています。
こうして完成したのがこちらのシステムです!
まずこちらのJoinでルーム名を入力し、PeerIdを発行します。
他の参加者(実は別タブでも参加可能です)が同じルーム名でJoinされた際に、a-videoタグが追加され、そちらがこのように360度画像上に円状に表示され、近未来感のある会議システムができました!
まとめ
今回はSkyWayを組み合わせ、360度空間でビデオ通話するサンプルを作成していきました。
実はもともとはWebARのSDKである8th Wallと組み合わせ、AR上で目の前の空間に通話相手を表示させる、というシステムを実現予定でした。ただビデオをAR上で表示する中での問題が起きており、そこの解決ができず一旦A-Frameベースですすめることにしました。
次回はWebAR上での会議システムを作っていこうと思います!
bageleeを運営しているpalanではこういったWebARの開発を行っている他、誰でも手軽にWebARをノーコードで作成できるpalanARというサービスも展開していますので、ご興味ある方はぜひご覧ください!
JavaScriptのお仕事に関するご相談
Bageleeの運営会社、palanではJavaScriptに関するお仕事のご相談を無料で承っております。
zoomなどのオンラインミーティング、お電話、貴社への訪問、いずれも可能です。
ぜひお気軽にご相談ください。
この記事は
参考になりましたか?
1
0
関連記事

2018年7月6日
【js】jQueryでできるハンバーガーメニューの作成

2018年6月18日
プログレスバーを簡単に実装できるprogressbar.js

2018年5月8日
画像に簡単にアニメーションをつけるcurtain.js

2018年2月14日
【js】jQueryでできるアコーディオンメニューの作成

2017年9月4日
【JS】スクロールした時にCSSanimationを発動させる「scrollMonitor」
簡単に自分で作れるWebAR
「palanAR」はオンラインで簡単に作れるWebAR作成ツールです。WebARとはアプリを使用せずに、Webサイト上でARを体験できる新しい技術です。
palanARへ
palanでは一緒に働く仲間を募集しています
正社員や業務委託、アルバイトやインターンなど雇用形態にこだわらず、
ベテランの方から業界未経験の方まで様々なかたのお力をお借りしたいと考えております。
運営メンバー

Eishi Saito 総務
SIerやスタートアップ、フリーランスを経て2016年11月にpalan(旧eishis)を設立。 マーケター・ディレクター・エンジニアなど何でも屋。 COBOLからReactまで色んなことやります。
sasakki デザイナー
アメリカの大学を卒業後、日本、シンガポールでデザイナーとして活動。

やまかわたかし デザイナー
フロントエンドデザイナー。デザインからHTML / CSS、JSの実装を担当しています。最近はReactやReact Nativeをよく触っています。
Sayaka Osanai デザイナー
Sketchだいすきプロダクトデザイナー。シンプルだけどちょっとかわいいデザインが得意。 好きな食べものは生ハムとお寿司とカレーです。

はらた エンジニア
サーバーサイドエンジニア Ruby on Railsを使った開発を行なっています

こぼり ともろう エンジニア
サーバーサイドエンジニア。SIerを経て2019年7月に入社。日々学習しながらRuby on Railsを使った開発を行っています。

ささい エンジニア
フロントエンドエンジニア WebGLとReactが強みと言えるように頑張ってます。

Damien
WebAR/VRの企画・開発をやっています。森に住んでいます。

ゲスト bagelee

かっきー

まりな

suzuki
miyagi

ogawa
雑食デザイナー。UI/UXデザインやコーディング、時々フロントエンドやってます。最近はARも。

いわもと
デザイナーをしています。 好きな食べ物はラーメンです。

taishi kobari
フロントエンドの開発を主に担当してます。Blitz.js好きです。

kubota shogo
サーバーサイドエンジニア。Ruby on Railsを使った開発を行いつつ月500kmほど走っています!
nishi tomoya

aihara
グラフィックデザイナーから、フロントエンドエンジニアになりました。最近はWebAR/VRの開発や、Blender、Unityを触っています。モノづくりとワンコが好きです。
nagao
SIerを経てアプリのエンジニアに。xR業界に興味があり、unityを使って開発をしたりしています。

Kainuma
サーバーサイドエンジニア Ruby on Railsを使った開発を行なっています

sugimoto
asama
ando
iwasawa ayane

oshimo
異業界からやってきたデザイナー。 palanARのUIをメインに担当してます。 これからたくさん吸収していきます!