ある中卒がWeb系エンジニアになるまでと、それからのこと

うつ病で高校を中退したり、たこ焼き屋のオヤジにホームページとたこ焼きを作らされたり、そのホームページが訴えられそうになったり、弁護士を目指したりした後にエンジニアになった人が書くブログ

vueプロジェクトでskywayを使ったグループ通話ができなかったので超力技で半分解決した話

2020/07/02の日報

Hanasot開発の日報、第6日目です。
今日は昨日に引き続き

  • vueプロジェクト内でskywayによるグループ通話を実装する

を行いました。
時間としては、

  • Hanasot開発 1h20min
  • 日報ブログ 1h11min

です。
運動は

  • 包丁研ぎ 3本(地味にきついので入れさせてください)
  • エアロバイク 15min

です。

vueプロジェクト内でskywayによるグループ通話を実装する

さて、昨日の記事でハマっているとお伝えしたグループ通話ですが、ちょっと進展しました。

f:id:chusotsuengineer:20200702215441p:plain
クレーンゲームで取った猫×3
参加者の数だけvideoタグを生成することに成功したのです。素晴らしい。
次にソースコードをご覧ください。

<template>
  <div>
    ~~~中略~~~
    <video
      v-for="participant in participants"
      :key="participant"
      :id="participant"
      width="400px"
      autoplay muted playsinline></video>
  </div>
</template>
<script>
  import Peer from 'skyway-js';
  export default {
    name: 'Dialogue',
    data() {
      return {
    ~~~中略~~~
        participants: [],
      }
    },
    methods: {
      makeCall() {
        const mediaConnection = this.peer.joinRoom(this.theirID, {
          mode: 'sfu',
          stream: this.localStream,
        });
        this.setEventListener(mediaConnection);
      },
      async setEventListener(mediaConnection) {
        const participants = [];
        let remoteStreams = [];
        Promise.all(mediaConnection.on('stream', () => {
          // video要素にカメラ映像をセットして再生
          Object.keys(mediaConnection.remoteStreams).forEach( key => {
            const remoteStream = mediaConnection.remoteStreams[key];
            const remoteId = remoteStream.peerId;
            participants.push(remoteId);
            remoteStreams.push(remoteStream);
          });
        }));
        this.participants = participants;
        await new Promise(resolve => setTimeout(resolve, 1000));
        remoteStreams.map(remoteStream => {
          const videoElm = document.getElementById(remoteStream.peerId);
          videoElm.srcObject = remoteStream;
          videoElm.play();
        });
      }
    },
  }
</script>

おわかりでしょうか。昨日thisの対象が変わってしまってparticipantsがundefinedになってしまっていたのをループ外に出すことで対応し、DOMが生成されるまで1秒待機してvideoタグにsrcを設定しています。
うん。ダサい。クソダサいです。
まあそれは一旦置いておきましょう。リファクタリングは後からできますからね。きっとしますよ。大丈夫。がんばれ未来の僕。
問題はこちらです。

f:id:chusotsuengineer:20200702220128p:plain
2番目に通話に参加した人の画面
f:id:chusotsuengineer:20200702220210p:plain
最初に通話に参加した人の画面
違いわかりますかね。難しいですがよーく見てください。2番目に参加した人の画面には3番目に参加した人が映っておらず、最初に参加した人の画面には2番目の人も3番目の人も映っていません。
なぜだ...

DOMがどうもダメっぽい

表示されていない1番目の人のDOMを調べてみるとですね。videoタグ自体は生成できているんです。idもちゃんと相手方のものが設定された状態で。
その上で映像だけが映っていないとなれば問題はsrcの設定ということになります。やっぱawaitで1秒待たせて無理やり映してるのがだめなのかなぁ。

所感

ちょっと今日は時間がなくて軽くしかまとめられませんでしたが、今はこんな状況です。なかなか複数人通話ができませんね。うーむ。
明日はsrcタグの設定にあたりをつけてやっていきます。先輩に助言を求めてみようかな。