Waavform

An open-source SwiftUI audio player. One line gives you a working player, and the waveform itself is the scrubber.

Client
Open source
Role
Design and engineering
Year
2024
The Waavform player on iPhone in landscape: a full-width audio waveform with the played portion filled dark, a blue playhead, current time and duration labels, and play/stop controls

The premise

Waavform is a waveform audio player for SwiftUI, published as an open-source Swift package. SwiftUI ships nothing like it, so the alternatives are AVPlayer behind a progress bar that says nothing about the audio, or days of custom rendering for what most apps treat as a minor element.

It’s a component rather than a product. That’s why it’s here: the interface and the API are equally important surfaces. It has to work in one line for someone who wants a sensible default, and bend to the pixel for someone matching a design system.

One line is the API

Waavform(audio: "TheMoon", type: "mp3")

That is a working player: waveform, transport, timecode, view switching. Every other parameter is optional and named, so configuration deepens as you go instead of demanding decisions up front. The default is the product.

The waveform is the interface

There is no separate progress bar. Played audio fills in the progress colour, unplayed audio sits behind it, and the boundary between them is the playhead: one element is the display, the position and the control. It also means you can see the quiet part coming. The current time rides the playhead rather than parking in a timecode row, so the number sits on the thing it describes.

The Waavform player during playback: the filled portion of the waveform grows as the playhead advances and the current-time label travels with it

The filled region and the time label are one mechanism. There is nothing to keep in sync.

Linear and scroll

The same waveform renders two ways, and the difference is what moves. Linear fits the whole file to the view width and animates the playhead across it: the drawing holds still, the marker travels. Scroll pins the playhead at the centre and animates the waveform underneath it: the marker holds still, the drawing travels.

What follows from that is how much audio is on screen. Linear puts a five minute track in a phone width, about a third of a second in every pixel, so single hits collapse into the line. Scroll holds a window around the current position at higher magnification, so that detail has pixels to occupy and everything outside the window is off screen.

The toggle is labelled with its destination, not its current state: linear shows a Scroll button, scroll shows a Linear one. It says what pressing it will do, so you never have to work out which view you are in first.

The Waavform player in scroll view on a dark background: the waveform slides past a red playhead fixed mid-screen, the played audio behind it dimmed grey and the audio ahead of it in white, while the time label riding the playhead advances from 01:55 to 01:57 against a 05:05 duration and the corner toggle reads Linear

Scroll view during playback. The waveform moves, the playhead does not, and the toggle in the corner reads Linear.

A Waavform player titled “The Moon” by Uberkazoo, stopped at 00:00 with a grey unplayed waveform, play and stop buttons, and a Scroll toggleA Waavform player titled “Body High” by Floydwhoelse, paused at 02:19 with the played portion filled blue against a grey remainder, and a Scroll toggleA Waavform player titled “Blue Goo” by GLotus in scroll view at 00:03, the playhead fixed mid-waveform, with a Linear toggle
Two players in linear, one in scroll, each with its own state and colour. The component composes rather than assuming it owns the screen.

Technology

  • Swift and SwiftUI, distributed as a Swift Package Manager package for iOS
  • One view with defaulted parameters as the entire public surface

Where it landed

Published as a Swift package in January 2024. A couple of dozen stars and a handful of forks, which is what a focused component in a narrow niche looks like. I’d rather say that than dress it up.