forked from
tokono.ma/diffuse
A music player that connects to your cloud/distributed storage.
1---
2layout: layouts/diffuse.vto
3base: ../
4title: Elements | Diffuse
5
6styles:
7 - styles/base.css
8 - styles/diffuse/page.css
9 - vendor/@phosphor-icons/web/bold/style.css
10 - vendor/@phosphor-icons/web/fill/style.css
11
12# ELEMENTS
13
14artwork:
15 - url: "components/artwork/audio-metadata/element.js"
16 title: "Audio Metadata"
17 desc: "Extracts embedded artwork from audio files using the music-metadata library."
18 - url: "components/artwork/last.fm/element.js"
19 title: "Last.fm"
20 desc: "Fetches cover art from the Last.fm API using track artist and album tags."
21 - url: "components/artwork/musicbrainz/element.js"
22 title: "MusicBrainz"
23 desc: "Fetches cover art from MusicBrainz and the Cover Art Archive using track artist and album tags."
24
25configurators:
26 - url: "components/configurator/artwork/element.js"
27 title: "Artwork"
28 desc: "Takes artwork components as children and tries each in sequence, returning the first non-null result."
29 - url: "components/configurator/input/element.js"
30 title: "Input"
31 desc: "Allows for multiple inputs to be used at once."
32 - url: "components/configurator/metadata/element.js"
33 title: "Metadata"
34 desc: "Takes metadata components as children and chains their patches in sequence."
35 - url: "components/configurator/output/element.js"
36 title: "Output"
37 desc: "Enables the user to configure a specific output. If no default output is set, it creates a temporary session by storing everything in memory."
38 - url: "components/configurator/scrobbles/element.js"
39 title: "Scrobbles"
40 desc: "Configure multiple scrobblers (music trackers)."
41
42engines:
43 - url: "components/engine/audio/element.js"
44 title: "Audio"
45 desc: "Plays audio through audio elements."
46 - url: "components/engine/queue/element.js"
47 title: "Queue"
48 desc: "A queue for tracks."
49 - url: "components/engine/repeat-shuffle/element.js"
50 title: "Repeat & Shuffle"
51 desc: "Signals synced with local storage (classified by group) that decide if audio should be repeated and if the queue should be shuffled when filling it."
52 - url: "components/engine/scope/element.js"
53 title: "Scope"
54 desc: >
55 Signals that could influence the scope of a set of tracks.
56
57input:
58 - url: "components/input/dropbox/element.js"
59 title: "Dropbox"
60 desc: >
61 Audio files from Dropbox, using the Dropbox v2 HTTP API.
62 - url: "components/input/https/element.js"
63 title: "HTTPS"
64 desc: >
65 HTTPS URLs to audio files or streams.
66 - title: "HTTPS (JSON)"
67 desc: >
68 Generate tracks based on HTTPS servers that provide JSON (directory) listings.
69 todo: true
70 - url: "components/input/icecast/element.js"
71 title: "Icecast"
72 desc: >
73 Icecast internet radio streams. Fetches ICY metadata to populate track information.
74 - url: "components/input/local/element.js"
75 title: "Local"
76 desc: >
77 Audio files or directories from your local device, using the browser's File System Access API.
78 - url: "components/input/opensubsonic/element.js"
79 title: "Opensubsonic"
80 desc: >
81 Add any (open)subsonic server.
82 - url: "components/input/s3/element.js"
83 title: "S3"
84 desc: >
85 AWS S3 and services that provide the same surface API such as Cloudflare R2.
86 - title: "WebDAV"
87 desc: >
88 Add any WebDAV server.
89 todo: true
90
91orchestrators:
92 - url: "components/orchestrator/auto-queue/element.js"
93 title: "Automatic Queue"
94 desc: >
95 Fill the queue automatically with non-manual items (shuffled or regular, based on repeat-shuffle engine).
96 - url: "components/orchestrator/favourites/element.js"
97 title: "Favourites"
98 desc: >
99 Mark tracks as favourites. Automatically creates an unordered 'Favourites' playlist.
100 - url: "components/orchestrator/input/element.js"
101 title: "Input"
102 desc: "**A default input configuration.** Contains all the inputs provided here."
103 - url: "components/orchestrator/media-session/element.js"
104 title: "Media Session"
105 desc: "Keeps the browser/os media session in sync with queue and audio state. Adds handlers for previous, next, seek to, etc."
106 - url: "components/orchestrator/offline/element.js"
107 title: "Offline"
108 desc: "Registers a service worker that makes the page available offline. Resources (except audio & video) are cached as they load and served from cache when offline."
109 - url: "components/orchestrator/output/element.js"
110 title: "Output"
111 desc: "**A default output configuration.** Contains all the outputs provided here along with the relevant transformers."
112 - url: "components/orchestrator/path-collections/element.js"
113 title: "Path Collections"
114 desc: "Wraps an output element to generate ephemeral playlists based on the first path segment of each track's URI. Ephemeral items are excluded from storage."
115 - url: "components/orchestrator/process-tracks/element.js"
116 title: "Process Inputs Into Tracks"
117 desc: "Whenever the cached tracks are initially loaded through the passed output element it will 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."
118 - url: "components/orchestrator/queue-audio/element.js"
119 title: "Queue ⭤ Audio"
120 desc: "Connects the given queue engine to the given audio engine."
121 - url: "components/orchestrator/scrobble-audio/element.js"
122 title: "Scrobble ⭤ Audio"
123 desc: "Connects the audio engine with a scrobbler element. Calls `nowPlaying` when a track starts playing and `scrobble` once the user has listened long enough."
124 - url: "components/orchestrator/sources/element.js"
125 title: "Sources"
126 desc: "Monitor tracks from the given output to form a list of sources based on the input's sources return value."
127 - url: "components/orchestrator/artwork/element.js"
128 title: "Artwork"
129 desc: "Fetches cover art for a given set of tracks, stored locally in indexedDB. Uses the artwork configurator to try each configured source in sequence."
130 - url: "components/orchestrator/scoped-tracks/element.js"
131 title: "Scoped Tracks"
132 desc: "Watches the given output's tracks collection and runs them through a built-in search index. Can perform a search and other ways to reduce the scope of tracks based on the given scope engine. Provides a `tracks` signal similar to `output.tracks.collection`"
133
134output:
135 - url: "components/output/polymorphic/indexed-db/element.js"
136 title: "Polymorphic / IndexedDB"
137 desc: "Stores output into the local indexedDB. Supports any type of data that indexedDB supports."
138 - url: "components/output/bytes/s3/element.js"
139 title: "Bytes / S3"
140 desc: >
141 Store output data on AWS S3 or compatible services such as Cloudflare R2.
142 - url: "components/output/raw/atproto/element.js"
143 title: "Raw / AT Protocol"
144 desc: >
145 Store your user data on the storage associated with your ATProtocol identity. Data is lexicon shaped by default so this element takes in that data directly without any transformations.
146
147metadata:
148 - url: "components/metadata/audio-file/element.js"
149 title: "Audio File"
150 desc: "Extracts tags and audio stats from audio files using the music-metadata library."
151
152supplements:
153 - url: "components/supplement/last.fm/element.js"
154 title: "Last.fm Scrobbler"
155 - title: "ListenBrainz Scrobbler"
156 todo: true
157 - title: "Rocksky Scrobbler"
158 todo: true
159 - title: "Teal.fm Scrobbler"
160 todo: true
161
162transformers:
163 - title: "Output / Bytes / Automerge"
164 desc: "Translate data to and from an Automerge CRDT."
165 url: "components/transformer/output/bytes/automerge/element.js"
166 todo: true
167 - title: "Output / Bytes / Cambria Lenses"
168 desc: "Uses the Cambria library to seamlessly translate between data schemas so that no data migration is needed."
169 todo: true
170 - title: "Output / Bytes / DASL Sync"
171 desc: "Syncs data between local and remote using CID-based diffing and performs union merges with tombstone tracking when both sides have diverged."
172 url: "components/transformer/output/bytes/dasl-sync/element.js"
173 - title: "Output / Bytes / JSON"
174 desc: "Raw data schema output ⇄ JSON Uint8Array."
175 url: "components/transformer/output/bytes/json/element.js"
176 - title: "Output / Raw / AT Protocol Sync"
177 desc: "Wraps an AT Protocol output with a local IndexedDB cache. Uses the repo revision to skip unnecessary fetches and performs union merges with tombstone tracking when both local and remote have diverged."
178 url: "components/transformer/output/raw/atproto-sync/element.js"
179 - title: "Output / Refiner / Default"
180 desc: "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.**"
181 url: "components/transformer/output/refiner/default/element.js"
182 - title: "Output / Refiner / Track URI Passkey"
183 desc: "Encrypts track URIs using a passkey-derived PRF key. On read, decrypts `encrypted://` URIs transparently; on write, re-encrypts all URIs before passing downstream. Tracks that cannot be decrypted are held separately and excluded from the visible collection."
184 url: "components/transformer/output/refiner/passkey-encryption/element.js"
185 - title: "Output / String / JSON"
186 desc: "Raw data schema output ⇄ JSON UTF8 string."
187 url: "components/transformer/output/string/json/element.js"
188
189# DEFINITIONS
190
191definitions:
192 - title: "Output / Collaboration"
193 desc: >
194 Represents a collaboration between multiple collaborators on a subject, such as a playlist.
195 url: "definitions/output/collaboration.json"
196 - title: "Output / Facet"
197 desc: >
198 Facet pointer or HTML snippet.
199 url: "definitions/output/facet.json"
200 - title: "Output / Playlist Item"
201 desc: >
202 Represents a single item in a playlist. Tracks are matched based on the given criteria. A playlist is formed by grouping items by their playlist property.
203 url: "definitions/output/playlistItem.json"
204 - title: "Output / Progress"
205 desc: >
206 Used to track progress of (long) audio playback.
207 todo: true
208 - title: "Output / Track"
209 desc: >
210 Represents audio that can be played, or a placeholder for a source of tracks. Contains a URI that will resolve to the audio.
211 url: "definitions/output/track.json"
212 - title: "Output / Track Bundle"
213 desc: >
214 A bundle of tracks.
215 url: "definitions/output/trackBundle.json"
216
217---
218
219<header>
220 <div>
221 <div class="diffuse-logo-container">
222 <a href="./" style="display: inline-block;">
223 {{ await comp.diffuse.logo() }}
224 </a>
225 {{ await comp.diffuse.status() }}
226 </div>
227 <p class="construct dither-mask">
228 Elements
229 </p>
230 <p>
231 Diffuse was built using these web components, consume these using the <a href="../code/">code tool</a>, the Javascript <a href="https://jsr.io/@toko/diffuse">package</a>, or the linked Javascript files down below.
232 </p>
233 <ul class="table-of-contents">
234 <li><a href="elements/#artwork">Artwork</a></li>
235 <li><a href="elements/#configurators">Configurators</a></li>
236 <li><a href="elements/#engines">Engines</a></li>
237 <li><a href="elements/#input">Input</a></li>
238 <li><a href="elements/#metadata">Metadata</a></li>
239 <li><a href="elements/#orchestrators">Orchestrators</a></li>
240 <li><a href="elements/#output">Output</a></li>
241 <li><a href="elements/#supplements">Supplements</a></li>
242 <li><a href="elements/#transformers">Transformers</a></li>
243 <!---->
244 <li style="margin-top: var(--space-xs);"><a href="#definitions">Definitions</a></li>
245 </ul>
246 </div>
247 <div class="dither-mask filler"></div>
248</header>
249<main>
250 <!-- ELEMENTS -->
251 <section>
252 <div class="columns">
253 {{ await comp.element({
254 title: "Artwork",
255 items: artwork,
256 content: `
257 Elements that provide artwork for tracks.
258 `
259 }) }}
260
261 {{ await comp.element({
262 title: "Configurators",
263 items: configurators,
264 content: `
265 Intermediates 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.
266 `
267 }) }}
268
269 {{ await comp.element({
270 title: "Engines",
271 items: engines,
272 content: `
273 Elements with each a singular purpose. There are orchestrator elements that control these.
274 `
275 }) }}
276
277 {{ await comp.element({
278 title: "Input",
279 items: input,
280 content: `
281 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.
282 `
283 }) }}
284
285 {{ await comp.element({
286 title: "Metadata",
287 items: metadata,
288 content: `
289 Elements that provide metadata for tracks.
290 `
291 }) }}
292
293 {{ await comp.element({
294 title: "Orchestrators",
295 items: orchestrators,
296 content: `
297 These are element compositions, logic only. Mostly exist in order to construct sensible defaults.
298 `
299 }) }}
300
301 {{ await comp.element({
302 title: "Output",
303 items: output,
304 content: `
305 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.
306 `
307 }) }}
308
309 {{ await comp.element({
310 title: "Supplements",
311 items: supplements,
312 content: `
313 Additional elements, such as scrobblers.
314 `
315 }) }}
316
317 {{ await comp.element({
318 title: "Transformers",
319 items: transformers,
320 content: `
321 Transform data from one format or schema into another. See the definitions 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.
322 `
323 }) }}
324 </div>
325 </section>
326
327 <!-- DEFINITIONS -->
328 <section>
329 <h2 id="definitions" style="color: var(--accent)">Definitions</h2>
330
331 <p>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, if needed.</p>
332
333 {{ await comp.list({ items: definitions }) }}
334 </section>
335</main>
336
337<script type="module">
338 import { versionUpgrade } from "./common/pages/version-upgrade.js";
339 versionUpgrade();
340</script>