More rambling about this streaming radio thing
I’ve been playing around with some protocol ideas and I have some more thoughts.
I’m thinking that feeds will primarily be provided in two forms: JSON, and html+mf2. Both of them will be intentionally flexible and a bit loosy-goosey, because there’s a lot of shapes this can take.
JSON
The JSON feed should be pretty straightforward. Each feed is either a single artist, or an array of artists. Each artist is a property bag with:
artist: The name of the artistartist-id: The MusicBrainz artist IDlinks: Useful links for interacting with the artist in a basic key/value store (the value being just a URL, or a propertybag withurlandiconproperties)images: Useful images for the artist’s information page (band photo, headshot, icon, etc.)releases: An array of releases
Each release contains:
titleurl: its representative webpagerelease-id: MusicBrainz release group/album ID (optional)stream: the URL for the audio media, if it’s a singleartistandartist-idif those need to override the artist-level properties for some reason (side projects, collaborations, one-offs, etc.)artworktracks: an array of tracks within the release, each of which contains:titleurltrack-id: MusicBrains track ID (optional)streamartist/artist-idas appropriate to override the releaseartworkto override the release
html+mf2
html+mf2 is basically “HTML, but with microformat data.” It’s a handy way of embedding structured data into an HTML document without requiring a sidecar or dealing with the wonkiness of inline JSON+LD or the like.
There’s an online mf2 parser which you can use to get a better idea of how the mf2 parsing libraries make sense of html+mf2 feeds; for example, here’s the html+mf2 radio feed as JSON.
The reason for wanting to support this is so that people can add an item directly into their players; for example, one should be able to just provide a link to Transitions and then the player should be able to get the metadata directly from it, with no need for there being a separate sidecar JSON file for everything.
The properties here should map to the JSON properties, for example:
p-namebecomestitleu-urlbecomesurlu-audiobecomesstreamu-photobecomesartworkp-uidbecomes the appropriate MusicBrainz ID for whatever the item represents, or maybe it gets e.g.p-artist-id,p-release-id,p-track-idso that inheritance is a lot more clear?
How things nest will be somewhat different than in the JSON thing. I’d think anything (h-entry/h-item) that has u-audio would be either a track (if it’s attached to an album) or a release (if it’s attached to an artist/feed), and any missing properties would inherit from the parent container.
The radio implementation
I’d expect that the radio implementation itself doesn’t actually care about the formatting of the individual feeds/items/etc., but that it would just recursively descend whatever the feed is and create artists/albums/tracks as appropriate, using metadata and canonical item URLs to try to coalesce them into single ground-truth things, and then would provide a nice browse experience that lets people add things to playlists, visit the original federated items, etc.
If someone adds a link to their personal streaming implementation, it would ingest whatever data is on the page as well as possibly discovering feeds from <link> tags, and the thing that’s added could also be marked as a private collection so that it isn’t made available to others on the platform (i.e. it’s someone’s collection of purchased music formatted as an ingestion feed). There’s no need for a private collection to have a different feed format than a public feed, but it’s super important to not make private collections' items available to other users of the platform, aside from basic metadata scrobbling.
On other projects people keep mentioning to me
I am aware of libre.fm, listenbrainz, and The Indie Beat. They’re all fine initatives, but their goals are somewhat different than mine here; they focus on the discovery and the “college radio station” aspect of Internet radio, while what I’m trying to build is a federated Spotify that isn’t controlled by any specific entity.
I would of course love The Indie Beat to support this style of federation, and there’s no reason there can’t be interop here. The goal is to have a simple protocol where anyone can federate their music listening in whatever way works best for them, and where the indie music sites (Mirlo, Bandwagon, Bandcamp, Faircamp, etc.) can provide opt-in streaming capability for this stuff as well, but doing it in a lightweight way that’s easy to join in on.
Much of this design has come from conversations I’ve had with the person behind Bandwagon and I need to resume those conversations.
I don’t think ActivityPub is a good model for this stuff, incidentally, and my understanding of the current content delivery pipeline for The Indie Beat is very push-based and requires what amounts to a peering agreement. I want the design to be more like blogs and podcasts, where people can just subscribe to anything that speaks the protocol, and that protocol should be dead simple to implement from a content provider’s standpoint. This isn’t for the world that formal agreements should be made between controlling parties.