-
Notifications
You must be signed in to change notification settings - Fork 275
feat: enhance audio device management in Conversational AI demo #179
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: enhance audio device management in Conversational AI demo #179
Conversation
- Added functionality to select and manage audio input (microphone) and output (speaker) devices. - Implemented device population and selection UI in the HTML. - Updated JavaScript to handle device selection, status updates, and permissions for microphone access. - Improved user experience by disabling device selectors during active conversations and displaying active device statuses.
|
Someone is attempting to deploy a commit to the ElevenLabs Team on Vercel. A member of the Team first needs to authorize it. |
| async function populateDeviceSelectors() { | ||
| try { | ||
| // We need to request permission first to get the device labels | ||
| await navigator.mediaDevices.getUserMedia({ audio: true }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The populateDeviceSelectors() function requests microphone access but never closes the resulting media stream, causing a memory leak and keeping the microphone "active" indefinitely.
View Details
📝 Patch Details
diff --git a/examples/conversational-ai/javascript/src/app.js b/examples/conversational-ai/javascript/src/app.js
index bdef975..007bc84 100644
--- a/examples/conversational-ai/javascript/src/app.js
+++ b/examples/conversational-ai/javascript/src/app.js
@@ -16,9 +16,13 @@ async function getAvailableAudioDevices() {
async function populateDeviceSelectors() {
try {
// We need to request permission first to get the device labels
- await navigator.mediaDevices.getUserMedia({ audio: true });
+ const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const devices = await getAvailableAudioDevices();
+
+ // Clean up the stream immediately after getting device information
+ stream.getTracks().forEach(track => track.stop());
+
const micSelector = document.getElementById("audioDeviceSelector");
const speakerSelector = document.getElementById("speakerDeviceSelector");
Analysis
In the populateDeviceSelectors() function, line 19 calls await navigator.mediaDevices.getUserMedia({ audio: true }) to request microphone permissions so that device labels become available. However, the function never stores a reference to the returned MediaStream or calls .getTracks().forEach(track => track.stop()) to release the microphone resource.
This creates two problems:
- Memory leak: The MediaStream object and associated resources are never properly cleaned up
- User experience issue: The browser will show the microphone as "in use" (red recording indicator) even when no conversation is active, which can confuse users
The fix is to capture the stream reference and immediately stop all tracks after getting the device information:
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
// ... get devices and populate selectors ...
// Clean up the stream
stream.getTracks().forEach(track => track.stop());This ensures the microphone resource is properly released while still allowing the device enumeration to work correctly.
…n conversation start - Removed the `setSpeakerDevice` function as it was not utilized. - Added logging for the selected speaker device when starting a conversation. - Updated the parameter name for output device ID in the conversation session to enhance clarity.
- Eliminated console logs for microphone and speaker device IDs during conversation initiation to streamline the code and reduce unnecessary output.
This branch will not work without upgrated ElevenLabs JavaScript Client Library