Skip to content

Commit

Permalink
examples の class 化 (#496)
Browse files Browse the repository at this point in the history
* examples の class 化

* sendrecv を class 化する

* id を remote-video にする

* 大文字

* examples の simulcast を class 化

* コスメ

* examples spotlight sendrecv の class 化

* channel_id の修正

* examples の spotlight sendonly / recvonly を class 化

* messaging を class に置き換える

* github actions pnpm v3 に上げる

* サンプルをclassベースに変更し、.env.templateを追加

* 送信まで

* チェックまで実装してみる

* page2 からもメッセージを送ってみる

* waitForFunction 使ってみる

* チェック以外を行う

* skip にする

* e2ee も class 化する
  • Loading branch information
voluntas authored Mar 1, 2024
1 parent f74af95 commit 796c554
Show file tree
Hide file tree
Showing 36 changed files with 1,318 additions and 747 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- uses: pnpm/action-setup@v2
- uses: pnpm/action-setup@v3
with:
version: 8
- run: pnpm --version
Expand Down
9 changes: 4 additions & 5 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,6 @@
- [CHANGE] stopAudioTrack と stopVideoTrack を非推奨にする
- 代わりに名前を変えただけの removeAudioTrack と removeVideoTrack を用意する
- @voluntas

## 2023.2.1

**テストとサンプルのみの変更であり、SDK の変更はありません**

- [CHANGE] examples を Vite を利用して動かすように変更する
- serve を削除
- Vite を追加
Expand All @@ -27,6 +22,10 @@
- [CHANGE] deploy-pages.yml を削除する
- E2E テストで実行できるようになったので
- @voluntas
- [CHANGE] サンプルを class ベースに変更する
- @voluntas
- [ADD] サンプル用の .env.template を用意する
- @voluntas
- [ADD] tests に Playwright を利用した E2E テストを追加する
- e2ee と messaging は一旦 skip で追加
- @voluntas
Expand Down
10 changes: 5 additions & 5 deletions examples/e2ee/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,20 @@ <h1>E2EE test</h1>
<div style="display: flex;">
<div>
<h2>local</h2>
<button id="start-sendrecv">start</button>
<button id="stop-sendrecv">stop</button><br />
<button id="start">start</button>
<button id="stop">stop</button><br />
<div id="local-connection-id"></div>
<div id="local-fingerprint"></div>
<video id="sendrecv-local-video" autoplay="" playsinline="" controls=""
<video id="local-video" autoplay="" playsinline="" controls=""
style="width: 320px; height: 240px; border: 1px solid black;"></video>

<h2>remote</h2>
<div id="sendrecv-remote-videos"></div>
<div id="remote-videos"></div>
</div>
</div>
</div>

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

</html>
88 changes: 0 additions & 88 deletions examples/e2ee/main.mjs

This file was deleted.

167 changes: 167 additions & 0 deletions examples/e2ee/main.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
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 || ''

await Sora.initE2EE('https://sora-e2ee-wasm.shiguredo.app/2020.2/wasm.wasm').catch((e) => {
const errorMessageElement = document.querySelector('#error-message')
if (errorMessageElement) {
errorMessageElement.textContent = 'E2EE用 wasm ファイルの読み込みに失敗しました'
}
})

const client = new SoraClient(
SORA_SIGNALING_URL,
SORA_CHANNEL_ID_PREFIX,
SORA_CHANNEL_ID_SUFFIX,
ACCESS_TOKEN,
)

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

class SoraClient {
private debug = false

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

private sora: SoraConnection
private connection: ConnectionPublisher

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

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>('#local-video')
if (localVideo) {
localVideo.srcObject = stream
}
}

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

// お掃除
const localVideo = document.querySelector<HTMLVideoElement>('#local-video')
if (localVideo) {
localVideo.srcObject = null
}

const localConnectionId = document.querySelector<HTMLDivElement>('#local-connection-id')
if (localConnectionId) {
localConnectionId.textContent = ''
}

const remoteVideos = document.querySelector<HTMLDivElement>('#remote-videos')
if (remoteVideos) {
remoteVideos.innerHTML = ''
}
}

private onnotify(event: SignalingNotifyMessage): void {
if (
event.event_type === 'connection.created' &&
event.connection_id === this.connection.connectionId
) {
const localConnectionId = document.querySelector<HTMLDivElement>('#local-connection-id')
if (localConnectionId) {
localConnectionId.textContent = this.connection.connectionId
}

const localFingerprint = document.querySelector<HTMLDivElement>('#local-fingerprint')
if (localFingerprint) {
localFingerprint.textContent = this.connection.e2eeSelfFingerprint || null
}
}

if (event.event_type === 'connection.created') {
const remoteFingerprints = this.connection.e2eeRemoteFingerprints || {}
Object.keys(remoteFingerprints).filter((connectionId) => {
const fingerprintElement = document.querySelector(
`#remote-video-box-${connectionId}-fingerprint`,
)
if (fingerprintElement) {
fingerprintElement.textContent = `fingerprint: ${remoteFingerprints[connectionId]}`
}
})
}
}

private ontrack(event: RTCTrackEvent): void {
const stream = event.streams[0]
/*
<div id="remote-video-box-${stream.id}">
<div id="remote-video-box-${stream.id}-connection-id">connectionId: ${stream.id}
<div id="remote-video-box-${stream.id}-fingerprint">fingerprint: ${stream.id}
<video id="remote-video-${stream.id}" style="border: 1px solid red;" autoplay playsinline controls srcObject="${stream}"></video>
</div>
*/

const remoteVideoBoxId = `remote-video-box-${stream.id}`
const remoteVideos = document.querySelector<HTMLDivElement>('#remote-videos')
if (remoteVideos && !remoteVideos.querySelector(`#${remoteVideoBoxId}`)) {
// <div id="remote-video-box-${stream.id}"> を作る
const remoteVideoBox = document.createElement('div')
remoteVideoBox.id = remoteVideoBoxId
// <div id="remote-video-box-${stream.id}-connection-id"> を作る
const connectionIdElement = document.createElement('div')
connectionIdElement.id = `${remoteVideoBoxId}-connection-id`
connectionIdElement.textContent = `connectionId: ${stream.id}`
remoteVideoBox.appendChild(connectionIdElement)
// <div id="remote-video-box-${stream.id}-fingerprint"> を作る
const fingerprintElement = document.createElement('div')
fingerprintElement.id = `${remoteVideoBoxId}-fingerprint`
remoteVideoBox.appendChild(fingerprintElement)
// <video id="remote-video-${stream.id}"> を作る
const remoteVideo = document.createElement('video')
remoteVideo.style.border = '1px solid red'
remoteVideo.autoplay = true
remoteVideo.playsInline = true
remoteVideo.controls = true
remoteVideo.srcObject = stream
remoteVideoBox.appendChild(remoteVideo)
remoteVideos.appendChild(remoteVideoBox)
}
}

private onremovetrack(event: MediaStreamTrackEvent): void {
const target = event.target as MediaStream
const remoteVideo = document.querySelector<HTMLVideoElement>(`#remote-video-${target.id}`)
if (remoteVideo) {
document.querySelector<HTMLDivElement>('#remote-videos')?.removeChild(remoteVideo)
}
}
}
6 changes: 3 additions & 3 deletions examples/messaging/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ <h1>DataChannel messaging test</h1>
<p>複数のブラウザで開いて sendMessage することで動作確認できます</p>
<div style="display: flex;">
<div>
<div id="local-connection-id"></div>
<div id="connection-id"></div>
<div style="display: flex;">
<input type="text" name="message" />
<button id="send-message" disabled>sendMessage</button><br />
</div>
<button id="start">start</button>
<button id="stop">stop</button><br />
<button id="stop" disabled>stop</button><br />
<div>
<h3>messages</h3>
<ul id="received-messages">
Expand All @@ -27,7 +27,7 @@ <h3>messages</h3>
</div>
</div>

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

</html>
53 changes: 0 additions & 53 deletions examples/messaging/main.mjs

This file was deleted.

Loading

0 comments on commit 796c554

Please sign in to comment.