NewsWorld
PredictionsDigestsScorecardTimelinesArticles
NewsWorld
HomePredictionsDigestsScorecardTimelinesArticlesWorldTechnologyPoliticsBusiness
AI-powered predictive news aggregation© 2026 NewsWorld. All rights reserved.
For live open‑source updates on the Middle East conflict, visit the IranXIsrael War Room.

A real‑time OSINT dashboard curated for the current Middle East war.

Open War Room

Trending
IranIranianMilitaryStrikesIsraeliCrisisPricesRegionalMarketOperationsLaunchGulfHormuzEscalationConflictTimelineTargetsStatesStraitDigestPowerProxyMarchDisruption
IranIranianMilitaryStrikesIsraeliCrisisPricesRegionalMarketOperationsLaunchGulfHormuzEscalationConflictTimelineTargetsStatesStraitDigestPowerProxyMarchDisruption
All Articles
Show HN: Gapless.js – gapless web audio playback
Hacker News
Clustered Story
Published about 3 hours ago

Show HN: Gapless.js – gapless web audio playback

Hacker News · Mar 2, 2026 · Collected from RSS

Summary

Hey HN, I just released v4 of my gapless playback library that I first built in 2017 for https://relisten.net. We stream concert recordings, where gapless playback is paramount. It's built from scratch, backed by a rigid state machine (the sole dependency is xstate) and is already running in production over at Relisten. The way it works is by preloading future tracks as raw buffers and scheduling them via the web audio API. It seamlessly transitions between HTML5 and web audio. We've used this technique for the last 9 years and it works fairly well. Occasionally it will blip slightly from HTML5->web audio, but there's not much to be done to avoid that (just when to do it - lotta nuance here). Once you get on web audio, everything should be clean. Unfortunately web audio support still lacks on mobile, in which case you can just disable web audio and it'll fallback to full HTML5 playback (sans gapless). But if you drive a largely desktop experience, this is fine. On mobile, most people use our native app. You can view a demo of the project at https://gapless.saewitz.com - just click on "Scarlet Begonias", seek halfway in the track (as it won't preload until >15s) and wait for "decoding" on "Fire on the Mountain" to switch to "ready". Then tap "skip to -2s and hear the buttery smooth segue. Comments URL: https://news.ycombinator.com/item?id=47222271 Points: 10 # Comments: 4

Full Article

gapless.js Gapless audio player for the web. Takes an array of audio tracks and uses HTML5 audio with the Web Audio API to enable seamless, gapless transitions between tracks. Though the earnest goal is not bundle-size driven, it has only one production dependency (xstate) so it operates in a rigid manner according to a well-designed state machine. It has a dead simple API and is easy to get up and running. Built for Relisten.net, where playing back gapless live tracks is paramount. Live Demo Install pnpm install gapless Quick Start import Queue from 'gapless'; const player = new Queue({ tracks: [ 'https://example.com/track1.mp3', 'https://example.com/track2.mp3', 'https://example.com/track3.mp3', ], onProgress: (track) => { console.log(`${track.currentTime} / ${track.duration}`); }, onEnded: () => { console.log('Queue finished'); }, }); player.play(); API Constructor Options (GaplessOptions) const player = new Queue({ tracks: [], // Initial list of track URLs onProgress: (info) => {}, // Called at ~60fps while playing onEnded: () => {}, // Called when the last track ends onPlayNextTrack: (info) => {}, // Called when advancing to next track onPlayPreviousTrack: (info) => {},// Called when going to previous track onStartNewTrack: (info) => {}, // Called whenever a new track becomes current onError: (error) => {}, // Called on audio errors onPlayBlocked: () => {}, // Called when autoplay is blocked by the browser onDebug: (msg) => {}, // Internal debug messages (development only) webAudioIsDisabled: false, // Disable Web Audio API (disables gapless playback) trackMetadata: [], // Per-track metadata (aligned by index) volume: 1, // Initial volume, 0.0–1.0 }); Methods Method Description play() Start or resume playback pause() Pause playback togglePlayPause() Toggle between play and pause next() Advance to the next track previous() Go to previous track (restarts current track if > 8s in) gotoTrack(index, playImmediately?) Jump to a track by index seek(time) Seek to a position in seconds setVolume(volume) Set volume (0.0–1.0) addTrack(url, options?) Add a track to the end of the queue removeTrack(index) Remove a track by index resumeAudioContext() Resume the AudioContext (for browsers that require user gesture) destroy() Clean up all resources Getters Getter Type Description currentTrack TrackInfo | undefined Snapshot of the current track currentTrackIndex number Index of the current track tracks readonly TrackInfo[] Snapshot of all tracks isPlaying boolean Whether the queue is playing isPaused boolean Whether the queue is paused volume number Current volume TrackInfo All callbacks and getters return TrackInfo objects — plain data snapshots with no methods: interface TrackInfo { index: number; // Position in the queue currentTime: number; // Playback position in seconds duration: number; // Total duration (NaN until loaded) isPlaying: boolean; isPaused: boolean; volume: number; trackUrl: string; // Resolved audio URL playbackType: 'HTML5' | 'WEBAUDIO'; webAudioLoadingState: 'NONE' | 'LOADING' | 'LOADED' | 'ERROR'; metadata?: TrackMetadata; machineState: string; // Internal state machine state } AddTrackOptions player.addTrack('https://example.com/track.mp3', { skipHEAD: true, // Skip HEAD request for URL resolution metadata: { title: 'Track Title', artist: 'Artist', album: 'Album', artwork: [{ src: 'https://example.com/art.jpg', sizes: '512x512', type: 'image/jpeg' }], }, }); TrackMetadata Metadata is used for the Media Session API (lock screen controls, browser media UI) and can contain arbitrary additional fields: interface TrackMetadata { title?: string; artist?: string; album?: string; artwork?: MediaImage[]; [key: string]: unknown; } Migration from v3 v4 is a complete rewrite. The public API has changed: v3 v4 import GaplessQueue from 'gapless.js' import Queue from 'gapless' (or import { Queue }) player.playNext() player.next() player.playPrevious() player.previous() player.resetCurrentTrack() player.seek(0) player.disableWebAudio() Pass webAudioIsDisabled: true in constructor player.nextTrack player.tracks[player.currentTrackIndex + 1] track.completeState Callbacks now receive TrackInfo objects Callbacks receive Track instances Callbacks receive plain TrackInfo data snapshots Key differences State machines: Internally uses XState for queue and track state management. XState is bundled — no extra dependency needed. ESM only: Published as ES module only. No CommonJS build. TrackInfo: All callbacks and getters return plain data objects (TrackInfo) instead of Track class instances. Media Session: Built-in support for the Media Session API via trackMetadata. Volume: Volume is now set via setVolume(n) and readable via the volume getter. License MIT


Share this story

Read Original at Hacker News

Related Articles

Hacker Newsabout 10 hours ago
Show HN: Web Audio Studio – A Visual Debugger for Web Audio API Graphs

Hi HN, I’ve been working on a browser-based tool for exploring and debugging Web Audio API graphs. Web Audio Studio lets you write real Web Audio API code, run it, and see the runtime graph it produces as an interactive visual representation. Instead of mentally tracking connect() calls, you can inspect the actual structure of the graph, follow signal flow, and tweak parameters while the audio is playing. It includes built-in visualizations for common node types — waveforms, filter responses, analyser time and frequency views, compressor transfer curves, waveshaper distortion, spatial positioning, delay timing, and more — so you can better understand what each part of the graph is doing. You can also insert an AnalyserNode between any two nodes to inspect the signal at that exact point in the chain. There are around 20 templates (basic oscillator setups, FM/AM synthesis, convolution reverb, IIR filters, spatial audio, etc.), so you can start from working examples and modify them instead of building everything from scratch. Everything runs fully locally in the browser — no signup, no backend. The motivation came from working with non-trivial Web Audio graphs and finding it increasingly difficult to reason about structure and signal flow once things grow beyond simple examples. Most tutorials show small snippets, but real projects quickly become harder to inspect. I wanted something that stays close to the native Web Audio API while making the runtime graph visible and inspectable. This is an early alpha and desktop-only for now. I’d really appreciate feedback — especially from people who have used Web Audio API in production or built audio tools. You can leave comments here, or use the feedback button inside the app. https://webaudio.studio Comments URL: https://news.ycombinator.com/item?id=47216773 Points: 12 # Comments: 1

Hacker Newsabout 3 hours ago
"That Shape Had None" – A Horror of Substrate Independence (Short Fiction)

Article URL: https://starlightconvenience.net/#that-shape-had-none Comments URL: https://news.ycombinator.com/item?id=47222226 Points: 18 # Comments: 2

Hacker Newsabout 3 hours ago
Bars close and hundreds lose jobs as US firm buys Brewdog in £33M deal

Article URL: https://www.bbc.com/news/articles/c05v0p1d0peo Comments URL: https://news.ycombinator.com/item?id=47221994 Points: 74 # Comments: 46

Hacker Newsabout 4 hours ago
Show HN: Govbase – Follow a bill from source text to news bias to social posts

Govbase tracks every bill, executive order, and federal regulation from official sources (Congress.gov, Federal Register, White House). An AI pipeline breaks each one down into plain-language summaries and shows who it impacts by demographic group. It also ties each policy directly to bias-rated news coverage and politician social posts on X, Bluesky, and Truth Social. You can follow a single bill from the official text to how media frames it to what your representatives are saying about it. Free on web, iOS, and Android. https://govbase.com I'd love feedback from the community, especially on the data pipeline or what policy areas/features you feel are missing. Comments URL: https://news.ycombinator.com/item?id=47220809 Points: 16 # Comments: 3

Hacker Newsabout 4 hours ago
Reflex (YC W23) Is Hiring Software Engineers – Python

Article URL: https://www.ycombinator.com/companies/reflex/jobs Comments URL: https://news.ycombinator.com/item?id=47220666 Points: 0 # Comments: 0

Hacker Newsabout 5 hours ago
Launch HN: OctaPulse (YC W26) – Robotics and computer vision for fish farming

Hi HN! My name is Rohan and, together with Paul, I’m the co-founder of OctaPulse (https://www.tryoctapulse.com/). We’re building a robotics layer for seafood production, starting with automated fish inspection. We are currently deployed at our first production site with the largest trout producer in North America. You might be wondering how the heck we got into this with no background in aquaculture or the ocean industry. We are both from coastal communities. I am from Goa, India and Paul is from Malta and Puerto Rico. Seafood is deeply tied to both our cultures and communities. We saw firsthand the damage being done to our oceans and how wild fish stocks are being fished to near extinction. We also learned that fish is the main protein source for almost 55% of the world's population. Despite it not being huge consumption in America it is massive globally. And then we found out that America imports 90% of its seafood. What? That felt absurd. That was the initial motivation for starting this company. Paul and I met at an entrepreneurship happy hour at CMU. We met to talk about ocean tech. It went on for three hours. I was drawn to building in the ocean because it is one of the hardest engineering domains out there. Paul had been researching aquaculture for months and kept finding the same thing: a $350B global industry with less data visibility than a warehouse. After that conversation we knew we wanted to work on this together. Hatcheries, the early stage on-land part of production, are full of labor intensive workflows that are perfect candidates for automation. Farmers need to measure their stock for feeding, breeding, and harvest decisions but fish are underwater and get stressed when handled. Most farms still sample manually. They net a few dozen fish, anesthetize them, place them on a table to measure one by one, and extrapolate to populations of hundreds of thousands. It takes about 5 minutes per fish and the data is sparse. When we saw this process we were ba