From 5345ab9b757f4fc7954092af3b8c5b3af881dd59 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Sat, 24 Aug 2024 17:53:59 -0700 Subject: [PATCH] Add example for subscribe receive audio frames (#260) * Add example for subscribe receive audio frames * update package * update example steps * update package.json to use workspace dependency * going back to using releases * writing wav files * update pnpm-lock.yaml --------- Co-authored-by: lukasIO --- examples/publish-wav/.env.example | 2 +- examples/publish-wav/package.json | 7 +- examples/receive-audio/.env.example | 6 + examples/receive-audio/README.md | 10 + examples/receive-audio/index.ts | 125 ++++++++++ examples/receive-audio/package.json | 22 ++ pnpm-lock.yaml | 360 +++++++++++++++++++++++++++- 7 files changed, 524 insertions(+), 8 deletions(-) create mode 100644 examples/receive-audio/.env.example create mode 100644 examples/receive-audio/README.md create mode 100644 examples/receive-audio/index.ts create mode 100644 examples/receive-audio/package.json diff --git a/examples/publish-wav/.env.example b/examples/publish-wav/.env.example index 6ad57d5c..ed0adf1d 100644 --- a/examples/publish-wav/.env.example +++ b/examples/publish-wav/.env.example @@ -1,4 +1,4 @@ -# 1. Copy this file and rename it to .env.local +# 1. Copy this file and rename it to .env # 2. Update the enviroment variables below. LIVEKIT_API_KEY=devkey diff --git a/examples/publish-wav/package.json b/examples/publish-wav/package.json index 38141a94..8aacf7a4 100644 --- a/examples/publish-wav/package.json +++ b/examples/publish-wav/package.json @@ -12,11 +12,12 @@ "keywords": [], "license": "Apache-2.0", "dependencies": { - "@livekit/rtc-node": "workspace:*", + "@livekit/rtc-node": "^0.7.0", "dotenv": "^16.4.5", - "livekit-server-sdk": "workspace:*" + "livekit-server-sdk": "^2.6.1" }, "devDependencies": { - "@types/node": "^20.10.4" + "@types/node": "^20.10.4", + "tsx": "^4.7.1" } } diff --git a/examples/receive-audio/.env.example b/examples/receive-audio/.env.example new file mode 100644 index 00000000..0e56d427 --- /dev/null +++ b/examples/receive-audio/.env.example @@ -0,0 +1,6 @@ +# 1. Copy this file and rename it to .env +# 2. Update the enviroment variables below. + +LIVEKIT_API_KEY=mykey +LIVEKIT_API_SECRET=mysecret +LIVEKIT_URL=wss://myproject.livekit.cloud diff --git a/examples/receive-audio/README.md b/examples/receive-audio/README.md new file mode 100644 index 00000000..ac31174f --- /dev/null +++ b/examples/receive-audio/README.md @@ -0,0 +1,10 @@ +# Receive audio example + +This example demonstrates receiving the first audio track published in a room and writing that audio data to a wav file. + +To run the example: + +- Copy .env.example to .env and fill in the values +- Run `pnpm install` in the root folder of this repo +- Run `tsx index.ts` in this folder +- From another client, join the room `test-room` and publish an audio track diff --git a/examples/receive-audio/index.ts b/examples/receive-audio/index.ts new file mode 100644 index 00000000..07dbf2c5 --- /dev/null +++ b/examples/receive-audio/index.ts @@ -0,0 +1,125 @@ +import { AudioStream, Room, RoomEvent, TrackKind } from '@livekit/rtc-node'; +import type { AudioFrame } from '@livekit/rtc-node/src'; +import { Buffer } from 'buffer'; +import { config } from 'dotenv'; +import * as fs from 'fs'; +import { AccessToken } from 'livekit-server-sdk'; + +config(); + +// Constants for WAV file +const BITS_PER_SAMPLE = 16; +const WAV_FILE = 'output.wav'; + +function writeWavHeader(writer: fs.WriteStream, frame: AudioFrame) { + const header = Buffer.alloc(44); + const byteRate = (frame.sampleRate * frame.channels * BITS_PER_SAMPLE) / 8; + const blockAlign = (frame.channels * BITS_PER_SAMPLE) / 8; + + writer = fs.createWriteStream(WAV_FILE); + // Write the RIFF header + header.write('RIFF', 0); // ChunkID + header.writeUInt32LE(0, 4); // ChunkSize placeholder + header.write('WAVE', 8); // Format + + // Write the fmt subchunk + header.write('fmt ', 12); // Subchunk1ID + header.writeUInt32LE(16, 16); // Subchunk1Size (PCM) + header.writeUInt16LE(1, 20); // AudioFormat (PCM = 1) + header.writeUInt16LE(frame.channels, 22); // NumChannels + header.writeUInt32LE(frame.sampleRate, 24); // SampleRate + header.writeUInt32LE(byteRate, 28); // ByteRate + header.writeUInt16LE(blockAlign, 32); // BlockAlign + header.writeUInt16LE(16, 34); // BitsPerSample + + // Write the data subchunk + header.write('data', 36); // Subchunk2ID + header.writeUInt32LE(0, 40); // Subchunk2Size placeholder + + // Write the header to the stream + writer.write(header); +} + +function updateWavHeader(path: string) { + // Update the size of the audio data in the header + const stats = fs.statSync(path); + const fileSize = stats.size; + + const chunkSize = fileSize - 8; + const subchunk2Size = fileSize - 44; + const header = Buffer.alloc(8); + header.writeUInt32LE(chunkSize, 0); + header.writeUInt32LE(subchunk2Size, 4); + + // Reopen the file for updating the header + const fd = fs.openSync(path, 'r+'); + fs.writeSync(fd, header, 0, 4, 4); // Update ChunkSize + fs.writeSync(fd, header, 4, 4, 40); // Update Subchunk2Size + fs.closeSync(fd); +} + +// create access token from API credentials +const token = new AccessToken(process.env.LIVEKIT_API_KEY, process.env.LIVEKIT_API_SECRET, { + identity: 'example-participant', +}); +token.addGrant({ + room: 'test-room', + roomJoin: true, + roomCreate: true, + canPublish: true, + canPublishData: true, +}); +const jwt = await token.toJwt(); + +// set up room +const room = new Room(); + +let trackToProcess: string | null = null; +let writer: fs.WriteStream | null = null; + +room.on(RoomEvent.TrackSubscribed, (track, publication, participant) => { + console.log('subscribed to track', track.sid, publication, participant.identity); + if (track.kind === TrackKind.KIND_AUDIO) { + const stream = new AudioStream(track); + trackToProcess = track.sid; + + stream.on('frameReceived', (ev) => { + if (!trackToProcess) { + return; + } + + if (writer == null) { + // create file on first frame + // also guard when track is unsubscribed + writer = fs.createWriteStream('output.wav'); + writeWavHeader(writer, ev.frame); + } + + if (writer) { + const buf = Buffer.from(ev.frame.data.buffer); + writer.write(buf); + } + }); + } +}); + +const finishedPromise = new Promise((resolve) => { + room.on(RoomEvent.TrackUnsubscribed, (_, publication, participant) => { + console.log('unsubscribed from track', publication.sid, participant.identity); + if (publication.sid === trackToProcess) { + trackToProcess = null; + if (writer) { + writer.close(); + // update header + updateWavHeader(WAV_FILE); + } + resolve(); + } + }); +}); + +await room.connect(process.env.LIVEKIT_URL, jwt, { autoSubscribe: true, dynacast: true }); +console.log('connected to room', room); + +// stay in the room until publisher leaves +await finishedPromise; diff --git a/examples/receive-audio/package.json b/examples/receive-audio/package.json new file mode 100644 index 00000000..c925ee1d --- /dev/null +++ b/examples/receive-audio/package.json @@ -0,0 +1,22 @@ +{ + "name": "example-receive-audio", + "author": "LiveKit", + "private": "true", + "description": "", + "type": "module", + "main": "index.ts", + "scripts": { + "lint": "eslint -f unix \"**/*.ts\"" + }, + "keywords": [], + "license": "Apache-2.0", + "dependencies": { + "@livekit/rtc-node": "^0.7.0", + "dotenv": "^16.4.5", + "livekit-server-sdk": "^2.6.1" + }, + "devDependencies": { + "@types/node": "^20.10.4", + "tsx": "^4.7.1" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f7c021bb..18cc4f69 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -75,18 +75,40 @@ importers: examples/publish-wav: dependencies: '@livekit/rtc-node': - specifier: workspace:* - version: link:../../packages/livekit-rtc + specifier: ^0.7.0 + version: 0.7.0 dotenv: specifier: ^16.4.5 version: 16.4.5 livekit-server-sdk: - specifier: workspace:* - version: link:../../packages/livekit-server-sdk + specifier: ^2.6.1 + version: 2.6.1 + devDependencies: + '@types/node': + specifier: ^20.10.4 + version: 20.14.9 + tsx: + specifier: ^4.7.1 + version: 4.17.0 + + examples/receive-audio: + dependencies: + '@livekit/rtc-node': + specifier: ^0.7.0 + version: 0.7.0 + dotenv: + specifier: ^16.4.5 + version: 16.4.5 + livekit-server-sdk: + specifier: ^2.6.1 + version: 2.6.1 devDependencies: '@types/node': specifier: ^20.10.4 version: 20.14.9 + tsx: + specifier: ^4.7.1 + version: 4.17.0 examples/webhooks-http: dependencies: @@ -365,138 +387,282 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.23.1': + resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.21.5': resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} engines: {node: '>=12'} cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.23.1': + resolution: {integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.21.5': resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} engines: {node: '>=12'} cpu: [arm] os: [android] + '@esbuild/android-arm@0.23.1': + resolution: {integrity: sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.21.5': resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} engines: {node: '>=12'} cpu: [x64] os: [android] + '@esbuild/android-x64@0.23.1': + resolution: {integrity: sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.21.5': resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.23.1': + resolution: {integrity: sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.21.5': resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} engines: {node: '>=12'} cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.23.1': + resolution: {integrity: sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.21.5': resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.23.1': + resolution: {integrity: sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.21.5': resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.23.1': + resolution: {integrity: sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.21.5': resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} engines: {node: '>=12'} cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.23.1': + resolution: {integrity: sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.21.5': resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} engines: {node: '>=12'} cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.23.1': + resolution: {integrity: sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.21.5': resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} engines: {node: '>=12'} cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.23.1': + resolution: {integrity: sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.21.5': resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} engines: {node: '>=12'} cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.23.1': + resolution: {integrity: sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.21.5': resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.23.1': + resolution: {integrity: sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.21.5': resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.23.1': + resolution: {integrity: sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.21.5': resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.23.1': + resolution: {integrity: sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.21.5': resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} engines: {node: '>=12'} cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.23.1': + resolution: {integrity: sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.21.5': resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} engines: {node: '>=12'} cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.23.1': + resolution: {integrity: sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/netbsd-x64@0.21.5': resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.23.1': + resolution: {integrity: sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.23.1': + resolution: {integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.21.5': resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.23.1': + resolution: {integrity: sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/sunos-x64@0.21.5': resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} engines: {node: '>=12'} cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.23.1': + resolution: {integrity: sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.21.5': resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} engines: {node: '>=12'} cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.23.1': + resolution: {integrity: sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.21.5': resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} engines: {node: '>=12'} cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.23.1': + resolution: {integrity: sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.21.5': resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} engines: {node: '>=12'} cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.23.1': + resolution: {integrity: sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@eslint-community/eslint-utils@4.4.0': resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -564,6 +730,40 @@ packages: '@livekit/protocol@1.20.0': resolution: {integrity: sha512-2RJQwzBa+MfUoy0zBWuyj8S2MTBxeTgREeG0r/1bNmkAFiBhsdgr87gIvblyqJxffUxJpALMu1Ee0M1XHX+9Ug==} + '@livekit/rtc-node-darwin-arm64@0.7.0': + resolution: {integrity: sha512-74R3POrGWZxRiHHCUhboI/mGCctzDjNS9uucbr+GgfFLAviAXs0ltC19Y08lWiFx1YBMF/mV2pLNF/fj+/Opaw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@livekit/rtc-node-darwin-x64@0.7.0': + resolution: {integrity: sha512-tj3TymM4aBCWaaJHasQXKJZvIjYmTQ34hg1vBlY+fBrx9F10JBAhYZeWpx/tf37p41R6wSnnDrWXW9RnQJivbA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@livekit/rtc-node-linux-arm64-gnu@0.7.0': + resolution: {integrity: sha512-PAuaWujIY623lTfVbRFd+tPPOZfzIIseVJDs1IOivUM00uGqlC1SHbbrONp5vR+gSez1TDLyN8MyVy2FopuZRA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@livekit/rtc-node-linux-x64-gnu@0.7.0': + resolution: {integrity: sha512-056F2dUJJvzR/s5hPCcSe4pUTx0OX3WPg1qHkB575fjSSY05TcKNeNwVWRMs76EBkwiodKtmccLYLKFJ6rQ7Dw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@livekit/rtc-node-win32-x64-msvc@0.7.0': + resolution: {integrity: sha512-vUP/LUTnxHyg3z2Qgc1+YnfuAa+VLqCouWMkgoew5SBSu1+npCn93Q06SSU2Dov3/uw9i5XjHOq9XJjffVWgIQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@livekit/rtc-node@0.7.0': + resolution: {integrity: sha512-ITRv6CCfjGC/K7aI3AZnNBD3eQnHPguL0q8SmH52quebwNn1BYW+IZAzoIa4VCNnOlrfCdrGT1DCmZQz61nn0w==} + engines: {node: '>= 18'} + '@manypkg/find-root@1.1.0': resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} @@ -1329,6 +1529,11 @@ packages: engines: {node: '>=12'} hasBin: true + esbuild@0.23.1: + resolution: {integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==} + engines: {node: '>=18'} + hasBin: true + escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} @@ -1950,6 +2155,10 @@ packages: linkify-it@5.0.0: resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} + livekit-server-sdk@2.6.1: + resolution: {integrity: sha512-j/8TOlahIyWnycNkuSzTv6q+win4JTbDGNH48iMsZDMnJBks9hhC9UwAO4ES42sAorIAxGkrH58hxt4KdTkZaQ==} + engines: {node: '>=19'} + load-yaml-file@0.2.0: resolution: {integrity: sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==} engines: {node: '>=6'} @@ -2588,6 +2797,11 @@ packages: tslib@2.6.3: resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} + tsx@4.17.0: + resolution: {integrity: sha512-eN4mnDA5UMKDt4YZixo9tBioibaMBpoxBkD+rIPAjVmYERSG0/dWEY1CEFuV89CgASlKL499q8AhmkMnnjtOJg==} + engines: {node: '>=18.0.0'} + hasBin: true + turbo-darwin-64@2.0.6: resolution: {integrity: sha512-XpgBwWj3Ggmz/gQVqXdMKXHC1iFPMDiuwugLwSzE7Ih0O13JuNtYZKhQnopvbDQnFQCeRq2Vsm5OTWabg/oB/g==} cpu: [x64] @@ -3094,72 +3308,144 @@ snapshots: '@esbuild/aix-ppc64@0.21.5': optional: true + '@esbuild/aix-ppc64@0.23.1': + optional: true + '@esbuild/android-arm64@0.21.5': optional: true + '@esbuild/android-arm64@0.23.1': + optional: true + '@esbuild/android-arm@0.21.5': optional: true + '@esbuild/android-arm@0.23.1': + optional: true + '@esbuild/android-x64@0.21.5': optional: true + '@esbuild/android-x64@0.23.1': + optional: true + '@esbuild/darwin-arm64@0.21.5': optional: true + '@esbuild/darwin-arm64@0.23.1': + optional: true + '@esbuild/darwin-x64@0.21.5': optional: true + '@esbuild/darwin-x64@0.23.1': + optional: true + '@esbuild/freebsd-arm64@0.21.5': optional: true + '@esbuild/freebsd-arm64@0.23.1': + optional: true + '@esbuild/freebsd-x64@0.21.5': optional: true + '@esbuild/freebsd-x64@0.23.1': + optional: true + '@esbuild/linux-arm64@0.21.5': optional: true + '@esbuild/linux-arm64@0.23.1': + optional: true + '@esbuild/linux-arm@0.21.5': optional: true + '@esbuild/linux-arm@0.23.1': + optional: true + '@esbuild/linux-ia32@0.21.5': optional: true + '@esbuild/linux-ia32@0.23.1': + optional: true + '@esbuild/linux-loong64@0.21.5': optional: true + '@esbuild/linux-loong64@0.23.1': + optional: true + '@esbuild/linux-mips64el@0.21.5': optional: true + '@esbuild/linux-mips64el@0.23.1': + optional: true + '@esbuild/linux-ppc64@0.21.5': optional: true + '@esbuild/linux-ppc64@0.23.1': + optional: true + '@esbuild/linux-riscv64@0.21.5': optional: true + '@esbuild/linux-riscv64@0.23.1': + optional: true + '@esbuild/linux-s390x@0.21.5': optional: true + '@esbuild/linux-s390x@0.23.1': + optional: true + '@esbuild/linux-x64@0.21.5': optional: true + '@esbuild/linux-x64@0.23.1': + optional: true + '@esbuild/netbsd-x64@0.21.5': optional: true + '@esbuild/netbsd-x64@0.23.1': + optional: true + + '@esbuild/openbsd-arm64@0.23.1': + optional: true + '@esbuild/openbsd-x64@0.21.5': optional: true + '@esbuild/openbsd-x64@0.23.1': + optional: true + '@esbuild/sunos-x64@0.21.5': optional: true + '@esbuild/sunos-x64@0.23.1': + optional: true + '@esbuild/win32-arm64@0.21.5': optional: true + '@esbuild/win32-arm64@0.23.1': + optional: true + '@esbuild/win32-ia32@0.21.5': optional: true + '@esbuild/win32-ia32@0.23.1': + optional: true + '@esbuild/win32-x64@0.21.5': optional: true + '@esbuild/win32-x64@0.23.1': + optional: true + '@eslint-community/eslint-utils@4.4.0(eslint@8.57.0)': dependencies: eslint: 8.57.0 @@ -3239,6 +3525,32 @@ snapshots: dependencies: '@bufbuild/protobuf': 1.10.0 + '@livekit/rtc-node-darwin-arm64@0.7.0': + optional: true + + '@livekit/rtc-node-darwin-x64@0.7.0': + optional: true + + '@livekit/rtc-node-linux-arm64-gnu@0.7.0': + optional: true + + '@livekit/rtc-node-linux-x64-gnu@0.7.0': + optional: true + + '@livekit/rtc-node-win32-x64-msvc@0.7.0': + optional: true + + '@livekit/rtc-node@0.7.0': + dependencies: + '@bufbuild/protobuf': 1.10.0 + typed-emitter: 2.1.0 + optionalDependencies: + '@livekit/rtc-node-darwin-arm64': 0.7.0 + '@livekit/rtc-node-darwin-x64': 0.7.0 + '@livekit/rtc-node-linux-arm64-gnu': 0.7.0 + '@livekit/rtc-node-linux-x64-gnu': 0.7.0 + '@livekit/rtc-node-win32-x64-msvc': 0.7.0 + '@manypkg/find-root@1.1.0': dependencies: '@babel/runtime': 7.24.7 @@ -4101,6 +4413,33 @@ snapshots: '@esbuild/win32-ia32': 0.21.5 '@esbuild/win32-x64': 0.21.5 + esbuild@0.23.1: + optionalDependencies: + '@esbuild/aix-ppc64': 0.23.1 + '@esbuild/android-arm': 0.23.1 + '@esbuild/android-arm64': 0.23.1 + '@esbuild/android-x64': 0.23.1 + '@esbuild/darwin-arm64': 0.23.1 + '@esbuild/darwin-x64': 0.23.1 + '@esbuild/freebsd-arm64': 0.23.1 + '@esbuild/freebsd-x64': 0.23.1 + '@esbuild/linux-arm': 0.23.1 + '@esbuild/linux-arm64': 0.23.1 + '@esbuild/linux-ia32': 0.23.1 + '@esbuild/linux-loong64': 0.23.1 + '@esbuild/linux-mips64el': 0.23.1 + '@esbuild/linux-ppc64': 0.23.1 + '@esbuild/linux-riscv64': 0.23.1 + '@esbuild/linux-s390x': 0.23.1 + '@esbuild/linux-x64': 0.23.1 + '@esbuild/netbsd-x64': 0.23.1 + '@esbuild/openbsd-arm64': 0.23.1 + '@esbuild/openbsd-x64': 0.23.1 + '@esbuild/sunos-x64': 0.23.1 + '@esbuild/win32-arm64': 0.23.1 + '@esbuild/win32-ia32': 0.23.1 + '@esbuild/win32-x64': 0.23.1 + escape-string-regexp@1.0.5: {} escape-string-regexp@4.0.0: {} @@ -4844,6 +5183,12 @@ snapshots: dependencies: uc.micro: 2.1.0 + livekit-server-sdk@2.6.1: + dependencies: + '@livekit/protocol': 1.20.0 + camelcase-keys: 9.1.3 + jose: 5.4.0 + load-yaml-file@0.2.0: dependencies: graceful-fs: 4.2.11 @@ -5469,6 +5814,13 @@ snapshots: tslib@2.6.3: {} + tsx@4.17.0: + dependencies: + esbuild: 0.23.1 + get-tsconfig: 4.7.5 + optionalDependencies: + fsevents: 2.3.3 + turbo-darwin-64@2.0.6: optional: true