Access the operating systems "Media Remote"/Now Playing interface from Java/Kotlin. Works on all modern operating systems.
- Get current system media sessions
- Support for multiple apps playing at the same time
- Query name, album, artist, artwork data, duration and additional metadata
- Get the play head position
- Control playback (play/pause/toggle/next/prev/stop)
- Seek support
- Cross-platform universal interface (one API for all platforms)
| Feature | Linux | Windows | macOS |
|---|---|---|---|
| Session discovery (all sessions) | Yes | Yes | No |
| Control/Query multiple sessions at once | Yes | Yes | No |
| Active session selection | Yes | Yes | Yes |
| Session lookup by app name | Yes | Yes | Partial |
| Playback state read | Yes | Yes | Yes |
| Now playing: name/album/artist/duration | Yes | Yes | Yes |
| Now playing: artwork | Yes | Yes | Yes |
| Now playing: livestream detection | Untested | Untested | Untested |
| Now playing: additional metadata | Yes | Yes | No |
| Now playing: position | Yes | Yes | Yes |
| Now playing: computed position progression | Yes | Yes | Yes |
| Playback controls: play/pause/toggle/next/prev/stop | Yes | Yes | Yes |
| Playback controls: seek | Yes | Yes | Yes |
| Polling: supported | Yes | Yes | Yes |
| Event driven: supported | Yes | Yes | Yes |
| Event driven: process system events | No | No | No |
| Polling: computed position progression | Yes | Yes | Yes |
| Event driven: computed position progression | Yes | Yes | Yes |
Event driven: onPlaybackStateChanged |
Yes | Yes | Yes |
Event driven: onSessionAdded/Removed |
Yes | Yes | No |
Event driven: onNowPlayingChanged |
Yes | Yes | Yes |
Event driven: onSessionActiveChanged |
Yes | Yes | Yes |
| Configurable poll/update intervals | Yes | Yes | Yes |
| Platform | Supported architecture | Native backend |
|---|---|---|
| Linux | N/A | Java DBUS/MPRIS2 |
| Windows | x64, ARM64 | JNI (mediainterface_winrt) |
| macOS | Intel, Apple Silicon | Perl + MediaRemoteAdapter |
Use mediainterface-all to get the core API + all platform providers in one dependency.
Replace VERSION_HERE with the Maven Central version shown in the badge above.
Javadocs:
- Core API: https://javadoc.io/doc/org.endlesssource.mediainterface/core
- Linux: https://javadoc.io/doc/org.endlesssource.mediainterface/linux
- Windows: https://javadoc.io/doc/org.endlesssource.mediainterface/windows
- macOS: https://javadoc.io/doc/org.endlesssource.mediainterface/macos
dependencies {
implementation("org.endlesssource.mediainterface:all:VERSION_HERE")
}<dependency>
<groupId>org.endlesssource.mediainterface</groupId>
<artifactId>all</artifactId>
<version>VERSION_HERE</version>
</dependency>If you use shadowJar, add this to your Gradle configuration to merge the included service file:
tasks.shadowJar {
duplicatesStrategy = DuplicatesStrategy.INCLUDE // include all service files
mergeServiceFiles { // always merge service files
include("META-INF/services/org.endlesssource.mediainterface.spi.PlatformMediaProvider")
}
}import org.endlesssource.mediainterface.SystemMediaFactory;
import org.endlesssource.mediainterface.api.SystemMediaInterface;
public class Main {
public static void main(String[] args) {
try (SystemMediaInterface media = SystemMediaFactory.createSystemInterface()) {
media.getActiveSession().ifPresent(session -> {
System.out.println("App: " + session.getApplicationName());
session.getNowPlaying().ifPresent(now -> {
String title = now.getTitle().orElse("Unknown title");
String artist = now.getArtist().orElse("Unknown artist");
System.out.println("Now playing: " + title + " - " + artist);
});
});
}
}
}See examples module
Java Media Interface is licensed under the Apache 2.0 License. (see LICENSE)
- @TimLohrer for the idea
- mediaremote-adapter for the MediaRemote Perl workaround