はじめに
この記事はとあるハッカソンのために事前勉強したものが特に使われることがなかったのでその供養のために書きます。
今回はskyway-jsをReactで試してみたという内容です。実装した内容は本当にチュートリアル程度のものなのですが、意外とReact(nativeじゃない方)の記事がなかったので書いてみようと思いました。
つくったもの
こちらで公開しています。単純にお互いのIDを交換しあって1対1のビデオチャットができるというものです。SkyWayを用いることで簡単にビデオチャットをアプリに実装することができます。
開発環境
デプロイ環境としてVercelを使ってみました。理由は、もともとこのSkyWayをNext.jsでやろうと思っていてその際に公式から推奨されるものであったのがこれだったからです。しかしNext.jsはskyway-jsのインポートがうまく行かなかったので途中で断念しました。
なので今回もcreate-react-app
を使ってReactの環境を構築しました。
実装内容
実装したのはこれだけです。
import React from 'react'
import { useState, useRef } from 'react'
import './App.css'
import Peer from 'skyway-js'
const peer = new Peer({ key: process.env.REACT_APP_SKYWAY_KEY })
const App = () => {
const [myId, setMyId] = useState('')
const [callId, setCallId] = useState('')
const localVideo = useRef(null)
const remoteVideo = useRef(null)
peer.on('open', () => {
setMyId(peer.id)
navigator.mediaDevices.getUserMedia({ video: true, audio: true }).then(localStream => {
localVideo.current.srcObject = localStream
})
})
peer.on('call', mediaConnection => {
mediaConnection.answer(localVideo.current.srcObject)
mediaConnection.on('stream', async stream => {
remoteVideo.current.srcObject = stream
})
})
const makeCall = () => {
const mediaConnection = peer.call(callId, localVideo.current.srcObject)
mediaConnection.on('stream', async stream => {
remoteVideo.current.srcObject = stream
await remoteVideo.current.play().catch(console.error)
})
}
return (
<div>
<div>skyway test</div>
<div><video width="400px" autoPlay muted playsInline ref={localVideo}></video></div>
<div>{myId}</div>
<div>
<input value={callId} onChange={e => setCallId(e.target.value)}></input>
<button onClick={makeCall}>発信</button>
</div>
<div><video width="400px" autoPlay muted playsInline ref={remoteVideo}></video></div>
</div>
)
}
export default App
navigator.mediaDevices.getUserMedia({ video: true, audio: true })
を使って、内蔵カメラ・マイクから取り込んだストリームを<video>
のsrcObject
に取り込むReactでの良い方法がわからなかったのでuseRef
を使って無理くりやりました。
コード全体はこちらで共有してますのでもう少し良い方法をご存知でしたらPRいただきたいです。
さいごに
いやー、**SkyWayめちゃ簡単ですね!**少し前に書いたこの記事のやつとかと組み合わせて何かやれたら面白そうだなと思いました。
とりあえず今回のハッカソンで使うことはなかったのですが、そのうちどこかで使おうかなと思います。