# PlayNotch: a Music Controller in Your MacBook Notch

> Over Italy's June 2 Republic Day holiday weekend, I built PlayNotch, my first Swift app: an interactive music controller that lives inside the MacBook notch and handles Apple Music, Spotify, and YouTube Music without opening any app. Multi-player support, artwork-based theming, quick toggles, and zero private APIs.

- URL: https://mautoblog.com/en/posts/playnotch-macos-notch-music-controller-swift-2026/
- Language: en
- Published: 2026-06-02
- Updated: 2026-10-16
- Author: Matteo
- Categories: Projects, Software Development
- Tags: Swift, macOS, Open Source, Music, Productivity
- Translation (it): https://mautoblog.com/posts/playnotch-macos-notch-music-controller-swift-2026/

---

What is there to do over Italy's June 2 Republic Day holiday weekend? Exactly. While half the country was probably at the beach or firing up a barbecue, I was here on the couch, MacBook open, with an idea that had been buzzing in my head for weeks.

I had a simple but annoying problem: I use **YouTube Music** as my main player, and every time I wanted to change track, raise the volume, or hit pause, I had to go back to the browser tab, or click the menu bar, or hunt for the right window among the ten I already had open... in short, too many gestures for something that should be immediate. And then there is that **notch** - that black cutout at the top of the MacBook screen - which Apple has always treated like dead space, a decorative black hole.

"What if I put a music controller in there, like on the iPhone?"

Said and done. Welcome to [PlayNotch](https://github.com/Mauto82/PlayNotch).

## My First Swift App: Survived (Barely)

Before we go any further: I am not a Swift developer. I mainly work with PHP and Python, and Swift was one of those things I kept telling myself I would learn "sooner or later." Well, the June 2 holiday weekend turned out to be the "sooner or later."

The good news is that you do not need Xcode. PlayNotch is built entirely with **SwiftPM** (Swift Package Manager) and Apple's Command Line Tools. No 30GB graphical IDE, just code and terminal. For someone used to working from the CLI, that is already a civilized starting point.

The less good news is that Swift is... peculiar. The type system is strict, the compiler forgives nothing, and I spent the first hour fighting optionals and closures like they were old enemies. But then something clicks, and you start seeing the logic behind it. It is like the first time I learned generics in PHP 8: at first they look useless, and then suddenly you cannot live without them.

## What PlayNotch Does (And Why You Might Actually Want It)

When you launch PlayNotch, you do not see any icon in the Dock - the app runs in the background as an "agent"-style app. What you do see is a small bar that sits on the notch. Move the cursor over it and **boom**: it expands into a card with all the information about the track that is currently playing.

Here is what you get inside the expanded card:

[Video](/video/playnotch-demo.mp4)

- **Artwork, title, and artist** of the current track
- **Transport controls**: previous, play/pause, next
- **Scrubbable progress bar** - yes, I think we are allowed to say that - so you can drag to a specific point, with hover preview for the position
- **Volume control**: scroll over the notch or use the slider
- **Shuffle and repeat toggles** (native on Apple Music and Spotify; YouTube Music handles them through its own player bar)
- **Like/Favorite** for the current track (Apple Music and YouTube Music; Spotify unfortunately does not allow it via AppleScript)
- **Artwork-based theming** (optional): a "vibrant" color is extracted from the cover art and applied to the card, the progress bar, and the toggles
- **Blurred cover background** (optional): the artwork becomes the card background, liquid effect included
- **Quick system toggles** (optional):
  - Switch between Light, Dark, and Auto mode
  - Keep the Mac awake with `caffeinate`
  - Put the display to sleep

Everything is accessible without opening any app, without touching any menu. One hover and you have full control.

## Multi-Player: The Precedence Game

One of the things I liked least about existing solutions is that they do not handle the case where you have multiple players open at the same time very well. Spotify in the background, Apple Music starting by accident, YouTube Music open in a browser...

PlayNotch solves this with a simple rule: **last player to make sound wins**. The player you started most recently takes control of the card. If you pause it, control automatically falls back to the one that is still playing. No manual configuration, no dropdown menu to choose the source.

The three supported players work in slightly different ways under the hood:

| Player | How it is controlled |
|---|---|
| Apple Music | Direct AppleScript to `Music.app` |
| Spotify | Direct AppleScript to `Spotify.app` |
| YouTube Music | JavaScript injected into the browser tab |

Precisely for YouTube Music - my main use case, and probably the most annoying one to support - there is a small one-time setup step: you need to enable "Allow JavaScript from Apple Events" in the browser. The reason is simple: YouTube Music does not expose an AppleScript interface like Apple Music or Spotify do, so PlayNotch injects JavaScript directly into the browser tab to read and control the player. You do it once, and it works with Safari, Chrome, Brave, Edge, and Arc.

## How to Install It (It Is Easier Than It Looks)

You need **macOS 14** or later and the **Swift 6 toolchain** (not Xcode, just the Command Line Tools). Then:

```bash
git clone https://github.com/Mauto82/PlayNotch.git
cd PlayNotch
./scripts/build_app.sh --run
```

The script does everything: builds in release mode, creates the `.app` bundle in `build/`, terminates any previous instance, and launches the app. On first run, macOS will ask for automation permissions for each player - that is normal, just click OK.

> **Important note**: PlayNotch is ad-hoc signed, not notarized by Apple. On the very first launch, macOS may complain. The fix is to open it with right click -> "Open", or go to *System Settings -> Privacy & Security -> "Open Anyway"*. It only happens once.

If you are running **macOS 26** (in beta) like I am, it works there too.

## The Menu Bar Icon: Control Center for the Notch

Since there is no Dock icon, settings live in the menu bar - the **♪** icon is your access point. From there you can:

- Enable or disable **Launch at Login**
- Turn **Theme from Artwork** and **Blurred Cover Background** on or off
- Show or hide the **Quick Toggles** row
- Choose the **notch size** (Compact / Default / Large)
- Select which screen should show the notch (**Show on Screen**)
- Open macOS Automation settings
- Quit the app

## Project Structure

For anyone curious about how the code is organized, the structure is fairly readable:

```text
Sources/PlayNotch/
  main.swift
  AppDelegate.swift
  StatusItemController/    <- menu bar item
  Media/
    NowPlaying.swift       <- data model + MediaSource protocol
    AppleScriptRunner/     <- NSAppleScript helper
    AppleMusicSource/
    SpotifySource/
    YouTubeMusicSource/
    MediaController/       <- picks the active player
  Notch/
    NotchViewModel/        <- state, polling, artwork, accent color
    NotchView/             <- SwiftUI UI
    NotchWindow/           <- NSPanel above the menu bar
    NotchController/       <- screen geometry, mouse tracking
    PassthroughHostingView <- click pass-through outside the notch
    ColorExtraction/       <- vibrant color extraction from artwork
```

Polling happens once per second. The progress bar does not "jump" between one poll and the next because the position is interpolated locally - a small detail that makes a real difference in everyday use.

## What Now?

The roadmap is already basically done for this first version:

- ✅ Progress bar + seek + volume
- ✅ Like / favorite and shuffle / repeat
- ✅ Artwork-based theming
- ✅ Menu bar icon with launch at login and screen picker
- ✅ Blurred artwork background and "liquid" animations
- ✅ Preferences (notch size, quick toggles, screen, theming)
- ✅ Control Center row (appearance, keep-awake, sleep display)

If you have ideas, bugs to report, or want to contribute, the repository is public on [GitHub](https://github.com/Mauto82/PlayNotch). PRs are welcome - also because, let us be honest, my Swift is still the Swift of someone who learned it over a holiday weekend.

---

*P.S. All right, next time I will seriously consider the radical option of inviting a few friends over for a proper barbecue in the yard and spending a holiday weekend like a normal person. Maybe.*

