axiom-now-playing-musickit

axiom-now-playing-musickit

Popular

MusicKit Now Playing integration patterns. Use when playing Apple Music content with ApplicationMusicPlayer and understanding automatic vs manual Now Playing info updates.

388estrelas
38forks
Atualizado 2/3/2026
SKILL.md
readonlyread-only
name
axiom-now-playing-musickit
description

MusicKit Now Playing integration patterns. Use when playing Apple Music content with ApplicationMusicPlayer and understanding automatic vs manual Now Playing info updates.

MusicKit Integration (Apple Music)

Time cost: 5-10 minutes

Key Insight

MusicKit's ApplicationMusicPlayer automatically publishes to MPNowPlayingInfoCenter. You don't need to manually update Now Playing info when playing Apple Music content.

What's Automatic

When using ApplicationMusicPlayer:

  • Track title, artist, album
  • Artwork (Apple's album art)
  • Duration and elapsed time
  • Playback rate (playing/paused state)

The system handles all MPNowPlayingInfoCenter updates for you.

What's NOT Automatic

  • Custom metadata (chapter markers, custom artist notes)
  • Remote command customization beyond standard controls
  • Mixing MusicKit content with your own content

GOOD Code (MusicKit Content)

import MusicKit

@MainActor
class MusicKitPlayer {
    private let player = ApplicationMusicPlayer.shared

    func play(song: Song) async throws {
        // ✅ Just play - MPNowPlayingInfoCenter updates automatically
        player.queue = [song]
        try await player.play()

        // ❌ DO NOT manually set nowPlayingInfo here
        // MPNowPlayingInfoCenter.default().nowPlayingInfo = [...] // WRONG!
    }
}

Hybrid Apps (Own Content + Apple Music)

If your app plays both Apple Music and your own content:

import MusicKit

@MainActor
class HybridPlayer {
    private let musicKitPlayer = ApplicationMusicPlayer.shared
    private var avPlayer: AVPlayer?
    private var currentSource: ContentSource = .none

    enum ContentSource {
        case none
        case appleMusic      // MusicKit handles Now Playing
        case ownContent  // We handle Now Playing
    }

    func playAppleMusicSong(_ song: Song) async throws {
        // Switch to MusicKit
        avPlayer?.pause()
        currentSource = .appleMusic

        musicKitPlayer.queue = [song]
        try await musicKitPlayer.play()
        // ✅ MusicKit handles Now Playing automatically
    }

    func playOwnContent(_ url: URL) {
        // Switch to AVPlayer
        musicKitPlayer.pause()
        currentSource = .ownContent

        avPlayer = AVPlayer(url: url)
        avPlayer?.play()

        // ✅ Manually update Now Playing (Patterns 1-4)
        updateNowPlayingForOwnContent()
    }

    private func updateNowPlayingForOwnContent() {
        var nowPlayingInfo = [String: Any]()
        nowPlayingInfo[MPMediaItemPropertyTitle] = "My Track"
        // ... rest of manual setup from Patterns 1-4
        MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
    }
}

Common Mistake

// ❌ WRONG - Overwrites MusicKit's automatic Now Playing data
func playAppleMusicSong(_ song: Song) async throws {
    try await ApplicationMusicPlayer.shared.play()

    // ❌ This clears MusicKit's Now Playing info!
    var nowPlayingInfo = [String: Any]()
    nowPlayingInfo[MPMediaItemPropertyTitle] = song.title
    MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
}

// ✅ CORRECT - Let MusicKit handle it
func playAppleMusicSong(_ song: Song) async throws {
    try await ApplicationMusicPlayer.shared.play()
    // That's it! MusicKit publishes Now Playing automatically.
}

When to Use Manual Updates with MusicKit

Only override MPNowPlayingInfoCenter if:

  • You're mixing in additional metadata (e.g., podcast chapter markers)
  • You're displaying custom content alongside Apple Music
  • You have a specific reason to replace MusicKit's automatic behavior

Default: Let MusicKit manage Now Playing automatically.

Resources

Skills: axiom-now-playing, axiom-now-playing-carplay

You Might Also Like

Related Skills

verify

verify

243K

Use when you want to validate changes before committing, or when you need to check all React contribution requirements.

facebook avatarfacebook
Obter
test

test

243K

Use when you need to run tests for React core. Supports source, www, stable, and experimental channels.

facebook avatarfacebook
Obter

Use when feature flag tests fail, flags need updating, understanding @gate pragmas, debugging channel-specific test failures, or adding new flags to React.

facebook avatarfacebook
Obter

Use when adding new error messages to React, or seeing "unknown error code" warnings.

facebook avatarfacebook
Obter
flow

flow

243K

Use when you need to run Flow type checking, or when seeing Flow type errors in React code.

facebook avatarfacebook
Obter
flags

flags

243K

Use when you need to check feature flag states, compare channels, or debug why a feature behaves differently across release channels.

facebook avatarfacebook
Obter