From e9500e5b1b62eb2271a6030365459492686407f0 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Fri, 27 Dec 2024 13:06:41 -0800 Subject: [PATCH 1/5] add close method to AudioSource and VideoSource ensures we can clean up allocated resources correctly --- examples/publish-wav/index.ts | 4 ++++ packages/livekit-rtc/src/audio_source.ts | 4 ++++ packages/livekit-rtc/src/video_source.ts | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/examples/publish-wav/index.ts b/examples/publish-wav/index.ts index 56722969..df538d2a 100644 --- a/examples/publish-wav/index.ts +++ b/examples/publish-wav/index.ts @@ -63,6 +63,10 @@ while (written < dataSize) { written += frameSize; } await source.waitForPlayout(); +// release resources allocated for audio publishing +source.close(); await room.disconnect(); + +// disposes all resources, only use if no more sessions are expected await dispose(); diff --git a/packages/livekit-rtc/src/audio_source.ts b/packages/livekit-rtc/src/audio_source.ts index 4975d8e4..8ae3bb36 100644 --- a/packages/livekit-rtc/src/audio_source.ts +++ b/packages/livekit-rtc/src/audio_source.ts @@ -134,4 +134,8 @@ export class AudioSource { throw new Error(cb.error); } } + + close() { + this.ffiHandle.dispose(); + } } diff --git a/packages/livekit-rtc/src/video_source.ts b/packages/livekit-rtc/src/video_source.ts index 9ac4170d..4290d14f 100644 --- a/packages/livekit-rtc/src/video_source.ts +++ b/packages/livekit-rtc/src/video_source.ts @@ -64,4 +64,8 @@ export class VideoSource { message: { case: 'captureVideoFrame', value: req }, }); } + + close() { + this.ffiHandle.dispose(); + } } From 2d0e41050269441b4364c993686154f7b08d9673 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Fri, 27 Dec 2024 13:13:54 -0800 Subject: [PATCH 2/5] changeset --- .changeset/slow-hounds-fail.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/slow-hounds-fail.md diff --git a/.changeset/slow-hounds-fail.md b/.changeset/slow-hounds-fail.md new file mode 100644 index 00000000..5bc8cebc --- /dev/null +++ b/.changeset/slow-hounds-fail.md @@ -0,0 +1,5 @@ +--- +'@livekit/rtc-node': patch +--- + +add close method to AudioSource and VideoSource From 52b5ebf5db03337eafcf34e9a137dfb89f5461b0 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Sat, 28 Dec 2024 19:02:42 -0700 Subject: [PATCH 3/5] async close methods for future-proof --- packages/livekit-rtc/src/audio_source.ts | 2 +- packages/livekit-rtc/src/video_source.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/livekit-rtc/src/audio_source.ts b/packages/livekit-rtc/src/audio_source.ts index 8ae3bb36..a1d476c3 100644 --- a/packages/livekit-rtc/src/audio_source.ts +++ b/packages/livekit-rtc/src/audio_source.ts @@ -135,7 +135,7 @@ export class AudioSource { } } - close() { + async close() { this.ffiHandle.dispose(); } } diff --git a/packages/livekit-rtc/src/video_source.ts b/packages/livekit-rtc/src/video_source.ts index 4290d14f..ffffc685 100644 --- a/packages/livekit-rtc/src/video_source.ts +++ b/packages/livekit-rtc/src/video_source.ts @@ -65,7 +65,7 @@ export class VideoSource { }); } - close() { + async close() { this.ffiHandle.dispose(); } } From 4ebed99b5439c06c31f345b259300207f8b468c4 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Sat, 28 Dec 2024 19:12:03 -0700 Subject: [PATCH 4/5] consistent protocol version --- examples/agent-dispatch/index.ts | 2 +- examples/agent-dispatch/package.json | 2 +- examples/publish-wav/index.ts | 2 +- packages/livekit-server-sdk/package.json | 2 +- pnpm-lock.yaml | 43 ++++++++++-------------- 5 files changed, 22 insertions(+), 29 deletions(-) diff --git a/examples/agent-dispatch/index.ts b/examples/agent-dispatch/index.ts index 93998aeb..4f403c24 100644 --- a/examples/agent-dispatch/index.ts +++ b/examples/agent-dispatch/index.ts @@ -21,7 +21,7 @@ async function createExplicitDispatch() { }); console.log('created dispatch', dispatch); - const dispatches = await agentDispatchClient.listDispatches(roomName); + const dispatches = await agentDispatchClient.listDispatch(roomName); console.log(`there are ${dispatches.length} dispatches in ${roomName}`); } diff --git a/examples/agent-dispatch/package.json b/examples/agent-dispatch/package.json index 3d187c5b..4371e8ad 100644 --- a/examples/agent-dispatch/package.json +++ b/examples/agent-dispatch/package.json @@ -14,7 +14,7 @@ "dependencies": { "dotenv": "^16.4.5", "livekit-server-sdk": "workspace:*", - "@livekit/protocol": "^1.28.0" + "@livekit/protocol": "^1.30.0" }, "devDependencies": { "@types/node": "^20.10.4", diff --git a/examples/publish-wav/index.ts b/examples/publish-wav/index.ts index df538d2a..8c57dc5a 100644 --- a/examples/publish-wav/index.ts +++ b/examples/publish-wav/index.ts @@ -64,7 +64,7 @@ while (written < dataSize) { } await source.waitForPlayout(); // release resources allocated for audio publishing -source.close(); +await source.close(); await room.disconnect(); diff --git a/packages/livekit-server-sdk/package.json b/packages/livekit-server-sdk/package.json index ee4ecf6d..dfdd9bb0 100644 --- a/packages/livekit-server-sdk/package.json +++ b/packages/livekit-server-sdk/package.json @@ -42,7 +42,7 @@ "test:edge": "vitest --environment edge-runtime run" }, "dependencies": { - "@livekit/protocol": "^1.29.1", + "@livekit/protocol": "^1.30.0", "camelcase-keys": "^9.0.0", "jose": "^5.1.2" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3459c017..4c2e34d6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -43,7 +43,7 @@ importers: version: 2.1.3(eslint@8.57.1) eslint-plugin-import: specifier: ^2.29.1 - version: 2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) + version: 2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) eslint-plugin-n: specifier: ^17.9.0 version: 17.10.3(eslint@8.57.1) @@ -75,8 +75,8 @@ importers: examples/agent-dispatch: dependencies: '@livekit/protocol': - specifier: ^1.28.0 - version: 1.28.0 + specifier: ^1.30.0 + version: 1.30.0 dotenv: specifier: ^16.4.5 version: 16.4.5 @@ -242,8 +242,8 @@ importers: packages/livekit-server-sdk: dependencies: '@livekit/protocol': - specifier: ^1.29.1 - version: 1.29.1 + specifier: ^1.30.0 + version: 1.30.0 camelcase-keys: specifier: ^9.0.0 version: 9.1.3 @@ -928,11 +928,8 @@ packages: '@livekit/mutex@1.1.0': resolution: {integrity: sha512-XRLG+z/0uoyDioupjUiskjI06Y51U/IXVPJn7qJ+R3J75XX01irYVBM9MpxeJahpVoe9QhU4moIEolX+HO9U9g==} - '@livekit/protocol@1.28.0': - resolution: {integrity: sha512-j7ifbZ1TVfrLDQEuyl4M5rOAS8mRNhpgGoSKE4z03gc012hUHThx227bD1M1BfFPTqNFHzpaGCu/HYE/l09dHw==} - - '@livekit/protocol@1.29.1': - resolution: {integrity: sha512-OhxXTZlyM5f4ydnAq1p5azzzOtKWmIoCSVtyVj9rgE42zQI5JM1rR9pubVRZovouGSvEDSJx9yL4Js2IlIyM1Q==} + '@livekit/protocol@1.30.0': + resolution: {integrity: sha512-SDI9ShVKj8N3oOSinr8inaxD3FXgmgoJlqN35uU/Yx1sdoDeQbzAuBFox7bYjM+VhnZ1V22ivIDjAsKr00H+XQ==} '@livekit/typed-emitter@3.0.0': resolution: {integrity: sha512-9bl0k4MgBPZu3Qu3R3xy12rmbW17e3bE9yf4YY85gJIQ3ezLEj/uzpKHWBsLaDoL5Mozz8QCgggwIBudYQWeQg==} @@ -3963,11 +3960,7 @@ snapshots: '@livekit/mutex@1.1.0': {} - '@livekit/protocol@1.28.0': - dependencies: - '@bufbuild/protobuf': 1.10.0 - - '@livekit/protocol@1.29.1': + '@livekit/protocol@1.30.0': dependencies: '@bufbuild/protobuf': 1.10.0 @@ -4971,8 +4964,8 @@ snapshots: '@typescript-eslint/parser': 8.8.1(eslint@8.57.1)(typescript@5.6.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1))(eslint@8.57.1) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) eslint-plugin-jsx-a11y: 6.10.0(eslint@8.57.1) eslint-plugin-react: 7.37.1(eslint@8.57.1) eslint-plugin-react-hooks: 4.6.2(eslint@8.57.1) @@ -4990,7 +4983,7 @@ snapshots: eslint-config-standard@17.1.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1))(eslint-plugin-n@17.10.3(eslint@8.57.1))(eslint-plugin-promise@7.1.0(eslint@8.57.1))(eslint@8.57.1): dependencies: eslint: 8.57.1 - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) eslint-plugin-n: 17.10.3(eslint@8.57.1) eslint-plugin-promise: 7.1.0(eslint@8.57.1) @@ -5007,33 +5000,33 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1): + eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1))(eslint@8.57.1): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.3.7 enhanced-resolve: 5.17.1 eslint: 8.57.1 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) fast-glob: 3.3.2 get-tsconfig: 4.8.1 is-bun-module: 1.2.1 is-glob: 4.0.3 optionalDependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) transitivePeerDependencies: - '@typescript-eslint/parser' - eslint-import-resolver-node - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.8.1(eslint@8.57.1)(typescript@5.6.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1) + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1))(eslint@8.57.1) transitivePeerDependencies: - supports-color @@ -5044,7 +5037,7 @@ snapshots: eslint: 8.57.1 eslint-compat-utils: 0.5.1(eslint@8.57.1) - eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -5055,7 +5048,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.8.1(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 From 962ee1313c2a95b060d82f4613409ab293a44695 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Sat, 28 Dec 2024 19:17:31 -0700 Subject: [PATCH 5/5] fix receive-audio example --- examples/receive-audio/index.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/receive-audio/index.ts b/examples/receive-audio/index.ts index 07dbf2c5..4ddf4b0d 100644 --- a/examples/receive-audio/index.ts +++ b/examples/receive-audio/index.ts @@ -77,13 +77,13 @@ const room = new Room(); let trackToProcess: string | null = null; let writer: fs.WriteStream | null = null; -room.on(RoomEvent.TrackSubscribed, (track, publication, participant) => { +room.on(RoomEvent.TrackSubscribed, async (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) => { + for await (const frame of stream) { if (!trackToProcess) { return; } @@ -92,14 +92,14 @@ room.on(RoomEvent.TrackSubscribed, (track, publication, participant) => { // create file on first frame // also guard when track is unsubscribed writer = fs.createWriteStream('output.wav'); - writeWavHeader(writer, ev.frame); + writeWavHeader(writer, frame); } if (writer) { - const buf = Buffer.from(ev.frame.data.buffer); + const buf = Buffer.from(frame.data.buffer); writer.write(buf); } - }); + } } });