2021年12月1日

プログラミング

SkyWayとA-Frameを組み合わせて360度WebVR会議システムを作る!

目次

  1. はじめに
  2. SkyWayとは
  3. SkyWayのサンプルで多人数のオンライン通話をしてみる
  4. A-Frameと組み合わせてみる
  5. まとめ

はじめに

新しい技術にチャレンジし続けるpalanのアドベントカレンダーDay1、初日です!

『WebXR』をテーマにしたアドベントカレンダー『WebXR ( WebVR/WebAR ) Advent Calendar 2021』の Day 4 でもあります!
前回はやのせん@VR/メタバース教育さんの前回は「VIVE FlowでWebXR」について手短にでした。

今日はWebでリアルタイムコミュニケーションを実現する、SkyWayというSDKを使用し、A-Frameと組み合わせWebVR上で360度会議をする方法をご紹介していきます!

このような複数人での360度会議ができるようになります。

SkyWayとは

image.png (888.6 kB)

SkyWayはNTTコミュニケーションズが提供するビデオ通話、音声通話をかんたんにアプリに実装できる、マルチプラットフォームなSDKです。
WebベースのJavaScript SDKはもちろん、iOSやAndroidのSDKも用意されており、またサンプルのコードも充実しており、エンジニアが簡単にWeb会議など通話を組み込むことが可能です。

このように一対一の通信通話はもちろん、多人数の通話など、有料機能であれば録音しクラウドストレージに保存する機能などがあります。
image.png (169.9 kB)
image.png (102.7 kB)

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などを登録しておくと試しやすいです。
スクリーンショット 2021-12-01 0.56.58.png (154.1 kB)

また権限としてTURN、SFU、listAllPeers API、Peer認証などの利用可否を設定できます。
image.png (111.0 kB)

権限について

  • 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の削除などは除外し、とてもシンプルな構成にしました。

SkyWayのサンプルはこちらです。
スクリーンショット 2021-12-01 1.23.51.png (132.0 kB)

A-Frameと組み合わせてみる

それでは、A-Frameと組み合わせてみます!
今回はWebVR空間上にビデオ通話エリアを表示させていきます。
image (9).png (2.8 MB)

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を発行します。
image.png (151.9 kB)
他の参加者(実は別タブでも参加可能です)が同じルーム名でJoinされた際に、a-videoタグが追加され、そちらがこのように360度画像上に円状に表示され、近未来感のある会議システムができました!

スクリーンショット 2021-12-01 1.40.12.png (2.7 MB)

まとめ

今回はSkyWayを組み合わせ、360度空間でビデオ通話するサンプルを作成していきました。

実はもともとはWebARのSDKである8th Wallと組み合わせ、AR上で目の前の空間に通話相手を表示させる、というシステムを実現予定でした。ただビデオをAR上で表示する中での問題が起きており、そこの解決ができず一旦A-Frameベースですすめることにしました。
次回はWebAR上での会議システムを作っていこうと思います!

bageleeを運営しているpalanではこういったWebARの開発を行っている他、誰でも手軽にWebARをノーコードで作成できるpalanARというサービスも展開していますので、ご興味ある方はぜひご覧ください!

JavaScriptのお仕事に関するご相談

Bageleeの運営会社、palanではJavaScriptに関するお仕事のご相談を無料で承っております。
zoomなどのオンラインミーティング、お電話、貴社への訪問、いずれも可能です。
ぜひお気軽にご相談ください。

無料相談フォームへ

1

0

AUTHOR

eishis

Eishi Saito 総務

SIerやスタートアップ、フリーランスを経て2016年11月にpalan(旧eishis)を設立。 マーケター・ディレクター・エンジニアなど何でも屋。 COBOLからReactまで色んなことやります。

アプリでもっと便利に!気になる記事をチェック!

記事のお気に入り登録やランキングが表示される昨日に対応!毎日の情報収集や調べ物にもっと身近なメディアになりました。

簡単に自分で作れるWebAR

「palanAR」はオンラインで簡単に作れるWebAR作成ツールです。WebARとはアプリを使用せずに、Webサイト上でARを体験できる新しい技術です。

palanARへ
palanar

palanはWebARの開発を
行っています

弊社では企画からサービスの公開終了まで一緒に関わらせていただきます。 企画からシステム開発、3DCG、デザインまで一貫して承ります。

webar_waterpark

palanでは一緒に働く仲間を募集しています

正社員や業務委託、アルバイトやインターンなど雇用形態にこだわらず、
ベテランの方から業界未経験の方まで様々なかたのお力をお借りしたいと考えております。

話を聞いてみたい

運営メンバー

eishis

Eishi Saito 総務

SIerやスタートアップ、フリーランスを経て2016年11月にpalan(旧eishis)を設立。 マーケター・ディレクター・エンジニアなど何でも屋。 COBOLからReactまで色んなことやります。

sasakki デザイナー

アメリカの大学を卒業後、日本、シンガポールでデザイナーとして活動。

yamakawa

やまかわたかし デザイナー

フロントエンドデザイナー。デザインからHTML / CSS、JSの実装を担当しています。最近はReactやReact Nativeをよく触っています。

Sayaka Osanai デザイナー

Sketchだいすきプロダクトデザイナー。シンプルだけどちょっとかわいいデザインが得意。 好きな食べものは生ハムとお寿司とカレーです。

はらた

はらた エンジニア

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

kobori

こぼり ともろう エンジニア

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

sasai

ささい エンジニア

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

damien

Damien

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

ゲスト bagelee

ゲスト bagelee

かっきー

かっきー

まりな

まりな

suzuki

suzuki

miyagi

ogawa

ogawa

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

いわもと

いわもと

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

kobari

taishi kobari

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

shogokubota

kubota shogo

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

nishi tomoya

aihara

aihara

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

nagao

SIerを経てアプリのエンジニアに。xR業界に興味があり、unityを使って開発をしたりしています。

kainuma

Kainuma

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

sugimoto

sugimoto

asama

ando

CONTACT PAGE TOP