Skip to content

Add interface for Dbus MPRIS and MacOS MediaPlayer - #15754

Open
acolombier wants to merge 108 commits into
mixxxdj:mainfrom
acolombier:feat/mpris
Open

Add interface for Dbus MPRIS and MacOS MediaPlayer#15754
acolombier wants to merge 108 commits into
mixxxdj:mainfrom
acolombier:feat/mpris

Conversation

@acolombier

@acolombier acolombier commented Dec 15, 2025

Copy link
Copy Markdown
Member

This PR aims to unblock the situation with #3483 and the sheer size of change that could not be reviewed.

This is a rebase of #3483 with two additional commits:

No change was made to the interface, in order to easily bring on the NowPlaying.txt and Listenbrains in future efforts, with a minimum amount of changes.

It also contains a squash-merge of #4809, as well as a commit to integrate this in the same API. Of course, this can easily be moved as a subsequent PR if we think this is still too big.

Screencast.From.2025-12-15.18-01-43.mp4
Screenshot From 2025-12-16 00-55-25

@JoergAtGithub

Copy link
Copy Markdown
Member

This PR needs testing on macOS and Linux

@l-2-j

l-2-j commented Jan 25, 2026

Copy link
Copy Markdown

I'm grateful for this PR, as I've been planning a small set that syncs up some visuals to songs, and thus needs a way to extract the songs & playback positions from Mixxx.

On Linux, the GUI hitches at times. Seems like it's related to the cover art. Observed after the short GUI freezes that playerctl metadata reports mixxx mpris:artUrl as something different, and matches up with song play/pause or fading... Edit, confirmed that, adding an early return to MprisPlayer::requestCoverArtUrl in my testing fork made the hitching disappear.

I personally would also love if this also added the url to the metadata as well, to make achieving my song-to-visuals mappings easier. I am not a C++ dev, but something like this? 😅

@acolombier

Copy link
Copy Markdown
Member Author

Thanks for your testing and feedback! I will try to incorporate the code change in this PR ASAP. If you have a MacOS machine or know somebody that does, some feedback there would also be greatly appreciated :D

@l-2-j

l-2-j commented Jan 26, 2026

Copy link
Copy Markdown

Sadly I don't have nor know MacOS users 😅 Thought I'd leave an additional comment though since I noticed that it's possible to get the volume meters to red and still not have the song picked up into MPRIS. Found this out with a badly normalized (multistem) audio file (that even the max 30LUFS/-12DB of normalization couldn't save peaking off of the waveform), and compensating for it with setting the deck specific gain very low. I guess this is more of "user error" than a major logic issue though 😛

@acolombier

Copy link
Copy Markdown
Member Author

I noticed that it's possible to get the volume meters to red and still not have the song picked up into MPRIS

The current logic is to check periodically if there is a track "audible", that is, above a certain threshold. The threshold is defined here and the period there. Could you please check in your fork if adjusting any of these value gives you better result? I guess we could expose these settings in the parameters!

@acolombier

Copy link
Copy Markdown
Member Author

On Linux, the GUI hitches at times. Seems like it's related to the cover art. Observed after the short GUI freezes that playerctl metadata reports mixxx mpris:artUrl as something different, and matches up with song play/pause or fading

Indeed, the coverart file operation was happening in the main thread. This has now been moved in the threadpool instead.
A note to reviewers, I believe there is no need for locks in MprisPlayer::requestCoverArtUrl, where the QFuture is used, but a second pair of eyes would help.

I personally would also love if this also added the url to the metadata as well

Good shout - should be there now!

@acolombier
acolombier force-pushed the feat/mpris branch 2 times, most recently from 5a2dfc8 to ced8a45 Compare February 9, 2026 09:03
acolombier and others added 3 commits February 9, 2026 23:11
    - Stub out MacOSMediaPlayerService
    - Broadcast now playing info to MPNowPlayingInfoCenter
    - Wire up MacOSMediaPlayerService
    - Remove unused dependency
    - Set now playing playback state
    - Define __MACOS_MEDIAPLAYER__ publicly
    - Set asset URL and media type for now playing
    - Set some dummy values for playback rate and time
    - Set MPNowPlayingInfoPropertyIsLiveStream
    - Register play command in MPRemoteCommandCenter
    - Successfully load cover art asynchronously to macOS media player
    - Handle case where broadcasted track is null
    - Add moc include
    - Use new CoverArtCache API
@acolombier

Copy link
Copy Markdown
Member Author

@daschuer do you still have interest in reviewing this? I will take the freedom to close the two superseded PRs.

@l-2-j

l-2-j commented Feb 25, 2026

Copy link
Copy Markdown

The threshold is defined here and the period there. Could you please check in your fork if adjusting any of these value gives you better result?

I already tried adjusting the threshold before to differing values with seemingly no effect, but I'll try more thoroughly tweaking it and the period too when I have the time to rebase and such…

Indeed, the coverart file operation was happening in the main thread. This has now been moved in the threadpool instead.

I can still observe similar UI freezing as before sadly.

Probably not super common to have this kind of big cover images, ffprobe reports the almost second freezes with as Stream #0:5[0x0]: Video: mjpeg (Baseline), yuvj420p(pc, bt470bg/unknown/unknown), 3000x3000 [SAR 1:1 DAR 1:1], 90k tbr, 90k tbn (attached pic), aka a 3000x3000 ~308KiB jpg when extracted with ffmpeg. Though did notice to a lesser extent with a 1271x1271 cover as well.
I have /tmp as a tmpfs (=stored in memory) too so not like the file write should take that long either…
Guess I'll continue stubbing that out in my fork for now, as I personally have no use for the thumbnails from MPRIS right now 😆

should be there now!

Yup, thank you! Now with proper URL encoding too which I had forgotten about ([x]%5D in the filename turned into %5Bx%5D%255D in the URI, breaking my small project POC 😆 )

@acolombier

acolombier commented Feb 25, 2026

Copy link
Copy Markdown
Member Author

I can still observe similar UI freezing as before sadly.

Not entirely sure what his happening - there could be an issue somewhere else with DBus. It is worth to say that I have only rebased the existing work that was done, so there could be something else causing this freeze, but since I cannot reproduce it, it is hard to guess... Perhaps other core member will be able to spot it when testing it and help catching it?

Now with proper URL encoding too which I had forgotten about ([x]%5D in the filename turned into %5Bx%5D%255D in the URI

From what I can understand from the (quite light) MPRIS spec, this field is expected to be a URL, and thus the encoding as it is currently is expected, and your consumer project should decode the URI.
Do you have reference that may suggest otherwise regarding the format of this URI?
image

@acolombier

Copy link
Copy Markdown
Member Author

@mixxxdj/developers this PR is easily catching conflict, so let me know when you have the bandwidth to start reviewing/testing it and I will resolve them.

@JoergAtGithub

Copy link
Copy Markdown
Member

To be honest, I think it's unlikely that this PR will be merged. Not because of the code itself, but because this PR contains two complex platform-specific features - for two different platforms.
The complex interaction with two third-party systems requires intensive testing on macOS and Linux - it's not very likely that you'll find a reviewer who will test both.
And despite that, 3000 lines of code is too much for a single PR.

@acolombier

Copy link
Copy Markdown
Member Author

And despite that, 3000 lines of code is too much for a single PR.

As you can see in the PR description, I spent a significant amount of effort recovering the exact history of #3483! This means the only change in this PR is related to the last commit, which address the change request in the superseded PR. The only thing to review here is

image

Now, if you think I should move the last two commits from MacOS support in a subsequent PR, I can do that too, I just would like to stop spending time and effort if nobody is going to help me delivering this long outstanding feature.

@ywwg

ywwg commented Feb 26, 2026

Copy link
Copy Markdown
Member

I think the best way to split up this PR would be these four chunks:

  1. refactors in existing mixxx code required by the new components (autodj idle, etc)
  2. generic new code needed by the new components (scrobbling stuff?)
  3. macos service
  4. mpris service

the way I do this is cherrypicking files from the giant change into a fresh branch.

Can you resolve the merge conflicts first, though?

@acolombier

Copy link
Copy Markdown
Member Author

I don't have interest to break down the code I have written in a first place, so except if we can agree on merging 1) and 2), I don't think it is worth spending any further effort here.

@ywwg

ywwg commented Feb 27, 2026

Copy link
Copy Markdown
Member

why not fix the conflicts first and I'll take a look at it

// playerPositionChanged for deck1 after the track is loaded.
m_eState = ADJ_ENABLE_P1LOADED;

m_idleState.set(false);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assuming m_idleState is supposed to mirror m_eState, it's brittle to make it a separate value because they could get out of sync. Instead, better to make m_eState a controlobject that gets set to the appropriate enum value, and then whatever other part of this needs to know about idle state can just look for that value of m_eState.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not entirely sure, these are elements I have taken from the original PR, my only change was to get rid of the pointer, to align with the refactor that was done to remove the fat pointers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants