SkyWayを使用して自分のwebサイトにオンライン対話が出来る仕組みを作成してみた

SkyWayを使用して自分のwebサイトにオンライン対話が出来る仕組みを作成しました。
ルームIDでマッチングするので、ルームIDをWEB上に投稿できるように自分のサイトと組み合わせました。

SkyWay
https://webrtc.ecl.ntt.com/


#友人とのテストの様子
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612352/3f0c9404-c5ea-0482-7a10-de6f5c296d31.png)
※投稿することを了承いただいています。ありがとうございます。

#出来たこと
①事前に伝えたルームIDを指定することでビデオ会話が出来る
②ルーム内でチャットが出来る
③ルームIDをWEB上に投稿する機能

#出来なかったこと
①OSによって画面が反転することへの対応
②HTMLとCSSによる画面ビジュアル整え
③画面を両並びにサイズを調整すること

#公開ページ
https://3dblock.jp

#ルームIDを投稿
![FireShot Capture 003 - Voxel Ant - あなただけのブロックアートを。 - 3dblock.jp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612352/a10dfba3-b559-1e51-9fb4-a63da716e8f0.png)

画面下の[LET'S TALK]アイコンをクリックすることでトークルームに画面遷移

#ソースコード
```html:index6.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>会話ルーム</title>
    <link rel="stylesheet" href="../_shared/style.css">
</head>

<body>
    <div class="container">
        <h1 class="heading">内緒バナシ</h1>
        <p class="note">
            Change Room mode (before join in a room):
            <a href="#">mesh</a> / <a href="#sfu">sfu</a>
        </p>
        <div class="room">
            <div>
                <video id="js-local-stream"></video>
                <span id="js-room-mode"></span>:
                <input type="text" placeholder="Room Name" id="js-room-id">
                <button id="js-join-trigger">Join</button>
                <button id="js-leave-trigger">Leave</button>
            </div>

            <div class="remote-streams" id="js-remote-streams"></div>

            <div>
                <pre class="messages" id="js-messages"></pre>
                <input type="text" id="js-local-text">
                <button id="js-send-trigger">Send</button>
            </div>
        </div>
        <p class="meta" id="js-meta"></p>
    </div>
    <script src="//cdn.webrtc.ecl.ntt.com/skyway-latest.js"></script>
    <script src="main6.js"></script>
</body>

</html>
```

```js:main6.js
const Peer = window.Peer;

(async function main() {
    const localVideo = document.getElementById('js-local-stream');
    const joinTrigger = document.getElementById('js-join-trigger');
    const leaveTrigger = document.getElementById('js-leave-trigger');
    const remoteVideos = document.getElementById('js-remote-streams');
    const roomId = document.getElementById('js-room-id');
    const roomMode = document.getElementById('js-room-mode');
    const localText = document.getElementById('js-local-text');
    const sendTrigger = document.getElementById('js-send-trigger');
    const messages = document.getElementById('js-messages');
    const meta = document.getElementById('js-meta');
    const sdkSrc = document.querySelector('script[src*=skyway]');

    meta.innerText = `
    UA: ${navigator.userAgent}
    SDK: ${sdkSrc ? sdkSrc.src : 'unknown'}
  `.trim();

    const getRoomModeByHash = () => (location.hash === '#sfu' ? 'sfu' : 'mesh');

    roomMode.textContent = getRoomModeByHash();
    window.addEventListener(
        'hashchange',
        () => (roomMode.textContent = getRoomModeByHash())
    );

    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);

    // eslint-disable-next-line require-atomic-updates
    const peer = (window.peer = new Peer({
        key: "hogehoge",
        debug: 3,
    }));

    // Register join handler
    joinTrigger.addEventListener('click', () => {
        // Note that you need to ensure the peer has connected to signaling server
        // before using methods of peer instance.
        if (!peer.open) {
            return;
        }

        const room = peer.joinRoom(roomId.value, {
            mode: getRoomModeByHash(),
            stream: localStream,
        });

        room.once('open', () => {
            messages.textContent += '=== You joined ===\n';
        });
        room.on('peerJoin', peerId => {
            messages.textContent += `=== ${peerId} joined ===\n`;
        });

        // Render remote stream for new peer join in the room
        room.on('stream', async stream => {
            const newVideo = document.createElement('video');
            newVideo.srcObject = stream;
            newVideo.playsInline = true;
            // mark peerId to find it later at peerLeave event
            newVideo.setAttribute('data-peer-id', stream.peerId);
            remoteVideos.append(newVideo);
            await newVideo.play().catch(console.error);
        });

        room.on('data', ({ data, src }) => {
            // Show a message sent to the room and who sent
            messages.textContent += `${src}: ${data}\n`;
        });

        // for closing room members
        room.on('peerLeave', peerId => {
            const remoteVideo = remoteVideos.querySelector(
                `[data-peer-id=${peerId}]`
            );
            remoteVideo.srcObject.getTracks().forEach(track => track.stop());
            remoteVideo.srcObject = null;
            remoteVideo.remove();

            messages.textContent += `=== ${peerId} left ===\n`;
        });

        // for closing myself
        room.once('close', () => {
            sendTrigger.removeEventListener('click', onClickSend);
            messages.textContent += '== You left ===\n';
            Array.from(remoteVideos.children).forEach(remoteVideo => {
                remoteVideo.srcObject.getTracks().forEach(track => track.stop());
                remoteVideo.srcObject = null;
                remoteVideo.remove();
            });
        });

        sendTrigger.addEventListener('click', onClickSend);
        leaveTrigger.addEventListener('click', () => room.close(), { once: true });

        function onClickSend() {
            // Send message to all of the peers in the room via websocket
            room.send(localText.value);

            messages.textContent += `${peer.id}: ${localText.value}\n`;
            localText.value = '';
        }
    });

    peer.on('error', console.error);
})();   

```

#解説
`key: "hogehoge",`の部分は、SkyWayにログイン後に確認できるご自身のAPIを指定します。

#最後に
・時間が空いたらもう少しHTML/CSSでUI面の調整をしたいと思います。