kageroumado/phosphene: A video wallpaper engine for macOS Tahoe · GitHub

A video wallpaper engine for MacOS Tahoe.

Phosphene is a menu bar app + wallpaper extension that plays your own video files as macOS desktop and lock-screen wallpapers. It plugs into the system’s native wallpaper picker, so videos appear with Apple’s built-in aerial. System Settings → Wallpapers.

It is built on Apple’s private WallpaperExtensionKit The framework – the same one that Apple’s own Aerial uses – means that playback runs outside of the process, survives app closing, and integrates with the OS-level lock-screen/idle/sleep lifecycle.

⚠️ Private structure. weight of phosphine WallpaperExtensionKit through dlopen And uses mirror-based runtime introspection to talk to its XPC types. Apple may change this on any major OS release. The project tracks macOS 26 (Tahoe).

  • Bring your own video. Import MP4/MOV/any AVFoundation-readable file. They appear in the system wallpaper picker.
  • Gapless looping. Frame-accurate loop by offsetting PTS/DTS across loop boundaries – no flush, no stutter.
  • Multi-display + per-space selection. Different wallpapers per display, released by macOS.
  • Power-aware playback. a graduate PlaybackPolicy Completely reduces or stops operation based on thermal conditions, battery level, on-battery vs AC, game mode and presentation mode (active/locked/inactive).
  • Smooth lock-screen ramp. When? only on lock screen When enabled, the wallpaper eases in/out along a cubic curve as you lock and unlock, matching Apple’s own Arial behavior.
  • Stop when blocked. It detects that each display is completely covered by windows and pauses rendering until the desktop is visible again.
  • Adaptive variant. Optionally pre-render a lower-resolution/low-fps variant of a video; The renderer swaps to the cheapest variant that satisfies the current policy at each loop boundary.
  • Menu bar controls. Preview current wallpaper, toggle pause, switch displays, configure behavior, launch at login.
  • macOS Tahoe (26.0+). Phosphene relies on the Wallpaper extension point introduced in macOS 14 but uses Tahoe-only SwiftUI and glassEffect() API.
  • Apple Silicon. goals arm64-apple-macos26.0.
  • Xcode 17+ To build, Swift 6 with strict concurrency enabled.
git clone https://github.com/<you>/phosphene
cd phosphene
open Phosphene.xcodeproj

In Xcode, select phosphine Scheme and run. The project uses synchronized file system groups, so adding/removing files Phosphene/ Or PhospheneExtension/ No pbxproj editing required.

You will need to set up a development team for code signing. The wallpaper extension is embedded in the app bundle and registered with the system when the app is launched.

  1. Launch Phosphine. Use the menu bar icon for this Manage Library And add one or more videos.
  2. open System Settings → Wallpapers. Phosphene’s videos appear under their own collection.
  3. Select a video. macOS handles the actual wallpaper assignment – ​​Phosphene’s extension provides frames.
┌─────────────────────────┐         ┌──────────────────────────────┐
│  Phosphene.app          │         │  PhospheneExtension.appex     │
│  (menu bar UI)          │         │  (host: WallpaperAgent)       │
│                         │         │                              │
│  • Library management   │  Darwin │  • XPC handler                │
│  • Per-video metadata   │ ──────▶ │  • AVSampleBufferDisplayLayer │
│  • Optimization (HEVC)  │  notif. │  • Power / thermal monitor    │
│  • Preferences          │         │  • Snapshot generator         │
└─────────────────────────┘         └──────────────────────────────┘
                  │                              │
                  └──────────────┬───────────────┘
                                 ▼
                  Shared App Group container
                  (~/Library/Group Containers/glass.kagerou.phosphene)
                  • Video library + variants
                  • WallpaperPrefs.plist
                  • BMP snapshot cache

app side (Phosphene/) – SwiftUI menu-bar app. Manages on-disk video library, transcodes optional low-resolution variants VideoOptimizationServiceHighlights preferences, and posts Darwin notifications when libraries change.

extension side (PhospheneExtension/) – runs inside the system WallpaperAgent Process when Phosphine Wallpaper is activated. Burden WallpaperExtensionKit.framework At runtime, the wallpaper is registered as the provider, and renders the frame to the remote. CAContext through AVSampleBufferDisplayLayer. It receives XPC acquire / update / invalidate / snapshot calls from WallpaperAgent and changes via route presentation-mode PlaybackPolicy.

PlaybackPolicy Playback is the only source of truth for behavior. Inputs (thermal status, battery, presentation mode, user pause, occlusion, etc.) collapse onto one of full / reduced / minimal / paused. The renderer applies the policy on each state change.

VideoRenderer Decode owns the pipeline. instead of AVPlayerLayer – which silently fails inside the remote CAContext – it runs AVSampleBufferDisplayLayer Manually: one AVAssetReader One for the current loop, one preloaded for the next, and a PTS offset that increases across loops to monotonically increase the timeline. The result is glitch-free looping without flushing the renderer.

  • WallpaperSnapshotXPC To shake. System snapshot checks encoder type(of: coder) == NSXPCCoder.selfBut the actual coder is a subclass. penetrate without runtime PhospheneExtension.swiftSnapshots silently don’t encode anything and you get a gray lock screen during the transition.
  • Mirror-based XPC parsing. Apple’s request types (WallpaperCreationRequestXPC etc) are not part of any public SDK header. extension reads them Mirror reflection. If Apple changes the name of fields, expect surgical breakage.
  • Variants are advisory. If power-monitor detects we are on AC and idle the “1080p@30” variant will not be selected – PlaybackPolicy Always chooses the highest level still allowed.

MIT. Do whatever you want, no warranty.

Created by @kageroumado. Phosphine was originally a commercial project; It’s now open-source because the market for “video wallpaper apps on macOS” has become more crowded than it used to be.



<a href

Leave a Comment