環境
- Momo
- https://github.com/shiguredo/momo
momo-2020.8.1_raspberry-pi-os_armv6
- Raspberry Pi Zero
- Ayame
- https://github.com/OpenAyame/ayame-web-sdk
@open-ayame/ayame-web-sdk@2020.3.0
- Google Chrome
動機
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
動作結果
こちらも送受信ともにちゃんと動作しました。