# MediaRemote<no value>

MediaRemote is a private macOS framework that provides programmatic access to the system "Now Playing" information across all applications that integrate with macOS's media center. The `mediacontrol` and `mediacontroltcp` sources allow djctl to monitor track information from any macOS application that uses this API (ie. Apple Music, Spotify, VLC, web browsers playing media, etc.).

{{< callout caution >}}
The MediaRemote API is non-public and djctl access to it could break in a future macOS release.
{{< /callout >}}

## Modes

djctl supports two `mediacontrol` source modes:

* `mediacontrol` - Runs the `media-control` binary directly on the same machine as djctl
* `mediacontroltcp`- Receives `media-control` events over TCP, allowing the `media-control` binary to run on a different machine than djctl

## mediacontrol

This section covers `media-control` installed alongside djctl on a Mac.

### Install media-control

The `media-control` binary is required to use the MediaRemote API. Install it using [Homebrew](https://brew.sh/):

```bash
brew install media-control
```

By default, djctl expects the binary at `/opt/homebrew/bin/media-control`. If you install it elsewhere, you'll need to specify the path using the `--mediacontrol.binarypath` flag.

### Launch djctl

After installing `media-control`, open a terminal window and switch to the directory containing the djctl binary. Launch it using the following command:

```bash
./djctl start --source=mediacontrol
```

#### Optional: Filter by application

To monitor only specific applications (ie. only Spotify), use the `--mediacontrol.bundleid` flag:

```bash
./djctl start --source=mediacontrol --mediacontrol.bundleid=com.spotify.client
```

Refer to the table below for common bundle IDs.

|Application|Bundle ID|
|-|-|
|Apple Music|`com.apple.Music`|
|Brave Browser|`com.brave.Browser`|
|Firefox Browser|`org.mozilla.firefox`|
|IINA|`com.colliderli.iina`|
|Safari Browser|`com.apple.WebKit.GPU`|
|Spotify|`com.spotify.client`|
|Swinsian|`com.swinsian.Swinsian`|
|VLC|`org.videolan.vlc`|

### Output

If all goes well, output in the terminal window will resemble the following:

```
time="2026-03-08T16:30:00-08:00" level=warning msg="No license key, running in demo mode"
time="2026-03-08T16:30:00-08:00" level=warning msg="Visit https://www.djctl.com/buy/ to purchase a license"
time="2026-03-08T16:30:00-08:00" level=info msg="Starting http listener" httpAddr=":9090"
time="2026-03-08T16:30:00-08:00" level=info msg="Starting media-control source"
time="2026-03-08T16:30:00-08:00" level=info msg="media-control stream started" binary="/opt/homebrew/bin/media-control" bundleID=""
```

### Connect to the djctl web server

Connect to http://127.0.0.1:9090/ in your web browser.

### Play music!

Start playing music in any macOS application that supports the MediaRemote API. djctl will automatically detect track changes and display the currently playing track.

## mediacontroltcp

The TCP source mode allows you to run the `media-control` binary on one macOS machine and djctl on another machine (which can be macOS, Linux, or Windows).

### Launch djctl (any machine)

On the machine where you want to run djctl (can be macOS, Linux, or Windows), open a terminal window and switch to the directory containing the djctl binary. Use the `djctl start --source=mediacontroltcp` command to start the TCP listener.

#### Mac or Linux

```bash
./djctl start --source=mediacontroltcp
```

#### Windows

```bash
djctl.exe start --source=mediacontroltcp
```

### Optional: Filter by application

To monitor only specific applications, use the `--mediacontroltcp.bundleid` flag:

```bash
./djctl start --source=mediacontroltcp --mediacontroltcp.bundleid=com.spotify.client
```

### Install media-control (macOS machine)

On your macOS machine, install media-control:

```bash
brew install media-control
```

### Stream media-control events over TCP

On your macOS machine, run `media-control` in stream mode and pipe the output to a TCP connection. Replace `<DJCTL_HOST>` with the IP address or hostname of the machine running djctl:

```bash
media-control stream --no-diff | nc <DJCTL_HOST> 9191
```

For example, if djctl is running on a machine at 192.168.1.100:

```bash
media-control stream --no-diff | nc 192.168.1.100 9191
```

### Output

If all goes well, output in the terminal window of the machine running djctl will resemble the following:

```
time="2026-03-08T16:30:00-08:00" level=warning msg="No license key, running in demo mode"
time="2026-03-08T16:30:00-08:00" level=warning msg="Visit https://www.djctl.com/buy/ to purchase a license"
time="2026-03-08T16:30:00-08:00" level=info msg="Starting http listener" httpAddr=":9090"
time="2026-03-08T16:30:00-08:00" level=info msg="Starting media-control TCP source"
time="2026-03-08T16:30:00-08:00" level=info msg="media-control TCP listener started" addr=":9191" bundleID=""
```

Once the macOS machine running media-control connects to djctl, you'll see:

```
time="2026-03-08T16:30:15-08:00" level=info msg="media-control TCP connection accepted" remote="192.168.1.50:54321"
```

### Connect to the djctl web server

Connect to http://127.0.0.1:9090/.

### Play music!

Start playing music on your macOS machine (running media-control) in any application that supports the MediaRemote API. djctl will will receives updates from media-control and automatically detect track changes.

### Important Notes

* Artwork delay: This source requires --delay >= 1 to allow artwork events to arrive properly. djctl will automatically set this if not configured.
* Firewalls: When running djctl and media-control on separate machines, ensure network and endpoint firewalls do not block the connection.