Skip to content
This repository was archived by the owner on Mar 28, 2026. It is now read-only.

Commit 5a12a08

Browse files
authored
Merge pull request #989 from andrewrabert/mpris
MPRIS
2 parents 811ca84 + 00dfb70 commit 5a12a08

21 files changed

+2338
-34
lines changed

native/find-webclient.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ document.addEventListener('keydown', (e) => {
140140
(async () => {
141141
console.log('Auto-connect: starting');
142142

143+
await window.apiPromise;
144+
143145
const savedServer = window.jmpInfo.settings.main.userWebClient;
144146
console.log('Auto-connect: savedServer =', savedServer);
145147

native/jmpInputPlugin.js

Lines changed: 321 additions & 13 deletions
Large diffs are not rendered by default.

native/mpvAudioPlayer.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,10 @@ class mpvAudioPlayer {
262262
setPlaybackRate(value) {
263263
this._playRate = value;
264264
window.api.player.setPlaybackRate(value * 1000);
265+
266+
if (window.api && window.api.player) {
267+
window.api.player.notifyRateChange(value);
268+
}
265269
}
266270

267271
getPlaybackRate() {
@@ -348,4 +352,4 @@ function getSupportedFeatures() {
348352
}
349353

350354
window._mpvAudioPlayer = mpvAudioPlayer;
351-
})();
355+
})();

native/mpvVideoPlayer.js

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,20 @@
612612
return this._supportedFeatures.includes(feature);
613613
}
614614

615+
isFullscreen() {
616+
// Check native window fullscreen state
617+
if (window.jmpInfo && window.jmpInfo.settings && window.jmpInfo.settings.main) {
618+
return window.jmpInfo.settings.main.fullscreen === true;
619+
}
620+
return false;
621+
}
622+
623+
toggleFullscreen() {
624+
if (window.api && window.api.input) {
625+
window.api.input.executeActions(['host:fullscreen']);
626+
}
627+
}
628+
615629
// Save this for when playback stops, because querying the time at that point might return 0
616630
currentTime(val) {
617631
if (val != null) {
@@ -690,6 +704,10 @@
690704
let playSpeed = +value; //this comes as a string from player force int for now
691705
this._playRate = playSpeed;
692706
window.api.player.setPlaybackRate(playSpeed * 1000);
707+
708+
if (window.api && window.api.player) {
709+
window.api.player.notifyRateChange(playSpeed);
710+
}
693711
}
694712

695713
getPlaybackRate() {
@@ -879,22 +897,7 @@
879897
setAspectRatio(value) {
880898
window.jmpInfo.settings.video.aspect = value;
881899
}
882-
883-
isFullscreen() {
884-
// Check native window fullscreen state from settings (universal source of truth)
885-
if (window.jmpInfo && window.jmpInfo.settings && window.jmpInfo.settings.main) {
886-
return window.jmpInfo.settings.main.fullscreen === true;
887-
}
888-
return false;
889-
}
890-
891-
toggleFullscreen() {
892-
// Toggle native window fullscreen via host command
893-
if (window.api && window.api.input) {
894-
window.api.input.executeActions(['host:fullscreen']);
895-
}
896-
}
897-
}
900+
}
898901
/* eslint-enable indent */
899902

900903
window._mpvVideoPlayer = mpvVideoPlayer;

native/nativeshell.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,3 +554,23 @@ async function showSettingsModal() {
554554
});
555555
closeContainer.appendChild(close);
556556
}
557+
558+
let lastFullscreenState = window.jmpInfo.settings.main.fullscreen;
559+
560+
window.jmpInfo.settingsUpdate.push(function(section) {
561+
if (section === 'main') {
562+
const currentFullscreenState = window.jmpInfo.settings.main.fullscreen;
563+
if (currentFullscreenState !== lastFullscreenState) {
564+
lastFullscreenState = currentFullscreenState;
565+
566+
if (window.api && window.api.player) {
567+
window.api.player.notifyFullscreenChange(currentFullscreenState);
568+
console.log('Player fullscreen notified');
569+
}
570+
571+
if (window.Events && window.playbackManager && window.playbackManager._currentPlayer) {
572+
window.Events.trigger(window.playbackManager._currentPlayer, 'fullscreenchange');
573+
}
574+
}
575+
}
576+
});

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ add_subdirectory(system)
2222
add_subdirectory(settings)
2323
add_subdirectory(power)
2424
add_subdirectory(taskbar)
25+
add_subdirectory(mpris)
2526

2627
get_property(ALL_SRCS GLOBAL PROPERTY SRCS_LIST)
2728
set(MAIN_SRCS main.cpp)

src/core/ComponentManager.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "settings/SettingsComponent.h"
1414
#include "taskbar/TaskbarComponent.h"
1515
#include "ui/WindowManager.h"
16+
#include "mpris/MprisComponent.h"
1617

1718
#if KONVERGO_OPENELEC
1819
#include "system/openelec/OESystemComponent.h"
@@ -60,6 +61,7 @@ void ComponentManager::initialize()
6061
registerComponent(&PowerComponent::Get());
6162
registerComponent(&TaskbarComponent::Get());
6263
registerComponent(&WindowManager::Get());
64+
registerComponent(&MprisComponent::Get());
6365

6466
#if KONVERGO_OPENELEC
6567
registerComponent(&OESystemComponent::Get());

src/input/InputComponent.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,27 @@ void InputComponent::sendAction(const QString action)
258258
emit hostInput(actionsToSend);
259259
}
260260

261+
/////////////////////////////////////////////////////////////////////////////////////////
262+
void InputComponent::setVolume(int volume)
263+
{
264+
qDebug() << "InputComponent: setVolume" << volume;
265+
emit volumeChanged(volume);
266+
}
267+
268+
/////////////////////////////////////////////////////////////////////////////////////////
269+
void InputComponent::seekTo(qint64 position)
270+
{
271+
qDebug() << "InputComponent: seekTo" << position << "ms";
272+
emit positionSeek(position);
273+
}
274+
275+
/////////////////////////////////////////////////////////////////////////////////////////
276+
void InputComponent::setRate(double rate)
277+
{
278+
qDebug() << "InputComponent: setRate" << rate;
279+
emit rateChanged(rate);
280+
}
281+
261282
/////////////////////////////////////////////////////////////////////////////////////////
262283
void InputComponent::registerHostCommand(const QString& command, QObject* receiver, const char* slot)
263284
{

src/input/InputComponent.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,11 @@ class InputComponent : public ComponentBase
108108
void cancelAutoRepeat();
109109
void sendAction(const QString action);
110110

111+
// Volume, seek, and rate control
112+
Q_INVOKABLE void setVolume(int volume);
113+
Q_INVOKABLE void seekTo(qint64 position);
114+
Q_INVOKABLE void setRate(double rate);
115+
111116
signals:
112117
// Always emitted when any input arrives
113118
void receivedInput();
@@ -116,6 +121,15 @@ class InputComponent : public ComponentBase
116121
// in the keymap, such as "host:fullscreen".
117122
void hostInput(const QStringList& actions);
118123

124+
// Emitted when volume should be changed (0-100)
125+
void volumeChanged(int volume);
126+
127+
// Emitted when position should be changed (milliseconds)
128+
void positionSeek(qint64 position);
129+
130+
// Emitted when playback rate should be changed (1.0 = normal speed)
131+
void rateChanged(double rate);
132+
119133
private Q_SLOTS:
120134
void remapInput(const QString& source, const QString& keycode, InputBase::InputkeyState keyState);
121135

src/main.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ void ShowLicenseInfo()
9292

9393
/////////////////////////////////////////////////////////////////////////////////////////
9494
QStringList g_qtFlags = {
95-
"--enable-gpu-rasterization"
95+
"--enable-gpu-rasterization",
96+
"--disable-features=MediaSessionService"
9697
};
9798

9899
/////////////////////////////////////////////////////////////////////////////////////////
@@ -238,6 +239,11 @@ int main(int argc, char *argv[])
238239
webEngineDataDir = d.absolutePath() + "/QtWebEngine";
239240
}
240241

242+
#ifdef Q_OS_LINUX
243+
// Disable QtWebEngine's automatic MPRIS registration - we handle it ourselves
244+
qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--disable-features=MediaSessionService,HardwareMediaKeyHandling");
245+
#endif
246+
241247
QtWebEngineQuick::initialize();
242248
QApplication app(newArgc, newArgv);
243249

0 commit comments

Comments
 (0)