Back in January, I gave a brief update about Jockey, the open-source music player that kickstarted my career as an Android developer. I specifically commented on how I was working on a full re-write and that I’d have more to share in the “coming months”.

Boy was I naieve in January.

To hold up my end of the bargain regardless, this is that update. If I were to wait any longer, then you’d have to measure this time period in terms of years, and I’m not a fan of breaking low-stakes promises. Technicalities aside, here is the foretold update on Jockey — and wow is it different from the one I expected to give.

In this blog post, I specifically want to talk about how things have been going, what’s been difficult, where Jockey stands today, and what’s to come.

How’s it going?

Good? I guess?

2020 has been… A year. To recap just at a high level: 2020 has seen events such as record wildfires in both Austrailia and California, the appearance of weird pillars in unusual places that ideally should have been named Carl, a large explosion in Beirut, the words “Murder” and “Hornet” being placed too close together for my tastes, a global health crisis, the highest voter turnout for a US presidential election in history, and one of the largest civil rights movements in recent years in the United States. That’s just to name a few things.

On a personal level, I have been extraordinarily lucky to be able to work from home throughout all of this and to be at a company that hasn’t had substantial layoffs. That said, the company that I work for, Big Nerd Ranch, has been acquired earlier this year and there have been some rough edges and mixed emotions throughout all of the associated process.

I won’t get into any more detail about any of this, but I think it’s important context. This year has been bad, but I am doing well.

What’s been difficult?

The problems that have slowed down Jockey are almost exclusively technical (Assuming, of course, that you exclude the lack of free time that’s associated with a full-time job).

To explain in more detail, I want to revisit a subtle detail from the update I gave in January. I said that I was calling the rewrite of Jockey “Jockey/Encore”.

Jockey/Encore is not one project. It’s two.

Jockey is the entire “app” part of the application. It’s the entire UI and integration of various components into a final product, and it’s generally what you’d think of when you think of Jockey.

Encore, however, is where things get interesting. Encore is a set of libraries designed to be drop-in implementations for apps that want to display and play an audio catalog. There are two parts here: The media library and the playback implementation.

Encore/Library

The library component of Encore has been the most challenging piece so far, which was actually pretty surprising to me. The goal of Encore’s library functionality is to expose a media provider interface that returns collections of playable media. You could use this to read from Android’s MediaStore (i.e. on-device files), a third party services like Soundcloud, a cloud solution like a file server, or some arbitrary combination of all of the above.

The challenging part to figuring out how to design this kind of library. The goal is straightforward, but you have to be considerate of the various applications. If you think about music-only, you’re thinking about songs, artists, albums, etc. But Encore should also be able to work with other media like podcasts or audiobooks.

It’s hard to design this kind of abstraction where you simultaneously want to be as specific as possible, but also need to support use-cases that might not be known yet. There have been two designs that I’ve attempted so far, and neither one has done a particularly great job of accurately abstracting these ideas while also being usable enough for the application itself. I expect to go through a few more revisions before I can land on a design I’m satisfied with.

It’s really important to get this right before getting too far, since the library component affects so much of the app. Any changes made to these APIs affect the whole application, so I’ve been reluctant on building out a wide feature set until this has been nailed down. That said, once the library APIs are in a good place, I expect that the rest of the app will start moving extremely quickly.

Encore/Player

The playback components are actually some of the most fleshed-out parts of the entire application. Virtually every basic playback feature has been built-out so far, and with enough modularity to support adding almost any new feature you could think of. Overall, I’m very happy with the flexibility, design, and usability of Encore’s playback capabilities.

There are still a couple of important behind-the-scenes features that I need to build out to fully validate the efficacy of this solution, but I’m not expecting drastic changes on this front. I anticipate that the next blogpost I write about Jockey will be about Encore’s playback library, because I’m very excited about it. I haven’t seen any other media playback implementation that looks like this, and I really think that it could become a go-to solution for people who want to build out media apps moving forward.

Jockey

Last, but most certainly not least, I want to talk about challenges on Jockey itself. Specifically the UI portion.

I’m using Jetpack Compose to build out Jockey’s entire UI, and it is a delight. Jetpack Compose really makes me loathe using Android’s native UI framework at my day job, and I mean that as a huge compliment.

That said, it’s not without its faults. Jetpack Compose is still rough around the edges, even after being promoted from Developer Preview to Alpha. There are still some missing components — specifically around Material Design — and the components aren’t always 100% ready for production use. I also spend a decent amount of time updating Compose, since many of its APIs are being shuffled, renamed, or otherwise tweaked while it’s in this stage. More frustratingly, the compiler still gets… creative… from time to time.

That said, I find Jetpack Compose to be amazing for rapid prototyping. I fully expect that the most commonly used features in Jockey are going to be insanely fast to build compared to the pre-Compose world, and I expect there to be fewer UI defects by the time that this build goes live for the first time.

Where does Jockey stand today?

At a high level, here’s a quick list of features that are currently implemented in the Jockey 4.0 rewrite:

  • 🎶 All songs page
  • 🔊 Media playback
  • ▶️ The “Now Playing” tab (Including swipe gesture!)
  • 🔀 Shuffle & Repeat
  • ⏭ Gapless playback
  • 🚙 Android Auto

For your viewing pleasure, I’ve also compiled a small gif of Jockey as it behaves at time of writing. Although it might not look like much, I really want to emphasize that there’s quite a lot happening on the media playback front. Not all of this effort is visible yet, but this upfront investment should make future feature development significantly faster and less error-prone.

What’s next?

Like I said earlier, I’m currently working on getting a final design in-place for Encore’s library APIs. Once that’s done, I’ll be able to start fleshing out other pages in the library, which will drastically improve the app’s feature-set. There’s also some themeing tweaks I want to make, since I haven’t invested too much in general aesthetics yet. Once all of this basic functionality is in place, I expect to make Jockey and Encore public, and publish the first alpha release of Jockey 4.0.

After Jockey and Encore are public, I’m going to focus on broadening the feature set to include more thourough navigation, equalizer support, and other minor details to bring Jockey and Encore up to speed with the legacy version of Jockey.

For now, I’m going to leave you with some concept art to give you a teaser of what to expect stylistically. None of these designs are final, but they should give you a good idea of what you can expect — specifically around app navigation.

Until next time! (Which hopefully won’t be 11 months from now)

Mockups of Jockey 4.0