Skip to content

Conversation

@niraltmark
Copy link

@niraltmark niraltmark commented May 31, 2025

This branch will not work without upgrated ElevenLabs JavaScript Client Library

  • 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.
image

- 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.
@vercel
Copy link
Contributor

vercel bot commented May 31, 2025

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 });
Copy link
Contributor

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:

  1. Memory leak: The MediaStream object and associated resources are never properly cleaned up
  2. 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants