Diffuse

Construct your audio player.

Diffuse is a collection of components and software that make it possible to listen to audio from various sources on your devices and the web, and to create the ideal digital audio listening experience for you.

⚠️ HEAVILY EXPERIMENTAL

Built by tokono.ma

Usage

The easiest way to start is by exploring the software. If you prefer a traditional pre­packaged web application approach, you can check out themes.

Alternatively, there's constituents which allows you to use any component from any theme interchange­ably, each in a separate browser tab. Each tab talks to each other, so you can for example browse in one tab and play it in another.

If you're a programmer, you can compose the elements listed below to make your own theme. Easily build software by connecting various elements.

NOTE: I'd like there to be a way to compose your own theme without having to write code. Hopefully sometime in the future.

Demo

Diffuse is not your typical streaming service, you have to add sources of audio. This button here adds a few sample audio files from a S3 bucket.

TODO: Implement button

Next, select any theme from below to play the audio. Or any of the other options suggested in the usage section.

NOTE: The items are added to the default "IndexedDB" output, so make sure that output is configured.

Themes

Themes are element compositions and provide a traditional browser web application way of using them. In other words, pretty much the whole thing, besides your data, lives inside a single browser tab.

NOTE: Each theme is unique, not just a skin. For example, most themes here will limit the currently playing audio tracks to one item, but you might as well create a DJ theme that can play multiple items at the same time.

  • [todo] Blur
    A DJ theme with an Apple-inspired playback view. Features two audio players instead of the usual one.
  • Webamp
    Winamp 2 + Windows 98. Uses Webamp as the audio player connected to various Diffuse elements. Also features a desktop-like Windows 98 environment in which you can open "programs" that control the used Diffuse elements.

Constituents

TODO: Explain constituents.

Elements

The (web) components of the system. These custom elements are then recombined into an entire music player experience, or whatever you want to build.

Configurators

Elements that serve as an intermediate in order to make a particular kind of element configurable. In other words, these allow for an element to be swapped out with another that takes the same set of the actions and data output.

  • Input
    Allows for multiple inputs to be used at once.
  • Output
    Enables the user to configure a specific output. If no default output is set, it creates a temporary session by storing everything in memory.
  • [todo] Scrobbles
    Configure multiple scrobblers (music trackers).

Engines

Elements with each a singular purpose and don't have any UI. There are specialised UI and orchestrator elements that control these.

  • Audio
    Plays audio through audio elements.
  • Queue
    A simple queue for tracks.

Input

Inputs are sources of audio tracks. Each track is an entry in the list of possible items to play. These can be files or streams, static or dynamic.

  • Opensubsonic
    Add any (open)subsonic server.
  • S3
    AWS S3 and services that provide the same surface API such as Cloudflare R2.

Orchestrators

These too are element compositions. However, unlike themes, these are purely logical. Mostly exist in order to construct sensible defaults to use across themes and other compositions.

  • Process inputs into tracks
    Whenever the cached tracks are initially loaded through the passed output element it will contextualize and then list tracks by using the passed input element. Afterwards it loops over all tracks and checks if metadata needs to be fetched. If anything has changed, it'll pass the results to the output element.
  • Queue ⭤ Audio
    Connects the given queue engine to the given audio engine.
  • Queue ⭤ Tracks
    Sets the given queue element pool whenever the tracks signal from the given output changes.
  • Search ⭤ Tracks
    Supplies tracks to the given search processor whenever the tracks collection changes.

Output

Output is application-derived data such as playlists. These elements can receive such data and keep it around. These are categorised by the type of data they ingest, or many types in the case of polymorphic. Optionally use transformers to convert output into the expected format.

  • Polymorphic / IndexedDB
    Stores output into the local indexedDB. Supports any type of data that indexedDB supports.

Processors

These elements work with the output generated by the input elements to add more data to them, or process them in some other way.

  • Artwork
    Fetches cover art for a given set of tracks, stored locally in indexedDB. Checks the audio metadata first, then MusicBrainz and uses Last.fm as the fallback.
  • Metadata
    Fetch audio metadata for a given set of tracks, adding to the Track object.
  • Search
    Provides a way to search through a collection of tracks, powered by orama.js

Supplements

Additional elements, such as scrobblers.

  • [todo] Last.fm scrobbler
  • [todo] ListenBrainz scrobbler
  • [todo] Rocksky scrobbler
  • [todo] Teal.fm scrobbler

Transformers

Transform data from one format or schema into another. See schema section below for more information. Just as configurators, these are intermediates and require to have the same set of actions as the element it targets.

  • [todo] Output / Bytes / Cambria lenses
    Uses the Cambria library to seamlessly translate between data schemas so that no data migration is needed.
  • [todo] Output / Bytes / JSON
    Raw data schema output ⇄ JSON Uint8Array.
  • Output / Refiner / Default
    The task of a refiner transformer is to remove the output state that is not meant to be saved to storage. For example, ephemeral tracks; this transformer will keep them in memory, but they will not be present in the output. Ideally this is part of every theme, but you may swap it out with another transformer that might provide better defaults.
  • Output / String / JSON
    Raw data schema output ⇄ JSON UTF8 string.

Definitions

All of the elements here are built with these data definitions in mind. That said, you can mix elements that use different definitions; you just have to put a transformer between them in order to translate between them.

Code your own

TODO: Explain how to connect the various elements, publish packages, etc.