LoginSignup
2
2

More than 3 years have passed since last update.

WebRTC Native Client Momo の test モードと Ayame Web SDK で通信してみる

Posted at

環境

動機

Raspberry Pi のカメラで撮った映像を Momo を使って PC に送り、そこに JavaScript で色々手を加えたかったのですが、test モードで出てくる HTML と JS が結構いじりにくいものだったので、Ayame でなんとかできないかと試行錯誤したものです。

Momo 2020.6 のリリース で test モードと ayame モードの相互接続が可能であることが言われていたり、Discord 上でも Ayame 互換であるようなことが言われていたりしますが、Ayame Web SDK による利用について何も情報がないので記しておきます。

仕様の確認

Momo が test モードで動いたときに配信される HTML と JS は /html 以下のものです。

これと ayame-web-sdk および Ayame の仕様書 を見比べることで、なんとなく何が違うのかを探ることができます。

正直細かいところまではわかりませんでしたが、おそらく Ayame のプロトコルの register/accept 部分を除いてそれ以降は test モードと同じ動作をしているように見えます。ということで、エンドポイントは ws://[Raspberry Pi の IP アドレス]:8080/ws とし、roomId は空でも良いようです。

コード

https://github.com/OpenAyame/ayame-web-sdk-samples/blob/master/recvonly.html を参考にします。

<button id="connect-button"></button>
<button id="disconnect-button"></button>
<video id="remote-video"></video>
const remoteVideo = document.getElementById('remote-video');
const connectButton = document.getElementById('connect-button');
const disconnectButton = document.getElementById('disconnect-button');

const conn = Ayame.connection('ws://raspberrypi.local:8080/ws', '', {
  ...Ayame.defaultOptions,
  audio: { enabled: false },
  video: { direction: 'recvonly', enabled: true, codec: 'H264' },
});
conn.on('open', (e) => {
  console.log('open', e);
});
conn.on('disconnect', (e) => {
  console.log('disconnect', e);
});
conn.on('addstream', (e) => {
  console.log('addstream', e);
  remoteVideo.srcObject = e.stream;
  remoteVideo.play();
});

connectButton.addEventListener('click', () => {
  conn.connect(null);
});
disconnectButton.addEventListener('click', () => {
  conn.disconnect();
});
$ ./momo --no-audio-device --use-native --force-i420 test

動作結果

やってみたら案外ちゃんと動きました。

ただ、Connect ボタンを押してから動画が表示されるまでの時間が、test モードで出てくるページでは1秒以内に収まるのに対し、上のものを使うとたまに3秒程度かかることがありました。(ページを PC 側のローカルサーバではなく Raspberry Pi から配信するようにしたらこれがなくなったので、ページの置き場所による?)

データチャンネルも使ってみる

https://github.com/OpenAyame/ayame-web-sdk-samples/blob/master/datachannel.html を参考にします。

test モードにおけるラベルは serial になっていますが、他のもので試しても動いたので何でも良いようです。

const remoteVideo = document.getElementById('remote-video');
const connectButton = document.getElementById('connect-button');
const disconnectButton = document.getElementById('disconnect-button');

const conn = Ayame.connection('ws://raspberrypi.local:8080/ws', '', {
  ...Ayame.defaultOptions,
  audio: { enabled: false },
  video: { direction: 'recvonly', enabled: true, codec: 'H264' },
});

let dataChannel = null;
const sendData = (data) => {
  if (dataChannel && dataChannel.readyState === 'open') {
    dataChannel.send(data);
  }
};
const onMessage = (e) => {
  console.log(new TextDecoder().decode(e.data));
};

conn.on('open', async (e) => {
  console.log('open', e);
  dataChannel = await conn.createDataChannel('serial');
  if (dataChannel) {
    dataChannel.onmessage = onMessage;
  }
});
conn.on('datachannel', (channel) => {
  if (!dataChannel) {
    dataChannel = channel;
    dataChannel.onmessage = onMessage;
  }
});
conn.on('disconnect', (e) => {
  console.log('disconnect', e);
  dataChannel = null;
});
conn.on('addstream', (e) => {
  console.log('addstream', e);
  remoteVideo.srcObject = e.stream;
  remoteVideo.play();
});

connectButton.addEventListener('click', () => {
  conn.connect(null);
});
disconnectButton.addEventListener('click', () => {
  conn.disconnect();
});
$ socat -d -d pty,raw,echo=0 pty,raw,echo=0
> 2020/10/12 16:36:51 socat[1017] N PTY is /dev/pts/1
> 2020/10/12 16:36:51 socat[1017] N PTY is /dev/pts/2
> 2020/10/12 16:36:51 socat[1017] N starting data transfer loop with FDs [5,5] and [7,7]
$ ./momo --no-audio-device --use-native --force-i420 --serial /dev/pts/1,9600 test

動作結果

こちらも送受信ともにちゃんと動作しました。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2