# Chrome doesnt output Audio

**URL:** <https://mediasoup.discourse.group/t/chrome-doesnt-output-audio/6080>\
**Category:** mediasoup libraries\
**Created:** [May 30, 2024, 10:25pm UTC](https://mediasoup.discourse.group/t/chrome-doesnt-output-audio/6080 "2024-05-30T22:25:23Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![DogchampDiego](https://yyz2.discourse-cdn.com/free1/user_avatar/mediasoup.discourse.group/dogchampdiego/32/2626_2.png) [@DogchampDiego](https://mediasoup.discourse.group/u/DogchampDiego)\
**Post date:** [May 30, 2024, 10:25pm UTC](https://mediasoup.discourse.group/t/chrome-doesnt-output-audio/6080/1 "2024-05-30T22:25:23Z")

</div>

So Iam setting up a conferencing Platform with mediasoup. This is my Client Side. Everything is working fine with Firefox but when i Client joins which uses Chrome, i can only See Video but i dont hear any audio.

What i did:

- checked for audiocontext to be running

I dont know what the Problem is, maybe the Codecs or something.

My Codecs defined in my Mediaserver:  
router = await worker.createRouter({  
mediaCodecs: [  
{  
kind: ‘audio’,  
mimeType: ‘audio/opus’,  
clockRate: 48000,  
channels: 2  
},  
{  
kind: ‘video’,  
mimeType: ‘video/VP8’,  
clockRate: 90000,  
parameters: {  
‘x-google-start-bitrate’: 1000  
}  
}  
]  
});

My Clientside Code:  
const mediasoupClient = require(‘mediasoup-client’);  
const io = require(‘socket.io-client’);

const SIGNALING\_SERVER\_IP = ‘MY\_IP’;  
const socket = io(`https://${SIGNALING_SERVER_IP}:3000`);

let localStream = null;  
let roomUUID;  
let device;  
let producerTransport;  
let videoProducer = null;  
let audioProducer = null;  
let consumerTransport = null;  
let consumers = ;  
let isProducing = false; // To prevent multiple calls to startProducing  
let label2name = new Map();

const audioContext = new (window.AudioContext || window.webkitAudioContext)();  
const audioDestination = audioContext.createMediaStreamDestination();

let expectedAudioStreams = 0;  
let receivedAudioStreams = 0;  
let audioStreams = ;

// Create a single audio element to play the mixed audio  
const audioElement = new Audio();  
audioElement.srcObject = audioDestination.stream;  
audioElement.autoplay = true;  
document.body.appendChild(audioElement);

async function getLocalStream() {  
try {  
localStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });  
console.log(‘Local stream obtained:’, localStream);  
addVideoStream(localStream, true, ‘local’);  
await createDevice();  
await createProducerTransport();  
} catch (error) {  
console.error(‘Error accessing media devices.’, error);  
}  
}

function addVideoStream(stream, muted, label) {  
console.log(`Adding video stream (${label}):`, stream);

```
// Check if the stream is already added
const existingVideo = document.querySelector(`video[data-label="${label}"]`);
if (existingVideo) {
    console.warn(`Video stream (${label}) already added, skipping.`);
    return;
}

const videoElement = document.createElement('video');
videoElement.srcObject = stream;
videoElement.muted = muted;
videoElement.autoplay = true;
videoElement.controls = true;
videoElement.setAttribute('data-label', label); // Set a label to identify the video stream
videoElement.style.objectFit = 'contain'; // Ensure video fits within the container
videoElement.style.objectPosition = 'center'; // Center the video within the container

document.getElementById('videoContainer').appendChild(videoElement);
document.getElementById('joinForm').style.display = 'none';
document.getElementById('videoContainer').style.display = 'flex';

videoElement.volume = document.getElementById('videoContainer').volume || 1.0;
adjustVolume();

```

}

function addAudioStream(stream, label) {  
console.log(`Adding audio stream (${label}):`, stream);

```
const audioSource = audioContext.createMediaStreamSource(stream);
audioSource.connect(audioDestination);

audioStreams.push(audioSource);

// Increment the count of received audio streams
receivedAudioStreams++;
console.log(`Received ${receivedAudioStreams}/${expectedAudioStreams} audio streams`);

// Only play the mixed audio once all audio streams are received
if (receivedAudioStreams === expectedAudioStreams) {
    audioElement.play();
}

```

}

function adjustVolume() {  
const volume = document.getElementById(‘videoContainer’).volume || 1.0;  
document.querySelectorAll(‘video’).forEach(video =\> {  
video.volume = volume;  
});  
}

async function createDevice() {  
device = new mediasoupClient.Device();  
const routerRtpCapabilities = await new Promise((resolve) =\> {  
socket.emit(‘getRouterRtpCapabilities’, resolve);  
});  
await device.load({ routerRtpCapabilities });  
console.log(‘Device created and loaded’);  
}

async function createProducerTransport() {  
console.log(“Creating Producer Transport”);  
socket.emit(‘createProducerTransport’, { roomUUID }, async (transportOptions) =\> {  
if (transportOptions.error) {  
console.error(‘Error from server creating producer transport:’, transportOptions.error);  
return;  
}

```
    const { id, iceParameters, iceCandidates, dtlsParameters } = transportOptions;
    console.log('Received transport options:', transportOptions);
    producerTransport = device.createSendTransport({
        id,
        iceParameters,
        iceCandidates,
        dtlsParameters
    });

    console.log('Producer transport created:', producerTransport);

    producerTransport.on('connect', ({ dtlsParameters }, callback, errback) => {
        console.log('Producer Transport Connect event triggered with dtlsParameters:', dtlsParameters);
        socket.emit('connectProducerTransport', { dtlsParameters }, (response) => {
            if (response.error) {
                console.error('connectProducerTransport response error:', response.error);
                errback(response.error);
            } else {
                console.log('connectProducerTransport response success');
                callback();
            }
        });
    });

    producerTransport.on('produce', async (parameters, callback, errback) => {
        console.log('Start Producing with parameters:', parameters);
        socket.emit('produce', parameters, ({ id }) => {
            if (id) {
                console.log('Produced track with id:', id);
                callback({ id });
            } else {
                errback('Produce failed');
            }
        });
    });

    producerTransport.on('connectionstatechange', (state) => {
        console.log('Producer transport connection state changed:', state);
        console.log(producerTransport);
        if (state === 'failed') {
            console.error('Producer transport entered failed state');
            producerTransport.close();
        }
    });

    if (!isProducing) {
        await startProducing();
        isProducing = true;
    }
});

```

}

async function startProducing() {  
try {  
if (localStream.getVideoTracks().length \> 0) {  
const videoTrack = localStream.getVideoTracks()[0];  
console.log(‘Producing video track:’, videoTrack);  
videoProducer = await producerTransport.produce({ track: videoTrack });  
console.log(‘Video producer created:’, videoProducer.id);  
} else {  
console.warn(‘No video track available’);  
}

```
    if (localStream.getAudioTracks().length > 0) {
        const audioTrack = localStream.getAudioTracks()[0];
        console.log('Producing audio track:', audioTrack);
        audioProducer = await producerTransport.produce({ track: audioTrack });
        console.log('Audio producer created:', audioProducer.id);
    } else {
        console.warn('No audio track available');
    }

    if (videoProducer) {
        videoProducer.on('transportclose', () => {
            console.log('Video transport closed');
        });

        videoProducer.on('trackended', () => {
            console.log('Video track ended');
        });
    }

    if (audioProducer) {
        audioProducer.on('transportclose', () => {
            console.log('Audio transport closed');
        });

        audioProducer.on('trackended', () => {
            console.log('Audio track ended');
        });
    }
} catch (error) {
    console.error('Error producing tracks:', error);
}

```

}

async function createConsumerTransport() {  
console.log(`Creating Consumer Transport`);  
return new Promise((resolve, reject) =\> {  
socket.emit(‘createConsumerTransport’, { roomUUID }, async (transportOptions) =\> {  
if (transportOptions.error) {  
console.error(‘Error from server creating consumer transport:’, transportOptions.error);  
reject(transportOptions.error);  
return;  
}

```
        const { id, iceParameters, iceCandidates, dtlsParameters } = transportOptions;
        consumerTransport = device.createRecvTransport({
            id,
            iceParameters,
            iceCandidates,
            dtlsParameters
        });

        console.log('Consumer transport created:', consumerTransport);

        let isConnected = false;

        consumerTransport.on('connect', ({ dtlsParameters }, callback, errback) => {
            if (isConnected) {
                console.warn('Consumer transport already connected');
                return;
            }
            console.log('Consumer Transport Connect event triggered with dtlsParameters:', dtlsParameters);
            socket.emit('connectConsumerTransport', { dtlsParameters }, (response) => {
                if (response.error) {
                    errback(response.error);
                } else {
                    console.log('connectConsumerTransport response success');
                    isConnected = true;
                    callback();
                }
            });
        });

        consumerTransport.on('connectionstatechange', (state) => {
            console.log('Consumer transport state:', state);
            if (state === 'failed') {
                consumerTransport.close();
            }
        });

        resolve(consumerTransport);
    });
});

```

}

async function consume(producerId) {

```
socket.emit('consume', { producerId, rtpCapabilities: device.rtpCapabilities }, async (response) => {
    const { id, kind, rtpParameters } = response;
    const consumer = await consumerTransport.consume({ id, producerId, kind, rtpParameters });
    console.log('Consumed track:', consumer.track);
    consumers.push(consumer);
    const stream = new MediaStream();
    stream.addTrack(consumer.track);

    if (kind === 'video') {
        addVideoStream(stream, false, `producer-${producerId}`);
    } else if (kind === 'audio') {
        addAudioStream(stream, `producer-${producerId}`);
    }
});

```

}

socket.on(‘newProducer’, async ({ producerId, kind, name}) =\> {  
console.log(“New producer detected:”, producerId, kind);  
if (kind == “audio”) expectedAudioStreams++  
if (kind == “video”) label2name.set(name, producerId);

```
await consume(producerId);

```

});

socket.on(‘joined-room’, async ({ roomUUID, name, totalClients, existingProducers, participants }) =\> {  
console.log(`User ${name} joined the room: ${roomUUID} with Clients: ${totalClients}`);  
expectedAudioStreams = totalClients - 1;  
console.log(`Expecting ${expectedAudioStreams} audio streams`);

```
// Display the participants list
updateParticipantsList(participants);

// Start Producing
await getLocalStream();

// Start Consuming 
consumerTransport = await createConsumerTransport();

// Consume existing producers if available
for (const producerId of existingProducers) {
    await consume(producerId, 'video'); // Assuming you know the kind, adjust as necessary
    await consume(producerId, 'audio'); // Assuming you know the kind, adjust as necessary
}

```

});

socket.on(‘new-participant’, ({ name }) =\> {  
addParticipant(name);  
});

socket.on(‘user-left’, ({ name }) =\> {  
removeParticipant(name);  
removeUserVideo(name);  
});

document.addEventListener(‘DOMContentLoaded’, function() {  
console.log(‘DOM fully loaded and parsed’);  
const urlParams = new URLSearchParams(window.location.search);  
roomUUID = urlParams.get(‘room’);  
console.log(‘Room UUID:’, roomUUID);

```
const joinButton = document.getElementById('joinButton');
if (joinButton) {
    joinButton.addEventListener('click', joinMeeting);
    console.log('Join button found and event listener added');
} else {
    console.error('Join button not found');
}

const leaveButtonContainer = document.getElementById('leaveButtonContainer');
if (leaveButtonContainer) {
    leaveButtonContainer.addEventListener('click', leaveMeeting);
    console.log('Leave button container found and event listener added');
} else {
    console.error('Leave button container not found');
}

// Set an initial volume and add an event listener to adjust volume
const videoContainer = document.getElementById('videoContainer');
videoContainer.volume = 1.0;
videoContainer.addEventListener('volumechange', adjustVolume);

// Ask the server if the room still exists
socket.emit('ask-for-room', roomUUID, (response) => {
    console.log(response)
    if (response.exists) {
        // Check if there is a saved session in localStorage
        const savedRoomUUID = localStorage.getItem('roomUUID');
        const savedName = localStorage.getItem('name');
        const savedMeetingCode = localStorage.getItem('meetingCode');
        if (savedRoomUUID && savedName && savedMeetingCode) {
            roomUUID = savedRoomUUID;
            document.getElementById('nameInput').value = savedName;
            document.getElementById('meetingCodeInput').value = savedMeetingCode;
            joinMeeting();
        }
    } else {
        console.error('Room does not exist');
        // Optionally, clear local storage if the room no longer exists
        localStorage.removeItem('roomUUID');
        localStorage.removeItem('name');
        localStorage.removeItem('meetingCode');

        alert(`Room doesnt exist anymore, you got redirected to the Homepage'}`);
        window.location.href = '/';
    }
});

```

});

async function joinMeeting() {  
console.log(‘Join button clicked’);  
const name = document.getElementById(‘nameInput’).value.trim();  
const meetingCode = document.getElementById(‘meetingCodeInput’).value.trim();  
if (!name || !meetingCode || name.trim() === ‘’) {  
alert(‘Name and meeting code are required.’);  
return;  
}  
console.log(‘Name:’, name, ‘Meeting Code:’, meetingCode);

```
// Save session details to localStorage
localStorage.setItem('roomUUID', roomUUID);
localStorage.setItem('name', name);
localStorage.setItem('meetingCode', meetingCode);

socket.emit('join', { roomUUID, name, meetingCode }, (response) => {
    console.log(response)
    if (response.success) {
        console.log('Successfully joined the meeting:', response);
        const joinForm = document.getElementById('joinForm');
        const videoContainer = document.getElementById('videoContainer');
        const leaveButtonContainer = document.getElementById('leaveButtonContainer');
        // Hide join form smoothly
        joinForm.style.opacity = 0;
        joinForm.style.transform = 'scale(0.9)';

        setTimeout(() => {
            joinForm.style.display = 'none';
            // Show video container and leave button smoothly
            meetingContainer.style.display = 'flex';
            leaveButtonContainer.style.display = 'block';

            setTimeout(() => {
                videoContainer.style.opacity = 1;
                videoContainer.style.transform = 'scale(1)';
                leaveButtonContainer.style.opacity = 1;
                leaveButtonContainer.style.transform = 'scale(1)';

            }, 50);
        }, 500);
    } else {

        alert(`Failed to join the meeting: ${response ? response.message : 'Unknown error'}`);
    }
});

```

}

async function leaveMeeting() {  
console.log(‘Leave button clicked’);  
socket.emit(‘leave’, { roomUUID }, (response) =\> {  
if (response.success) {  
console.log(‘Successfully left the meeting:’, response);  
const videoContainer = document.getElementById(‘videoContainer’);  
const leaveButtonContainer = document.getElementById(‘leaveButtonContainer’);

```
        // Hide video container and leave button smoothly
        videoContainer.style.opacity = 0;
        videoContainer.style.transform = 'scale(0.9)';
        leaveButtonContainer.style.opacity = 0;
        leaveButtonContainer.style.transform = 'scale(0.9)';

        setTimeout(() => {
            videoContainer.style.display = 'none';
            leaveButtonContainer.style.display = 'none';
            // Clear session details from localStorage
            document.getElementById('joinForm').style.display = 'block';
            document.getElementById('videoContainer').style.display = 'none';
            document.getElementById('leaveButtonContainer').style.display = 'none';
            clearLocalStorage();
            stopLocalStream();
            stopAllTransportsAndProducers();
            // Redirect to homepage
            window.location.href = '/';
        }, 500);
    } else {
        alert(`Failed to leave the meeting: ${response ? response.message : 'Unknown error'}`);
        window.location.href = '/';
    }
});

```

}

function clearLocalStorage() {  
localStorage.removeItem(‘roomUUID’);  
localStorage.removeItem(‘name’);  
localStorage.removeItem(‘meetingCode’);  
}

function stopLocalStream() {  
if (localStream) {  
localStream.getTracks().forEach(track =\> track.stop());  
localStream = null;  
}  
}

function stopAllTransportsAndProducers() {  
if (videoProducer) {  
videoProducer.close();  
videoProducer = null;  
}  
if (audioProducer) {  
audioProducer.close();  
audioProducer = null;  
}  
if (producerTransport) {  
producerTransport.close();  
producerTransport = null;  
}  
if (consumerTransport) {  
consumerTransport.close();  
consumerTransport = null;  
}  
consumers.forEach(consumer =\> {  
consumer.close();  
});  
consumers = ;  
}

function updateParticipantsList(participants) {  
const participantsList = document.getElementById(‘participantsList’);  
participantsList.innerHTML = ‘’; // Clear the list  
participants.forEach(name =\> {  
const listItem = document.createElement(‘li’);  
listItem.textContent = name;  
participantsList.appendChild(listItem);  
});  
}

function addParticipant(name) {  
const participantsList = document.getElementById(‘participantsList’);  
const listItem = document.createElement(‘li’);  
listItem.textContent = name;  
participantsList.appendChild(listItem);  
}

function removeParticipant(name) {  
console.log(name)  
const participantsList = document.getElementById(‘participantsList’);  
const listItems = participantsList.getElementsByTagName(‘li’);  
console.log(listItems)  
for (let i = 0; i \< listItems.length; i++) {  
if (listItems[i].textContent.trim() === name.trim()) {  
participantsList.removeChild(listItems[i]);  
break;  
}  
}  
}

function removeUserVideo(name) {  
const producerId = label2name.get(name);  
console.log(“ProducerID”,producerId)  
if (!producerId) {  
console.warn(`No producer ID found for participant (${name}).`);  
return;  
}  
const videoElement = document.querySelector(`video[data-label="producer-${producerId}"]`);

```
if (videoElement) {
    videoElement.parentNode.removeChild(videoElement);
    console.log(`Removed video stream for ${name} (${producerId}).`);
} else {
    console.warn(`Video stream for ${name} (${producerId}) not found.`);
}

// Remove the mapping
label2name.delete(producerId);

```

}
