Sample CodeiOS, iPadOS, Mac Catalyst, macOSReviewed 2026-07-21View on Apple Developer

Editing and playing HDR video

At a glance

Item Summary
Purpose Demonstrate HDR-safe playback/export with a built-in compositor, Core Image handler, or custom video compositor.
App architecture Shared asset/filter/export code plus target-selected AVVideoCompositionBuilder implementations and platform UI adapters.
Main patterns Builder, compile-time strategy by target membership, framework protocol implementation, and platform-view adapter.
Project style Multiple app targets reuse CommonSource/CommonUI; compositor folders provide mutually exclusive same-named builders.

Project structure

├── CommonSource/
│   ├── Composition.swift             # AssetLoader, AssetExporter, HDR filter
│   └── HDRIndicator.ci.metal
├── CommonUI-macOS/                   # SwiftUI + AVPlayerView bridge
├── CIFilter-iOS/                     # iOS SwiftUI + AVPlayerViewController bridge
├── BuiltInCompositor/
│   └── AVVideoCompositionBuilder.swift
├── CIFilter/
│   └── AVVideoCompositionBuilder.swift
└── CustomCompositor/
    └── AVVideoCompositionBuilder.swift # Builder + AVVideoCompositing type

Structure observations

  • Every scheme compiles one same-named AVVideoCompositionBuilder; AssetLoader calls a stable static method without runtime dependency injection.
  • Shared files hold asset assembly, export, and the Core Image filter; technique-specific code stays in target folders.
  • UI differs by platform, while the composition call chain remains shared.

Overall architecture

Reference code

CommonSource/Composition.swift:13 — shared call into the target-selected builder

class AssetLoader {
    static func loadAsCompositions() -> (AVComposition, AVVideoComposition) {
        // ... create AVMutableComposition ...
        let videoComposition = AVVideoCompositionBuilder
            .buildVideoComposition(asset: asset, avComposition: avComposition)
        return (avComposition, videoComposition)
    }
}

Interpretation

This is a compile-time variation point: schemes select which builder file belongs to the target. It resembles Strategy, but there is no runtime strategy protocol or injected instance. Playback and export therefore share one composition-building API in every variant.

Ownership and state

Ownership evidence

CommonSource/Composition.swift:35 and CustomCompositor/AVVideoCompositionBuilder.swift:29 — operation handle and custom compositor resources

struct ProgressChecker {
    private var exportSession: AVAssetExportSession? = nil
    var progress: Float { exportSession?.progress ?? 0 }
}

class SampleCustomCompositor: NSObject, AVVideoCompositing {
    private let filter = HDRIndicatorFilter()
    private let coreImageContext = CIContext(/* ... */)
}
Owner Object or state Relationship Mutation authority
AssetLoader call Asset, mutable composition, video composition Creates and returns Static function during construction
PlayerView / AVKit adapter Player item and player Creates for view lifecycle Player view methods
AssetExporter operation Export session Creates; ProgressChecker retains a private reference Export session; checker only reads status
SampleCustomCompositor Filter and Core Image context Creates and retains Compositor callbacks
SwiftUI ContentView Alerts, progress handle, presentation state Owns as @State View actions and export callback

Class and protocol design

CustomCompositor/AVVideoCompositionBuilder.swift:29 — framework-defined compositor capability

class SampleCustomCompositor: NSObject, AVVideoCompositing {
    var supportsWideColorSourceFrames = true
    var supportsHDRSourceFrames = true
    func startRequest(_ request: AVAsynchronousVideoCompositionRequest) {
        // render HDR-preserving output
    }
}
Type Responsibility Depends on
AssetLoader Assemble the source track and request a target-specific video composition AVFoundation, builder name
AVVideoCompositionBuilder variants Configure one editing technique AVFoundation and optionally Core Image
SampleCustomCompositor Fulfill asynchronous composition requests AVVideoCompositing, Core Image
HDRIndicatorFilter Apply the shared Metal-backed HDR visualization CIFilter, CIColorKernel
AssetExporter.ProgressChecker Expose read-only progress/status from a hidden export session AVAssetExportSession

The significant protocol boundary is Apple’s AVVideoCompositing; the sample does not define its own builder protocol.

Access control

Symbol Access Verified effect Likely rationale
ProgressChecker.exportSession private Callers can inspect derived status only. Prevents external reconfiguration/cancellation through the handle.
Custom compositor filter and CIContext private Only compositor callbacks can mutate/render through them. Keeps request processing state internal.
SwiftUI alert, progress, and timer state private State cannot be changed by other files. Expresses view ownership.
PlayerViewRepresentable.coordinator static private Shared bridge storage is limited to that representable type. Hides AppKit bridging mechanics.
Notification.Name.exportAsset public static Export notification name is visible outside the app module. Wider than required here; likely convenience for menu/action wiring.
Builders and shared utility types internal by default Each is visible only inside its selected app target. Target composition, not a framework API, chooses the implementation.

Reference code

CommonUI-macOS/ContentView.swift:73 — private presentation state

@State private var showingAlert = false
@State private var alertReason: AlertReason = .none
@State private var showingExportProgress = false
@State private var exportProgressChecker: AssetExporter.ProgressChecker? = nil
private let exportAssetMenuSelectPublisher =
    NotificationCenter.default.publisher(for: .exportAsset)

Logic ownership and placement

Logic Owning type or file Placement rationale
Shared asset/composition assembly AssetLoader Identical across compositor variants
Built-in transform ramp BuiltInCompositor/AVVideoCompositionBuilder.swift Technique-specific target code
Per-frame Core Image handler CIFilter/AVVideoCompositionBuilder.swift Technique-specific target code
Custom request rendering SampleCustomCompositor Required by the framework protocol
Metal-backed HDR filter HDRIndicatorFilter and .ci.metal Shared image transformation
Playback/export presentation Platform UI files Platform lifecycle and user interaction

Design patterns

Pattern Source evidence Purpose or tradeoff
Builder CommonSource/Composition.swift:29 Gives shared code one construction call for a complex AV object.
Compile-time strategy BuiltInCompositor/AVVideoCompositionBuilder.swift:14, CIFilter/AVVideoCompositionBuilder.swift:14, CustomCompositor/AVVideoCompositionBuilder.swift:85 Schemes swap implementation without runtime branching; not dynamically replaceable.
Framework strategy/protocol CustomCompositor/AVVideoCompositionBuilder.swift:29 AVFoundation invokes the selected compositor implementation.
Adapter CommonUI-macOS/ContentView.swift:40, CIFilter-iOS/ContentView.swift:13 Embeds AppKit/AVKit player views in SwiftUI.
Facade-style utilities CommonSource/Composition.swift:13, CommonSource/Composition.swift:35 UI uses small static load/export operations instead of assembling AV objects.

Naming conventions

  • Variant folders name the editing mechanism: BuiltInCompositor, CIFilter, and CustomCompositor.
  • The same AVVideoCompositionBuilder name is intentionally reused across exclusive targets.
  • Shared types use explicit roles: AssetLoader, AssetExporter, ProgressChecker, and HDRIndicatorFilter.
  • Method names state construction or operation: buildVideoComposition, loadAsCompositions, exportAsynchronously.

Architecture takeaways

  • Target membership can be a clean compile-time variation point for a sample suite.
  • Keep a stable builder API so playback and export use identical composition configuration.
  • Encapsulate export session mutation and expose a read-only progress handle.
  • Use the framework’s compositor protocol when runtime AVFoundation callbacks are the true substitution boundary.

Source map

Source file Relevant symbols
CommonSource/Composition.swift AssetLoader, AssetExporter, HDRIndicatorFilter
BuiltInCompositor/AVVideoCompositionBuilder.swift built-in builder variant
CIFilter/AVVideoCompositionBuilder.swift Core Image handler variant
CustomCompositor/AVVideoCompositionBuilder.swift SampleCustomCompositor, custom builder variant
CommonUI-macOS/ContentView.swift player bridge, ContentView, ProgressPopup
CIFilter-iOS/ContentView.swift iOS AVKit bridge