
Photokit
Implement iOS video and audio playback with AVPlayer, HLS streaming, background audio, Now Playing, remote commands, and Picture-in-Picture using copy-paste Swift patterns.
Overview
photokit is an agent skill for the Build phase that supplies Swift patterns for AVPlayer-based playback, streaming, audio session, and Picture-in-Picture on iOS.
Install
npx skills add https://github.com/dpearson2699/swift-ios-skills --skill photokitWhat is this skill?
- AVPlayer and AVPlayerViewController setup with SwiftUI VideoPlayer
- AVPlayerItem/AVAsset loading and playback control patterns
- HLS streaming configuration section
- AVAudioSession, background audio, Now Playing Info Center, and MPRemoteCommandCenter
- Picture-in-Picture integration section
- 10 topical sections from AVPlayer setup through Picture-in-Picture
Adoption & trust: 1.2k installs on skills.sh; 713 GitHub stars; 2/3 security scanners passed (skills.sh audits).
What problem does it solve?
You are building an iOS media feature and need correct AVKit/AVFoundation setup for streaming, background audio, and system controls without re-reading Apple docs each time.
Who is it for?
Solo indie iOS devs adding video or audio playback to a SwiftUI app with standard system integrations.
Skip if: Photo library picking/editing workflows (PHPicker/Photos framework)—this readme focuses on AV playback, not PhotoKit asset browsing.
When should I use this skill?
Implementing or debugging iOS AV playback, HLS, background audio, or PiP in a Swift/SwiftUI codebase.
What do I get? / Deliverables
Your agent emits structured Swift snippets for player setup, HLS, session config, Now Playing, remote commands, and PiP aligned to documented AVFoundation APIs.
- SwiftUI player views and session configuration code
- Remote command and Now Playing integration snippets
Recommended Skills
Journey fit
Build is where native iOS playback UI and session wiring ship; this is implementation reference, not distribution or analytics. Frontend covers SwiftUI AVKit surfaces, player state observation, and PiP—user-facing media experiences on device.
How it compares
Reference skill patterns, not a hosted media CDN or cross-platform React Native player abstraction.
Common Questions / FAQ
Who is photokit for?
Swift iOS builders and agent users implementing AVPlayer features in native apps.
When should I use photokit?
During Build frontend work when integrating streaming playback, lock-screen controls, background audio, or PiP in a SwiftUI target.
Is photokit safe to install?
It is documentation-only Swift patterns with no bundled scripts—still review the Security Audits panel on this page before trusting any third-party skill repo.
SKILL.md
READMESKILL.md - Photokit
# AV Playback Patterns for media playback with AVPlayer, streaming HLS content, audio session configuration, background audio, Now Playing integration, remote command handling, and Picture-in-Picture. ## Contents - [AVPlayer and AVPlayerViewController Setup](#avplayer-and-avplayerviewcontroller-setup) - [AVPlayerItem and AVAsset Loading](#avplayeritem-and-avasset-loading) - [Playback Controls](#playback-controls) - [Observing Player State and Time](#observing-player-state-and-time) - [Streaming HLS Content](#streaming-hls-content) - [AVAudioSession Configuration](#avaudiosession-configuration) - [Background Audio Setup](#background-audio-setup) - [Now Playing Info Center](#now-playing-info-center) - [MPRemoteCommandCenter](#mpremotecommandcenter) - [Picture-in-Picture](#picture-in-picture) ## AVPlayer and AVPlayerViewController Setup `AVPlayer` manages playback of a single media asset. Use `AVPlayerViewController` (AVKit) for the system-standard playback UI with transport controls, or `AVPlayerLayer` for a custom player interface. Docs: [AVPlayer](https://sosumi.ai/documentation/avfoundation/avplayer), [AVPlayerViewController](https://sosumi.ai/documentation/avkit/avplayerviewcontroller) ### AVPlayerViewController in SwiftUI ```swift import SwiftUI import AVKit struct VideoPlayerView: View { let url: URL @State private var player: AVPlayer? var body: some View { VideoPlayer(player: player) .onAppear { player = AVPlayer(url: url) player?.play() } .onDisappear { player?.pause() player = nil } } } ``` ### AVPlayerViewController in UIKit ```swift import UIKit import AVKit final class VideoViewController: UIViewController { private var player: AVPlayer? func presentVideo(url: URL) { player = AVPlayer(url: url) let controller = AVPlayerViewController() controller.player = player present(controller, animated: true) { self.player?.play() } } } ``` ### Custom Player with AVPlayerLayer For full control over the player UI, embed an `AVPlayerLayer`: ```swift import AVFoundation import UIKit final class PlayerView: UIView { override class var layerClass: AnyClass { AVPlayerLayer.self } var playerLayer: AVPlayerLayer { layer as! AVPlayerLayer } var player: AVPlayer? { get { playerLayer.player } set { playerLayer.player = newValue } } func configure() { playerLayer.videoGravity = .resizeAspect } } ``` ## AVPlayerItem and AVAsset Loading `AVAsset` represents the static media (duration, tracks, metadata). `AVPlayerItem` adds the dynamic state (current time, buffering status) needed for playback. Docs: [AVPlayerItem](https://sosumi.ai/documentation/avfoundation/avplayeritem), [AVAsset](https://sosumi.ai/documentation/avfoundation/avasset) ```swift import AVFoundation // Local file let localURL = Bundle.main.url(forResource: "intro", withExtension: "mp4")! let localItem = AVPlayerItem(url: localURL) // Remote file let remoteURL = URL(string: "https://example.com/video.mp4")! let remoteItem = AVPlayerItem(url: remoteURL) // From an existing AVAsset (for more control) let asset = AVURLAsset(url: remoteURL, options: [ AVURLAssetPreferPreciseDurationAndTimingKey: true ]) // Load properties asynchronously before playback (iOS 15+) let duration = try await asset.load(.duration) let tracks = try await asset.load(.tracks) let isPlayable = try await asset.load(.isPlayable) let item = AVPlayerItem(asset: asset) let player = AVPlayer(playerItem: item) ``` ### Replacing the Current Item Reuse a single `AVPlayer` and swap items: ```swift let nextItem = AVPlayerItem(url: nextVideoURL) player.replaceCurrentItem(with: nextItem) player.play() ``` ### Queue Playback with AVQueuePlayer ```swift let items = videoURLs.map { AVPlayerItem(url: $0) } let queuePlayer = AVQueuePlayer(items