Summary
We're on @elevenlabs/react@1.15.1, which pulls in @elevenlabs/client@1.24.0.
Because we use strict CSP with no external CDNs allowed, we need to self-host one of the worklets (libsampleratePath, passed into conversation.startSession). Even with the override, we get CSP blocks on iOS, and after some digging we found that libsampleratePath is only applied to the audio input device but not the output device.
Is this intended or just an oversight?
Potential solution
In setupWebSocketIO in src/platform/web/VoiceSessionSetup.ts, libsampleratePath is passed to MediaDeviceInput.create but not MediaDeviceOutput.create, even though MediaDeviceOutput.create accepts it and runs addLibsamplerateModule when resampling is needed (which it seems to be on iOS):
const [input, output] = await Promise.all([
MediaDeviceInput.create({
...connection.inputFormat,
workletPaths: options.workletPaths,
libsampleratePath: options.libsampleratePath, // input gets it!!
}),
MediaDeviceOutput.create({
...connection.outputFormat,
workletPaths: options.workletPaths,
// libsampleratePath missing!!
audioContext: audioContext ?? undefined,
}),
]);
So addLibsamplerateModule(context, undefined) in output.js falls back to the jsdelivr URL regardless of what we pass.
We apply this patch as a workaround via pnpm for now:
diff --git a/dist/platform/web/VoiceSessionSetup.js b/dist/platform/web/VoiceSessionSetup.js
index 069794854e1dcc64391ec10cdfcbe4793420b769..aa3da678980fd0851bac2bb043c94d87d33add98 100644
--- a/dist/platform/web/VoiceSessionSetup.js
+++ b/dist/platform/web/VoiceSessionSetup.js
@@ -45,6 +45,7 @@ async function setupWebSocketIO(options, connection, audioContext) {
...connection.outputFormat,
outputDeviceId: options.outputDeviceId,
workletPaths: options.workletPaths,
+ libsampleratePath: options.libsampleratePath,
audioContext: audioContext ?? undefined,
}),
]);
Summary
We're on
@elevenlabs/react@1.15.1, which pulls in@elevenlabs/client@1.24.0.Because we use strict CSP with no external CDNs allowed, we need to self-host one of the worklets (
libsampleratePath, passed intoconversation.startSession). Even with the override, we get CSP blocks on iOS, and after some digging we found thatlibsampleratePathis only applied to the audio input device but not the output device.Is this intended or just an oversight?
Potential solution
In
setupWebSocketIOin src/platform/web/VoiceSessionSetup.ts,libsampleratePathis passed toMediaDeviceInput.createbut notMediaDeviceOutput.create, even thoughMediaDeviceOutput.createaccepts it and runsaddLibsamplerateModulewhen resampling is needed (which it seems to be on iOS):So
addLibsamplerateModule(context, undefined)inoutput.jsfalls back to the jsdelivr URL regardless of what we pass.We apply this patch as a workaround via pnpm for now: