How to Play Sound in Reverse with Howler.js

This article explains how to play audio in reverse using Howler.js. Because Howler.js and the underlying HTML5 Audio specifications do not support negative playback rates, playing audio backward requires specific workarounds. We will cover the two most effective methods: pre-reversing your audio files for maximum compatibility, and programmatically reversing audio buffers at runtime using the Web Audio API alongside Howler.

Why Howler.js Cannot Play Audio Backward Natively

Howler.js relies on the Web Audio API and HTML5 Audio. The browser standards for these technologies do not support a negative playback rate (e.g., setting rate to -1 will either mute the audio, throw an error, or have no effect).

To play a sound in reverse, you must use one of the two methods below.


The most performant and reliable approach is to reverse your audio file before uploading it to your project. This avoids runtime processing overhead and ensures 100% compatibility across all browsers, including older mobile devices.

You can easily reverse audio files using free tools: * Audacity: Import your file, select the entire track, go to Effect > Reverse, and export. * FFmpeg: Run the following command in your terminal: bash ffmpeg -i input.mp3 -af reverse output.mp3

Once exported, load the reversed file into Howler.js like a standard track:

const reverseSound = new Howl({
  src: ['audio/reversed-sound.mp3']
});

reverseSound.play();

Method 2: Programmatic Reversal Using Web Audio API

If you must reverse audio dynamically at runtime, you can fetch the audio file, decode it into an AudioBuffer, reverse the channel array data, and play it back using Howler’s shared AudioContext.

Here is how to implement programmatic audio reversal:

async function playReverse(url) {
  // 1. Ensure Howler's Web Audio context is initialized
  const ctx = Howler.ctx;
  if (!ctx) {
    console.error("Web Audio API is not supported or Howler is not initialized.");
    return;
  }

  try {
    // 2. Fetch the audio file as an ArrayBuffer
    const response = await fetch(url);
    const arrayBuffer = await response.arrayBuffer();

    // 3. Decode the audio data into an AudioBuffer
    const audioBuffer = await ctx.decodeAudioData(arrayBuffer);

    // 4. Reverse the data for each audio channel
    for (let i = 0; i < audioBuffer.numberOfChannels; i++) {
      audioBuffer.getChannelData(i).reverse();
    }

    // 5. Play the reversed buffer using Howler's audio node chain
    const source = ctx.createBufferSource();
    source.buffer = audioBuffer;
    
    // Connect to Howler's master gain node to respect Howler's global volume/mute
    source.connect(Howler.masterGain);
    source.start(0);
  } catch (error) {
    console.error("Error reversing and playing audio:", error);
  }
}

// Example usage:
playReverse('audio/sound.mp3');

Considerations for Programmatic Reversal