jmshrv / finamp

A Jellyfin music client for mobile
Mozilla Public License 2.0
1.7k stars 121 forks source link

[Feature Request] Implement "Play on" compatibility with the Jellyfin web client #616

Open pinsarda opened 4 months ago

pinsarda commented 4 months ago

The official Jellyfin client has a "Play on" feature (in the top right corner with the cast icon, next to syncplay). It allows to control the session remotely from an other client connected to the same account. Spotify and Deezer have an equivalent (named "Spotify Connect" for spotify, don't know for deeser) While not an essential feature it can be very useful in certain setups such as home theaters, or to remote control a jellyfin music client running on a steam deck for instance.

For the technical part, I couldn't find any reference to the feature in the jellyfin api doc after a (arguably very quick) search, so I hope it is implemented on the server side and is not too much tied to the official client itself. I think the best course of action would be to look at the code from the official client before deciding on the right way to do it.

Obviously this is not very high priority, but if possible it would be super neat to have. And it would be even better if we could get this implemented in feishin as well.

pinsarda commented 2 months ago

Hi ! Since I had my week-end off, I digged a bit deeper into this. As I hoped every endpoint is accessible through the api, and the implementation is easier than expected on the server front. I already have most of the needed functions implemented and working in a small python script.
I would like to contribute by implementing this into finamp, however it would be my first ever code contribution so I need guidance and patience, especially on a not well known codebase and technology. If that's fine with you, I'd be glad to help :)

Design :

I suggest adding a button on the left of the queue (in symmetry with the lyrics button). Once clicked it would open a selection popup with the available sessions. From there it would work like spotify and deezer. We could also add an option to default to remote session control if one is detected on startup.

Code :

Controlling the remote session would be the easy part. Simply swapping the audioHandler from a MusicPlayerBackgroundTask to a new class reimplementing the functions for remote playback seems pretty straightforward with minimal change to the codebase. (We only need variables with the remote session id and a trigger boolean that would work like any other setting)
However we also need to update the UI when change is being made on the remote session. I guess we can put the websocket inside the new audioHandler and swap the ProgressState in the ProgressSlider with a new one ? Also would we keep the audioHandler in the background to trigger a music change when called by the server, or would it need to be separated into an other script ?

I am confident I can get this working, but I will definitely need help refactoring the code to do it the right way.
Let me know if you are interested so I can start prototyping and open a draft.

Chaphasilor commented 2 months ago

Hi, thanks for taking the time to look into this!

In principle I'd love to have Finamp be able to control remote sessions and be controlled itself. However, I'm not so sure if this really will be as easy to implement as you assume, especially to do it right and without breaking existing functionality.

I'd definitely suggest we implement the two parts ( a) being remote controllable, and b) controlling other clients) in two steps, possibly in two separate PRs. Starting with making Finamp remote-controllable is probably the easier thing to implement for now, but I'm not sure if this is the part that you are interested in yourself.

One thing to keep in mind with Finamp is that keeping a websocket connection open in the background at all times isn't a great idea when it comes to battery life, and might be hard to pull off too.

Regarding the UI, I agree with your idea, the placement is also what I had already planned. However, the current plan was to put some kind of output selector there, that offers both a volume control (requested in #500), and contains cast functionality (like the AirPlay button and a ChromeCast button). But this panel could then also show available remote clients (both Jellyfin clients and DLNA receivers).
I can definitely create a mockup for the UI or even handle the implementation myself.

Let me know how you'd like to proceed!

pinsarda commented 2 months ago

I agree and am aware that it is not an easy task, and will probably take a long time before being ready to land in the redesign. I will have time to get this done eventually, even if it has to take several dozens hours over a few months.

Indeed I was more focused on using jellyfin for controlling my pc rather than the other way around, but it should need about the same code to get it working so I am ok implementing remote-controllability first. But I don't know what to use apart from a websocket, this is the way the web client handles it and afaik how similar features are achieved in general.

UI-wise what you are proposing seems totally good to me, as well as doing it with two separate PRs

Chaphasilor commented 2 months ago

The reason I suggested starting with controlling Finamp is because it doesn't need any UI at all, and also needs no major changes to the playback logic, just the websocket + a handler that invokes methods on the audio handler (music_player_background_task).

The websocket will eventually be also used for other features, so it should be kept as generic as reasonble.

We can look into how to manage the WS connection (i.e. when to keep it active, adding settings to control it, etc.) later on, once the basic functionality works.

Feel free to open a draft PR and let me know if you have any issues!

LeoSum8 commented 3 weeks ago

Remote control would really be great to control music playback on the stereo system (via mopidy and snapcast) from the phone.

Currently I use Finamp only for listening on the go (also due to its offline functionality) and at home I use the official jellyfin app due to its remote control function.

I'd prefer only using Finamp :)