ryanfrancesconi/spfk-video
Video frame extraction and track/metadata reading for Swift, built on Apple's AVFoundation framework.
Usage
Video Track & QuickTime Metadata
import SPFKVideo
let result = await VideoTrackReader.read(from: videoURL)
let videoTrack = result.videoTrack // VideoTrackProperties?
let quickTimeUserData = result.quickTimeUserData // QuickTimeUserData?
print(videoTrack?.width, videoTrack?.height, videoTrack?.frameRate, videoTrack?.codec)
print(quickTimeUserData?.deviceMake, quickTimeUserData?.latitude, quickTimeUserData?.longitude)VideoTrackReader.read(from:) reads video-technical properties (resolution, frame rate, codec, pixel aspect ratio, rotation) via AVAssetTrack, and QuickTime user-data (GPS, capture device, creation date) via AVMetadataItem. Both reads are best-effort and independent — a failure in one doesn't suppress the other. QuickTime metadata is merged from both the modern mdta keyspace (.quickTimeMetadata) and the legacy udta keyspace (.quickTimeUserData), since which keyspace a given file populates varies by capture device/software.
Frame Extraction
import SPFKVideo
// Extract frames at specific timestamps, keyed by the requested time.
let frames = try await VideoFrameExtractor.frames(
from: videoURL,
at: [1.0, 3.0, 5.0, 7.0],
maximumSize: CGSize(width: 300, height: 0) // width-constrained, height scales proportionally
)
let frameAt3s = frames[3.0] // CGImage?
// Get the video track's own duration, independent of a sibling audio track's length.
let duration = try await VideoFrameExtractor.duration(of: videoURL)frames(from:at:maximumSize:tolerance:) uses AVAssetImageGenerator's images(for:) async sequence. Wide tolerance (0.3s default) lets the generator reuse the nearest already-decoded frame rather than forcing exact decoding — significantly faster for thumbnail and classification sampling that doesn't need frame-perfect accuracy. A timestamp whose frame fails to extract is simply absent from the result rather than failing the whole batch.
This package is extraction only — no persistence. Disk caching of extracted frames is an application-level concern and lives in the consuming app's own data layer.
Dependencies
| Package | Description | |---------|-------------| | spfk-base | Core utilities and extensions | | spfk-testing | Test infrastructure (test target only) |
Requirements
- Platforms: macOS 13+, iOS 16+
- Swift: 6.2+
About
Spongefork is the personal software projects of musician and developer Ryan Francesconi. Dedicated to creative sound manipulation, his first application, Spongefork, was released in 1999 for macOS 8. From 2026, Spongefork returns as his software container for more musical experimentation. In addition to software releases, open source components can be found on his GitHub page.
Package Metadata
Repository: ryanfrancesconi/spfk-video
Default branch: main
README: README.md