okaryo.log

Achieving Seamless Looping Sound Playback in JavaScript | okaryo.log

Achieving Seamless Looping Sound Playback in JavaScript

    #JavaScript

Introduction

Recently, I released ScrapboxRelaxExtension, a Chrome extension that allows playing ambient sounds on Scrapbox.

During this process, I realized the need for a bit of a trick to ensure the ambient sounds loop seamlessly.

Implementation Method

Normally, HTMLAudioElement is sufficient for playing music in JavaScript. Initially, I implemented it like this:

const audioElement = new Audio("sound.wav");
audioElement.loop = true;
audioElement.play();
audioElement.pause();

However, this approach resulted in a slight break in the sound at the loop joint. I tried increasing the playback duration of the music to reduce the frequency of these joints, but this wasn’t a fundamental solution as it also increased the file size.

While exploring other options, I came across the AudioBufferSourceNode API.

By preloading music data into memory, it’s possible to make the loop joints seamless. I fetched files over the network, but it seems feasible to use local files with FileReader or similar methods, as long as it’s a Buffer.

const audioContext = new AudioContext();
const response = await fetch("https://sample.com/sound.wav");
const arrayBuffer = await response.arrayBuffer();
const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
const audio = audioContext.createBufferSource();
audio.buffer = audioBuffer;
audio.loop = true;
audio.connect(audioContext.destination);
audio.start();
audio.stop();

You can further fine-tune the loop joints by setting loopStart and loopEnd as needed.

One point of caution is that loading music data into memory can lead to high memory consumption, especially with large files.

Conclusion

This was my first experience with audio-related APIs, and it was quite refreshing.

Apart from looping playback, I also learned a lot, such as how browser restrictions require user actions to play music on web pages, presenting various challenges and learning opportunities.


Related Posts

No related posts

Related Posts
Promotion

This site uses Google Analytics.