Skip to content

Commit

Permalink
sendrecv を class 化する
Browse files Browse the repository at this point in the history
  • Loading branch information
voluntas committed Feb 29, 2024
1 parent ebbfd2a commit a21fb76
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 117 deletions.
10 changes: 5 additions & 5 deletions examples/sendrecv/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ <h1>Sendrecv test</h1>
<div style="display: flex;">
<div>
<h2>sendrecv1</h2>
<button id="start-sendrecv1">start</button>
<button id="stop-sendrecv1">stop</button><br />
<button id="sendrecv1-start">start</button>
<button id="sendrecv1-stop">stop</button><br />
<video id="sendrecv1-local-video" autoplay="" playsinline="" controls=""
style="width: 320px; height: 240px; border: 1px solid black;"></video>
<div id="sendrecv1-connection-id"></div>
<div id="sendrecv1-remote-videos"></div>
</div>
<div>
<h2>sendrecv2</h2>
<button id="start-sendrecv2">start</button>
<button id="stop-sendrecv2">stop</button><br />
<button id="sendrecv2-start">start</button>
<button id="sendrecv2-stop">stop</button><br />
<video id="sendrecv2-local-video" autoplay="" playsinline="" controls=""
style="width: 320px; height: 240px; border: 1px solid black;"></video>
<div id="sendrecv2-connection-id"></div>
Expand All @@ -30,7 +30,7 @@ <h2>sendrecv2</h2>
</div>
</div>

<script type="module" src="./main.mjs"></script>
<script type="module" src="./main.mts"></script>
</body>

</html>
108 changes: 0 additions & 108 deletions examples/sendrecv/main.mjs

This file was deleted.

142 changes: 142 additions & 0 deletions examples/sendrecv/main.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import Sora, {
type SoraConnection,
type SignalingNotifyMessage,
ConnectionPublisher,
} from '../../dist/sora'

document.addEventListener('DOMContentLoaded', async () => {
const SORA_SIGNALING_URL = import.meta.env.VITE_SORA_SIGNALING_URL
const SORA_CHANNEL_ID_PREFIX = import.meta.env.VITE_SORA_CHANNEL_ID_PREFIX || ''
const SORA_CHANNEL_ID_SUFFIX = import.meta.env.VITE_SORA_CHANNEL_ID_SUFFIX || ''
const ACCESS_TOKEN = import.meta.env.VITE_ACCESS_TOKEN || ''

const sendrecv1 = new SoraClient(
'sendrecv1',
SORA_SIGNALING_URL,
SORA_CHANNEL_ID_PREFIX,
SORA_CHANNEL_ID_SUFFIX,
ACCESS_TOKEN,
)

const sendrecv2 = new SoraClient(
'sendrecv2',
SORA_SIGNALING_URL,
SORA_CHANNEL_ID_PREFIX,
SORA_CHANNEL_ID_SUFFIX,
ACCESS_TOKEN,
)

document.querySelector('#sendrecv1-start')?.addEventListener('click', async () => {
// sendrecv1
const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: true })
await sendrecv1.connect(stream)
})
document.querySelector('#sendrecv1-stop')?.addEventListener('click', async () => {
await sendrecv1.disconnect()
})

document.querySelector('#sendrecv2-start')?.addEventListener('click', async () => {
// sendrecv2
const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: true })
await sendrecv2.connect(stream)
})
document.querySelector('#sendrecv2-stop')?.addEventListener('click', async () => {
await sendrecv2.disconnect()
})
})

class SoraClient {
// sendrecv1 or sendrecv2
private label: string

private debug = false

private channelId: string
private metadata: { access_token: string }
private options: object

private sora: SoraConnection
private connection: ConnectionPublisher

constructor(
label: string,
signalingUrl: string,
channelIdPrefix: string,
channelIdSuffix: string,
accessToken: string,
) {
this.label = label

this.sora = Sora.connection(signalingUrl, this.debug)
this.channelId = `${channelIdPrefix}sendrecv${channelIdSuffix}`
this.metadata = { access_token: accessToken }
this.options = {}

this.connection = this.sora.sendrecv(this.channelId, this.metadata, this.options)

this.connection.on('notify', this.onnotify.bind(this))
this.connection.on('track', this.ontrack.bind(this))
this.connection.on('removetrack', this.onremovetrack.bind(this))
}

async connect(stream: MediaStream) {
await this.connection.connect(stream)
const localVideo = document.querySelector<HTMLVideoElement>(`#${this.label}-local-video`)
if (localVideo) {
localVideo.srcObject = stream
}
}

async disconnect() {
await this.connection.disconnect()

// お掃除
const localVideo = document.querySelector<HTMLVideoElement>(`#${this.label}-local-video`)
if (localVideo) {
localVideo.srcObject = null
}
// お掃除
const remoteVideos = document.querySelector(`#${this.label}-remote-videos`)
if (remoteVideos) {
remoteVideos.innerHTML = ''
}
}

private onnotify(event: SignalingNotifyMessage): void {
if (
event.event_type === 'connection.created' &&
this.connection.connectionId === event.connection_id
) {
const connectionIdElement = document.querySelector(`#${this.label}-connection-id`)
if (connectionIdElement) {
connectionIdElement.textContent = event.connection_id
}
}
}

private ontrack(event: RTCTrackEvent): void {
const stream = event.streams[0]
const remoteVideoId = `${this.label}-remotevideo-${stream.id}`
const remoteVideos = document.querySelector(`#${this.label}-remote-videos`)
if (remoteVideos && !remoteVideos.querySelector(`#${remoteVideoId}`)) {
const remoteVideo = document.createElement('video')
remoteVideo.id = remoteVideoId
remoteVideo.style.border = '1px solid red'
remoteVideo.autoplay = true
remoteVideo.playsInline = true
remoteVideo.controls = true
remoteVideo.width = 160
remoteVideo.height = 120
remoteVideo.srcObject = stream
remoteVideos.appendChild(remoteVideo)
}
}

private onremovetrack(event: MediaStreamTrackEvent): void {
const target = event.target as MediaStream
const remoteVideo = document.querySelector(`#${this.label}-remotevideo-${target.id}`)
if (remoteVideo) {
document.querySelector(`#${this.label}-remote-videos`)?.removeChild(remoteVideo)
}
}
}
8 changes: 4 additions & 4 deletions tests/sendrecv.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { test } from '@playwright/test'
test('sendrecv x2', async ({ page }) => {
await page.goto('http://localhost:9000/sendrecv/')

await page.click('#start-sendrecv1')
await page.click('#start-sendrecv2')
await page.click('#sendrecv1-start')
await page.click('#sendrecv2-start')

// #sendrecv1-connection-id 要素が存在し、その内容が空でないことを確認するまで待つ
await page.waitForSelector('#sendrecv1-connection-id:not(:empty)')
Expand All @@ -20,6 +20,6 @@ test('sendrecv x2', async ({ page }) => {
const sendrecv2ConnectionId = await page.$eval('#sendrecv2-connection-id', (el) => el.textContent)
console.log(`sendrecv2 connectionId=${sendrecv2ConnectionId}`)

await page.click('#stop-sendrecv1')
await page.click('#stop-sendrecv2')
await page.click('#sendrecv1-stop')
await page.click('#sendrecv2-stop')
})

0 comments on commit a21fb76

Please sign in to comment.