Read Aloud Feature not working on ChatGPT via Firefox

Hi all,

I’m facing an issue where the new Read Aloud feature in the ChatGPT web version doesn’t work on Firefox (Ubuntu 22.04). The button appears active, but there’s no audio playback, unlike on Chrome or Brave where it works fine.

Is this a known bug? Has anyone else experienced it or found a workaround? Hoping for a fix or any tips from the community or OpenAI!

Thanks!

6 Likes

Can confirm no audio on Firefox.

A call is made that returns 50kB of audio for a sentence response, but the play button just remains stuck on play with no audible multimedia.

6 Likes

No audio on Firefox 123.0 (64-bit) Win 10 (only acts like it is playing)

This issue remains after clearing all cache and forcing the settings ON for audio playback on the site ~ see screenshot:
audio set

3 Likes

yeah, dont’ work at Firefox on windows.

1 Like

Also the same here with FF on Mac - would be great to get this fixed.

Update: This is the error, the Firefox console throws, whenever I try to play the audio: Uncaught (in promise) DOMException: MediaSource.addSourceBuffer: Type not supported in MediaSource NextJS 33 sourceopen e_ eS d h eU eH re re rn ro oN eF ro nU nD ru rr ra ra hydrateRoot ef ef ed ep 91262 promise callback*91262 p <anonymous> O <anonymous> u <anonymous>

I’m not technically skilled enough to find out, whether it’s a Firefox issue or a ChatGPT issue.

1 Like

I experience the same issue in Firefox…
I really hope it gets fixed soon.

1 Like

Hey everyone, the problem seems to be that Firefox can’t stream the AAC, but it can still play back “complete” AAC audio. There is a Userscript that captures the response from the Synthesize (i.e. Voice) API and opens it as an AAC blob in a new tab: Reddit - Dive into anything

It’s not a great solution, but it’s good enough if you just want to have it occasionally read something to you.

Note: The Userscript does not modify website behavior (even without it, the audio data is received), it just automates the process of opening dev tools and saving the response from the API as an .aac file and playing it back.

2 Likes

Thanks a lot for diving deeper into what the issue is and providing this workaround!

I implemented your Userscript via the Tampermonkey extension and it works!! Yes, it’s kind of a janky solution, but thanks to you, I don’t have to use Brave Browser for ChatGPT anymore.

I tried creating a browser extension, that converts the aac and then plays it back in the background, just like it’s supposed to, but I failed unfortunately. The idea was to use ffmpeg.wasm.

I also reported the bug to OpenAI btw.

2 Likes

@everyone

I think, I found the perfect solution!

I modified the Userscript of @Winkelmann and now, the audio is being played directly on the website (no tab opening) and on top of the screen, there are controls to pause, stop, rewind and play from the beginning.

It’s not a very aesthetically pleasing solution and the audio takes longer to play, since it doesn’t stream and has to finish generating, but hey, now you can rewind the audio, which is not something the Read Aloud feature normally offers.

Here’s the Userscript code, that you need to enter into the Tampermonkey extension:

// ==UserScript==
// @name         OpenAI Chat Synthesize Interceptor with Advanced Icon Controls
// @version      0.6
// @description  Capture ChatGPT Synthesize API responses and add advanced playback controls with icons.
// @author       You
// @match        https://chat.openai.com/*
// @grant        none
// ==/UserScript==

(function () {
    // 'use strict';
    let audio = null; // Global audio element
    let playPauseBtn; // Global play/pause button

    const originalFetch = window.fetch;
    window.fetch = async function (url, options) {
        const response = await originalFetch.apply(this, arguments);
        if (url.startsWith('https://chat.openai.com/backend-api/synthesize')) {
            console.log('Intercepted Synthesize API request for URL:', url);
            const clone = response.clone();
            const arrayBuffer = await clone.arrayBuffer();
            const aacFile = new Blob([arrayBuffer], { type: 'audio/aac' });
            const fileUrl = URL.createObjectURL(aacFile);
            if (audio) {
                audio.src = fileUrl;
            } else {
                audio = new Audio(fileUrl);
                createControls();
            }
            audio.play().catch(err => console.error('Audio playback error:', err))
                .then(() => {
                    playPauseBtn.innerHTML = '⏸'; // Change to Pause icon
                    showControlsTemporarily(); // Show controls when audio starts playing
                });
        }
        return response;
    };

    function createControls() {
        const controlsDiv = document.createElement('div');
        controlsDiv.id = 'audioControls';
        controlsDiv.style.position = 'fixed';
        controlsDiv.style.top = '15px';
        controlsDiv.style.left = '50%';
        controlsDiv.style.transform = 'translateX(-50%)';
        controlsDiv.style.zIndex = '10000';
        controlsDiv.style.display = 'flex';
        controlsDiv.style.gap = '10px';
        controlsDiv.style.opacity = '0'; // Initially invisible, updated to be controlled by showControlsTemporarily
        controlsDiv.style.transition = 'opacity 0.5s ease'; // Smooth transition for opacity

        // Make controls visible on hover
        controlsDiv.onmouseover = function() {
            controlsDiv.style.opacity = '1';
        };

        // Make controls invisible again when not hovered
        controlsDiv.onmouseout = function() {
            controlsDiv.style.opacity = '0';
        };

        // Play from the beginning button
        const startOverBtn = document.createElement('button');
        startOverBtn.innerHTML = '⏮'; // Start over icon
        startOverBtn.style.cursor = 'pointer';
        startOverBtn.style.background = 'none';
        startOverBtn.style.border = 'none';
        startOverBtn.onclick = function() {
            audio.currentTime = 0;
            audio.play();
            playPauseBtn.innerHTML = '⏸'; // Change to Pause icon
        };

        // Play/Pause button
        playPauseBtn = document.createElement('button');
        playPauseBtn.innerHTML = '▶️'; // Play icon, assuming audio is stopped at first
        playPauseBtn.style.cursor = 'pointer';
        playPauseBtn.style.background = 'none';
        playPauseBtn.style.border = 'none';
        playPauseBtn.onclick = function() {
            if (audio.paused || audio.ended) {
                audio.play();
                playPauseBtn.innerHTML = '⏸'; // Change to Pause icon
            } else {
                audio.pause();
                playPauseBtn.innerHTML = '▶️'; // Change to Play icon
            }
        };

        // Rewind 10 seconds button
        const rewindBtn = document.createElement('button');
        rewindBtn.innerHTML = '⏪'; // Rewind icon
        rewindBtn.style.cursor = 'pointer';
        rewindBtn.style.background = 'none';
        rewindBtn.style.border = 'none';
        rewindBtn.onclick = function() {
            audio.currentTime = Math.max(0, audio.currentTime - 10); // Rewind 10 seconds or to the start
            if (audio.paused) {
                audio.play();
                playPauseBtn.innerHTML = '⏸'; // Ensure play/pause button shows Pause icon
            }
        };

        // Stop button
        const stopBtn = document.createElement('button');
        stopBtn.innerHTML = '⏹'; // Stop icon
        stopBtn.style.cursor = 'pointer';
        stopBtn.style.background = 'none';
        stopBtn.style.border = 'none';
        stopBtn.onclick = function() {
            audio.pause();
            audio.currentTime = 0;
            playPauseBtn.innerHTML = '▶️'; // Change to Play icon
        };

        controlsDiv.appendChild(startOverBtn);
        controlsDiv.appendChild(rewindBtn);
        controlsDiv.appendChild(playPauseBtn);
        controlsDiv.appendChild(stopBtn);

        document.body.appendChild(controlsDiv);

        // Call this to initially show controls
        showControlsTemporarily();
    }

    function showControlsTemporarily() {
        const controlsDiv = document.getElementById('audioControls');
        if (controlsDiv) {
            controlsDiv.style.opacity = '1'; // Make controls visible

            // Use setTimeout to fade controls out after 5 seconds
            setTimeout(() => {
                if (!controlsDiv.matches(':hover')) { // Only fade out if not hovering over controls
                    controlsDiv.style.opacity = '0';
                }
            }, 2000); // Adjust time as needed
        }
    }
})();

4 Likes

Thanks a lot. This works amazingly well.
This is a good solution until OpenAI gets to implementing a workaround or firefox fixes the issue.

1 Like

This seems to be the exact Firefox issue:

also see:

2 Likes

It’s fixed just update your Firefox, but it only works on ChatGPT 4.

I can confirm this.
Not sure if they fixed it with Firefox 124 or if OpenAI changed something on their side, but now Read Aloud works without that Tampermonkey script for me. :+1:

1 Like

I now have a new second system (win 11 state of the art everything)

New system Firefox 120.01 - YES - read aloud works perfectly
Old system Win 10 Firefox 120.01 - NO - read aloud showing it is playing but no sound

Hi, could you tell me how to use this feature? I’m not very computer savvy, and it’s not working for me either. Could you please guide me on how to go to the settings and activate this feature on my computer or application? Thank you for your help

Same for me on Naver Whale

I have this issue on Opera Gx as well.