Skip to content

v0.1.0 — Music-library resolution

Choose a tag to compare

@SteliyanH SteliyanH released this 27 Aug 08:32
· 27 commits to main since this release

First release. MPMediaItem → kadr AudioTrack.

Why it is a separate package

kadr core is AVFoundation-only by policy. MediaPlayer is a different framework with its own privacy prompt and its own platform limits, so it lives here — the same reason Photos lives in kadr-photos. A package is justified by a dependency, not by a topic.

Per-clip volume, waveform extraction and audio-only export are kadr core's job and stay there. If this package ever holds only AVFoundation work, it has stopped being a package and become a fragmentation of core — that is written into the ROADMAP as an explicit non-goal.

The thing worth knowing first

Most of a typical music library cannot be exported into a video. Apple Music tracks are DRM-protected: MPMediaItem.assetURL is nil for anything from a subscription, and no API turns one into a file. Only music the user owns — purchased, or imported themselves — exposes a URL.

A consumer that does not know this ships a picker where nearly everything the user taps fails, with nothing useful said. So the surface makes it explicit twice:

// Offer only what will actually work
let usable = try MusicLibrary.usableSongs()

// Or resolve and handle the refusal properly
let track = try MusicLibrary.audioTrack(for: picked)
video = video.music(track.volume(0.4).ducking(0.2))

Added

  • MusicLibrary.audioTrack(for:) — resolves an item, or throws an error explaining why it cannot.
  • MusicLibrary.usableSongs() — filtered by assetURL, so the result is what a picker should offer rather than what the library contains.
  • MusicLibrary.isAuthorized / requestAuthorization() — the latter returns the status rather than a Bool, because .denied and .restricted need different interfaces: one is fixable in Settings, the other is not fixable by the user at all.
  • MusicLibraryError conforming to LocalizedError. The recovery text names Apple Music as the reason rather than suggesting a retry, because retrying with another subscription track fails identically.

Platforms

iOS 17+ and visionOS 1+. macOS is declared in the manifest so the package resolves against kadr and can be tested in CI, but MediaPlayer's types are unavailable there — canImport(MediaPlayer) is true on macOS while every type is marked unavailable, so the guards are #if os(iOS) || os(visionOS). tvOS is excluded outright.

Requires

NSAppleMusicUsageDescription in your app's Info.plist. Without it, requesting authorization terminates the app.