Music Player Integration
Relevant source files
The following files were used as context for generating this wiki page:
- buddi/MediaControllers/AppleMusicController.swift
- buddi/MediaControllers/SpotifyController.swift
- buddi/MediaControllers/YouTube Music Controller/YouTubeMusicController.swift
- buddi/managers/MusicManager.swift
- buddi/MediaControllers/NowPlayingController.swift
- buddi/components/Music/MusicVisualizer.swift
- buddi/components/Notch/NotchHomeView.swift
The Music Player Integration system in Buddi provides a unified interface for controlling and monitoring media playback from various macOS applications. It serves as a bridge between the application's Notch UI and external media players like Apple Music, Spotify, and YouTube Music, as well as a generic "Now Playing" interface for other system-wide media.
This module is responsible for fetching track metadata (title, artist, album), managing playback state (play/pause, skip, seek), handling artwork, and providing real-time visual feedback through a music visualizer. It abstracts the complexities of different communication protocols—such as AppleScript for native apps and WebSockets/REST APIs for third-party clients—into a single manager accessible by the UI components.
Sources: buddi/managers/MusicManager.swift:20-60, README.md:27-28
System Architecture
The architecture follows a provider-consumer pattern where a central MusicManager coordinates between the UI and specific media controllers.
Core Components
| Component | Description |
|---|---|
MusicManager | A singleton that manages the active controller, maintains the current playback state for the UI, and handles lyrics fetching. |
MediaControllerProtocol | A common interface that all specific music controllers must implement to provide playback commands and state updates. |
AppleMusicController | Integrates with the native Music app using AppleScript and distributed notifications. |
SpotifyController | Integrates with Spotify using AppleScript and distributed notifications. |
YouTubeMusicController | Communicates with third-party YouTube Music clients via HTTP and WebSockets. |
NowPlayingController | Uses the MediaRemote private framework and a Perl adapter to monitor system-wide media. |
Sources: buddi/managers/MusicManager.swift:20-130, buddi/MediaControllers/AppleMusicController.swift:11, buddi/MediaControllers/SpotifyController.swift:12, buddi/MediaControllers/YouTube Music Controller/YouTubeMusicController.swift:14
Data Flow Diagram
The following diagram illustrates how playback information travels from the external media application to the Buddi Notch UI.
Media Controller Implementations
Each controller manages communication with its specific target application using the most efficient method available.
Apple Music & Spotify
Both controllers rely heavily on AppleScript for command execution (play, pause, skip) and DistributedNotificationCenter for observing state changes. They fetch detailed track info by executing asynchronous AppleScript blocks that return NSAppleEventDescriptor objects containing track metadata and artwork.
Sources: buddi/MediaControllers/AppleMusicController.swift:34-45, buddi/MediaControllers/SpotifyController.swift:42-53
YouTube Music
The YouTubeMusicController is more complex, utilizing a dual-channel approach:
- WebSockets: Provides real-time updates for position changes, volume, and playback state.
- REST API: Used for authentication and sending commands like
toggle-playorseek-to. - Polling: Acts as a fallback if the WebSocket connection fails.
Sources: buddi/MediaControllers/YouTube Music Controller/YouTubeMusicController.swift:115-160, buddi/MediaControllers/YouTube Music Controller/YouTubeMusicNetworking.swift:116-140
NowPlaying (Media Remote)
The NowPlayingController utilizes a helper script (mediaremote-adapter.pl) to bridge the system's MediaRemote framework. It processes a JSON stream of updates to maintain track synchronization across apps that don't have dedicated controllers.
Sources: buddi/MediaControllers/NowPlayingController.swift:126-150
Playback Management
The MusicManager centralizes playback control. It exposes methods that are called by UI buttons (e.g., in MusicControlsView) and forwards them to the active controller.
Playback State Object
The PlaybackState structure is the primary data vehicle, containing:
isPlaying: Boolean status.title,artist,album: Metadata strings.currentTime,duration: Progress tracking.artwork: Binary data for the album cover.repeatMode&isShuffled: Playback settings.
Sources: buddi/managers/MusicManager.swift:30-55, buddi/MediaControllers/YouTube Music Controller/YouTubeMusicModels.swift:30-41
Command Sequence
User Interface & Feedback
The NotchHomeView.swift provides the visual representation of the music player.
Music Controls & Slider
The UI includes a marquee for long track titles, a progress slider, and dynamic buttons. The slider uses a TimelineView to estimate the current playback position between state updates, ensuring smooth movement.
Sources: buddi/components/Notch/NotchHomeView.swift:122-160, buddi/managers/MusicManager.swift:456-462
Audio Visualizer
The AudioSpectrum class provides a 4-bar visualizer using CAShapeLayer. It animates bar scales randomly when isPlaying is true to simulate audio activity.
// Example of the bar update logic
private func updateBars() {
for (i, barLayer) in barLayers.enumerated() {
let currentScale = barScales[i]
let targetScale = CGFloat.random(in: 0.35 ... 1.0)
barScales[i] = targetScale
let animation = CABasicAnimation(keyPath: "transform.scale.y")
// ... animation configuration
barLayer.add(animation, forKey: "scaleY")
}
}
Sources: buddi/components/Music/MusicVisualizer.swift:55-73
Configuration and Selection
Users can select their preferred media source during onboarding or in settings. This preference is stored using the Defaults library.
| Controller Type | Preference Key | Description |
|---|---|---|
.nowPlaying | MediaControllerType | System-wide detection (Default unless deprecated). |
.appleMusic | MediaControllerType | Native Apple Music integration. |
.spotify | MediaControllerType | Native Spotify integration. |
.youtubeMusic | MediaControllerType | Third-party YouTube Music client integration. |
Sources: buddi/components/Onboarding/MusicControllerSelectionView.swift:18-30, buddi/models/Constants.swift:33-40
Conclusion
The Music Player Integration is a robust, modular system designed for extensibility. By utilizing a protocol-oriented approach and a centralized manager, Buddi provides a seamless music control experience within the macOS notch, regardless of the user's preferred media application.