• Concept: Music Server / Music Server Protocol v2

    (Updates Concept: Cross-platform music playback daemon)

    Motivation: I’m trying to move away from Spotify, tired of renting my own playlists back month after month. So I’m paying for music downloads online (MP3s and FLACs) and ripping CDs, and generally moving to an old-is-new-again post-Spotify music workflow.

    As Linux is my primary desktop environment, I’m reacquainting myself with the Linux music playback ecosystem for the first time in a decade, more or less. While many of the projects I once relied on (hello, Amarok!) are still around, on the whole the field feels neglected. Even Spotify’s crappy client does get some things right, and usability standards have generally risen since my last outing. But open source offerings haven’t entirely kept up.

    I’m also struck by the lack of common infrastructure between projects. While low-level libraries are shared (e.g. libogg, libpulseaudio), the core file discovery, indexing, tag editing, playback, and playlist management functionality that music players rely on are cobbled together afresh by each project. (As well as transcoding, another common feature.)

    The duplication applies not only to desktop music players (Amarok, Rhythmbox, Clementine, cmus) but also to music servers such as Navidrome or mpd.

    Proposal: define an abstract music playback and management interface, the Music Server Protocol, and implement it definitively in musicd, a comprehensive music server, integrating with existing or newly-built clients.

    musicd could run incidentally (like a language server in the LSP world) or as a persistent daemon, and optionally expose a public network interface.

    The latter point, network transparency, allows such a system to be a true Spotify replacement, serving music to mobile apps from VPS or other servers.

    Multiuser support would be a useful feature, allowing friends and family to integrate their music collections; a lock-based rights management scheme could ensure that music licenses are treated as finite in the shared environment.

    Implementation: I would implement musicd in Rust, interfacing with the same libraries as the existing apps. If there’s a sufficiently-mature Rust codebase that already does what I need, I’d happily fork it. I’m insisting on Rust because I’m more familiar with it than with C++ these days, and because I’d prefer Rust’s rigors in what I hope would become a building-block for many projects.

  • Javascript, The Bad Parts #3: no negative array indexing 😾

    On the petty side—gets frowny cat, rather than horror cat. After a decade of Python, it’s surprising to me that Javascript doesn’t allow arr[-1] and such. Maybe negative indices returning undefined is widely relied upon, leading to compatibility issues? Not sure why it’s not a thing—arr[arr.length - 1] is just no fun.

  • Javascript, The Bad Parts #2: no custom comparisons in `Set` 🙀

    In Javascript, Set treats objects only by reference, not by value, requiring weird contortions to maintain unique sets of non-primitive values.

    In every other modern language I’ve worked with, the standard library set allows custom comparisons. But not Javascript.

    In Java / Kotlin, HashSet defers to an object’s hashCode method, which can be overridden to control comparisons. With TreeSet it’s even easier: just pass a Comparator of your own into the constructor.

    Python’s set will handle any hashable value, so overriding __hash__ and __eq__ should do the trick.

    Rust’s HashSet relies on the Eq, Hash, and PartialEq traits—conceptually somewhat similar to Python’s approach, with Rust’s trait implementations and Python’s special methods being two ways to accomplish much the same thing.

    But in Javascript, and by extension Typescript, the standard library provides no facility for useful sets of custom types.

    https://medium.com/coding-at-dawn/how-to-use-set-to-filter-unique-items-in-javascript-es6-196c55ce924b

  • Javascript: The Bad Parts #1

    No Array.prototype.remove (a la Array.prototype.filter) 😿

    You have to use splice based on an index instead. Would be much simpler to provide an item to be removed. The equivalent of arr.splice(arr.indexOf(item), 1).

    https://stackoverflow.com/questions/5767325/how-can-i-remove-a-specific-item-from-an-array

  • Concept: People

    A contact manager on steroids. Real social networks. A person or group view that shows all known interactions, notes/diary entries, etc.

    Desktop application, I hope.

  • Concept: Donation Daemon

    Set a weekly / monthly / annual donation level.

    Daemon monitors app usage, and distributes donations proportionally, possibly through a third party service.

  • Concept: Music Server / Music Server Protocol

    Identifies, indexes, and manages music files, and exposes them for playback via the Music Server Protocol.

    Difference from Concept: Music Player Daemon: the playback occurs on the client, not the server

    Differences from Navidrome: no built-in web interface; supports editing of tags.

    Differences from Subsonic API: supports tag editing; has a concept of permissions; mult-user; more efficient than XML (I hope).

    Differences from Plex: Music only.

    Jellyfin: architecture looks good, all open source, but it seems video-focused and like it would suck for managing music; also seems to be .net-based

    Totally novel API ?

    Requirements:

    • Scanning and discovery
    • Uploads
    • Permissions / users and ownership
    • Tag editing
    • Playlist building, names, images, descriptions
    • Reencoding / transcoding
    • Desktop and mobile client support
    • Low-bandwidth connection support
    • Gracefully handle albums, multi-artist albums, singles
    • Music only. No videos, no podcast-specific support.
    • Offline mode
  • Concept: Cross-platform music playback daemon

    Coming back to local Linux music playback, I’m pretty disappointed with the state of things. Spotify’s UI feels nice in comparison, which says something, given how neglected it seems. Things largely feel like 2016 or so. Every music player seems to solve the same problem using a totally new codebase, with only low-level libraries shared between them (reading MP3 or FLAC files, for example).

    I can’t be the first person to have this idea… but, do like neovim did for text editing, like the Language Server Protocol does for coding: split apart core music playback functionality in a UI-agnostic fashion, and let interfaces interact with it via a socket protocol or whatever the equivalent of that is nowadays. (D-bus? MessagePack? no idea)

    Handle the file formats, indexing, tag editing, output interfaces, notification of events, maybe interaction with online music repositories (e.g. FunkWhale)

  • Concept: The Projects Blog

    Like this document. But in the open. Allow for comments on my project ideas, refinement, collaboration, etc. to bring things to reality.

    this blog

  • Concept: Journaldom

    A system for transcribing and selectively exposing your old journals.

    Option: ship your journals to us, we use ML models to automatically transcribe and integrate everything.

    Allow people to select which pages / passages, which people, etc. they want to reveal, and to whom. Set minimum age (e.g. only release 20 year old entries or older)

    Automatic named entity recognition; similar to what photo services do with photos

    Q: How good is handwriting recognition getting?