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

Processing spatial video with a custom video compositor

At a glance

Item Summary
Purpose Create a custom video compositor to edit spatial video for playback and export.
App architecture A Swift sample with the source-visible chain AVFSpatialCustomVideoCompositorSampleContentViewSampleModelAVFoundation APIs.
Main patterns Protocol-oriented abstraction, Builder
Project style 14 scanned source file(s) across Swift, organized around ranked entry, type, and file boundaries.
Execution model Source-visible boundaries: Sendable or @Sendable, async declaration or closure, Task, @MainActor, Task closure isolated to MainActor; none alone proves a background thread.
State/event model Source-visible mechanisms: SwiftUI state property wrapper, @Observable.
Key frameworks/packages AVFoundation, os, SwiftUI, AVKit, CoreImage; these are source dependencies, not architecture labels.

Project structure

Source bundle/
└── AVFSpatialCustomVideoCompositorSample/
    ├── AVFSpatialCustomVideoCompositorSample.swift
    ├── Compositing/
    │   ├── VideoCompositionBuilder.swift
    │   ├── PixelBufferHelper.swift
    │   ├── MonoOutputCompositor.swift
    │   └── StereoOutputCompositor.swift
    ├── ContentView.swift
    ├── Views/
    │   ├── PlayerView.swift
    │   └── SettingsView.swift
    ├── Export/
    │   ├── Exporter.swift
    │   ├── ExportSessionExporter.swift
    │   └── ReaderWriterExporter.swift
    └── SampleModel.swift

Structure observations

  • Architecturally prominent files are ranked from entry points and role-named declarations; resource-only paths are omitted.
  • Primary languages: Swift.
  • The verified tree contains 3 project/configuration file(s) and 21 source declaration(s).

Overall architecture

Reference code

AVFSpatialCustomVideoCompositorSample/AVFSpatialCustomVideoCompositorSample.swift:11 — architecture anchor

@main
struct AVFSpatialCustomVideoCompositorSample: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .task {
                    UserSettings.shared.registerDefaults()
                }
        }
    }
}

Interpretation

The arrows summarize the source-visible entry, role-named types or folders, and framework direction; when nodes come from structural folders, the sequence is a high-level interpretation rather than proof that every adjacent node calls the next. Ownership is claimed only where the next section cites a stored property or assignment. The diagram is intentionally limited to the dominant path into AVFoundation.

Ownership and state

Ownership evidence

AVFSpatialCustomVideoCompositorSample/AVFSpatialCustomVideoCompositorSample.swift:24 — stored dependency or nearest verified ownership anchor

let logger = Logger(subsystem: "AVF-SpatialCustomVideoCompositorSample", category: "app")
Owner Object or state Relationship Mutation authority
AVFSpatialCustomVideoCompositorSample Logger (logger) creates and retains Initialized by the owner; the binding is immutable
VideoCompositionBuilder AVAsset (asset) stores or receives Initialized by the owner; the binding is immutable
VideoCompositionBuilder CompositorType (compositorType) stores or receives Initialized by the owner; the binding is immutable
SpatialVideoCompositionInstruction AVVideoCompositionInstructionProtocol (wrappedInstruction) stores or receives Initialized by the owner; the binding is immutable

Composition arrows indicate a source-visible construction expression or locally owned value state; aggregation means the owner stores or receives a dependency without proving exclusive lifetime ownership.

Concurrency, scheduling, and thread safety

Evidence limit: actor isolation, async/await, or Task creation does not by itself prove background-thread execution; Sendable conformance alone does not prove thread-safe mutation.

Concern Source mechanism Verified placement or handoff Evidence
Transfer contract Sendable or @Sendable The source declares a sendability boundary; this alone does not synchronize mutable state. AVFSpatialCustomVideoCompositorSample/Compositing/MonoOutputCompositor.swift:71
Suspension boundary async declaration or closure The source declares or crosses an asynchronous boundary; it does not by itself establish background execution. AVFSpatialCustomVideoCompositorSample/Compositing/VideoCompositionBuilder.swift:26
Task creation Task The source creates an unstructured task; surrounding context determines inherited actor isolation. AVFSpatialCustomVideoCompositorSample/ContentView.swift:56
Main isolation @MainActor The cited annotation marks its attached declaration or closure as main-actor isolated. AVFSpatialCustomVideoCompositorSample/Export/ReaderWriterExporter.swift:178
Main isolation Task closure isolated to MainActor The cited operation explicitly enters a main-actor-isolated region. AVFSpatialCustomVideoCompositorSample/Export/ReaderWriterExporter.swift:178

@MainActor/MainActor.run, DispatchQueue.main, and RunLoop.main are reported as distinct isolation, queue, and event-loop mechanisms. A plain Task is kept separate from Task.detached; neither is labeled as a background thread.

Reference code

AVFSpatialCustomVideoCompositorSample/Compositing/MonoOutputCompositor.swift:71 — representative execution boundary

class MonoOutputCompositor: NSObject, AVVideoCompositing {
    // ...
    var sourcePixelBufferAttributes: [String: any Sendable]? = [
        kCVPixelBufferPixelFormatTypeKey as String: [
            kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange,
            kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange
        ]
    ]
    // ...
}

State propagation, frameworks, and dependencies

Evidence limit: an import proves a source-level compilation dependency at the cited line; it does not prove runtime use, architectural adoption, or whether a Swift package is a direct application dependency.

Category Mechanism or module Verified role Evidence
State propagation SwiftUI state property wrapper A SwiftUI property wrapper supplies or observes UI state. AVFSpatialCustomVideoCompositorSample/ContentView.swift:14
State propagation @Observable Observation macro publishes source-visible changes. AVFSpatialCustomVideoCompositorSample/Export/ExportSessionExporter.swift:12
Source import AVFoundation The cited file imports this module; runtime use and architectural role are not inferred. AVFSpatialCustomVideoCompositorSample/Compositing/MonoOutputCompositor.swift:8
Source import os The cited file imports this module; runtime use and architectural role are not inferred. AVFSpatialCustomVideoCompositorSample/AVFSpatialCustomVideoCompositorSample.swift:8
Source import SwiftUI The cited file imports this module; runtime use and architectural role are not inferred. AVFSpatialCustomVideoCompositorSample/AVFSpatialCustomVideoCompositorSample.swift:9
Source import AVKit The cited file imports this module; runtime use and architectural role are not inferred. AVFSpatialCustomVideoCompositorSample/Views/PlayerView.swift:8
Source import CoreImage The cited file imports this module; runtime use and architectural role are not inferred. AVFSpatialCustomVideoCompositorSample/Compositing/PixelBufferHelper.swift:9
Source import Foundation The cited file imports this module; runtime use and architectural role are not inferred. AVFSpatialCustomVideoCompositorSample/Export/FileManagerExtensions.swift:8

receive(on:) describes downstream delivery scheduling, while subscribe(on:) describes upstream subscription/request/cancel scheduling. An import Combine alone establishes neither behavior nor a Store, reducer, Redux, or other application architecture.

Class and protocol design

AVFSpatialCustomVideoCompositorSample/Export/Exporter.swift:39 — representative type boundary

protocol Exporter {
    // ...
    var status: ExporterStatus { get }
    // ...
}
Type Responsibility Depends on or conforms to
VideoCompositionBuilder Incrementally constructs a framework value or graph Concrete collaborators/imported frameworks
ContentView User-interface presentation and input forwarding View
PlayerView User-interface presentation and input forwarding UIViewControllerRepresentable
PlayerView User-interface presentation and input forwarding NSViewRepresentable
SampleModel Feature data or observable state Concrete collaborators/imported frameworks
SettingsView User-interface presentation and input forwarding View
Exporter Defines a capability or collaboration contract Concrete collaborators/imported frameworks
AVFSpatialCustomVideoCompositorSample Represents a feature value or composable behavior App
SpatialVideoCompositionInstruction Owns feature behavior and collaborator lifecycle NSObject, AVVideoCompositionInstructionProtocol
CompositorType Defines a closed set of feature states or choices String, CaseIterable, Identifiable

The source explicitly defines local protocol relationships: ExportSessionExporterExporter, ReaderWriterExporterExporter.

Access control

Symbol Access Verified effect Likely rationale
asset (AVFSpatialCustomVideoCompositorSample/Compositing/VideoCompositionBuilder.swift:12) private Use is restricted to the lexical declaration and same-file extensions allowed by Swift. Inference: keep state mutation or dependency lifetime inside the owning implementation.
compositorType (AVFSpatialCustomVideoCompositorSample/Compositing/VideoCompositionBuilder.swift:13) private Use is restricted to the lexical declaration and same-file extensions allowed by Swift. Inference: keep state mutation or dependency lifetime inside the owning implementation.
videoTrack (AVFSpatialCustomVideoCompositorSample/Compositing/VideoCompositionBuilder.swift:67) private Use is restricted to the lexical declaration and same-file extensions allowed by Swift. Inference: keep state mutation or dependency lifetime inside the owning implementation.
formatDescription (AVFSpatialCustomVideoCompositorSample/Compositing/VideoCompositionBuilder.swift:79) private Use is restricted to the lexical declaration and same-file extensions allowed by Swift. Inference: keep state mutation or dependency lifetime inside the owning implementation.

Reference code

AVFSpatialCustomVideoCompositorSample/Compositing/VideoCompositionBuilder.swift:12 — representative boundary

struct VideoCompositionBuilder {
    // ...
    private let asset: AVAsset
    // ...
}

Swift declarations without a modifier are internal; explicit private, fileprivate, private(set), public, or open entries above are interpreted by language semantics. Objective-C/C samples instead rely on header and implementation boundaries, which are not equivalent to Swift lexical privacy.

Logic ownership and placement

Logic Owning type or file Placement rationale
Incrementally constructs a framework value or graph VideoCompositionBuilder The source’s Builder suffix makes this role explicit.
Feature data or observable state SampleModel The source’s Model suffix makes this role explicit.
User-interface presentation and input forwarding ContentView, PlayerView, SettingsView The source’s View suffix makes this role explicit.

Design patterns

Pattern Source evidence Purpose or tradeoff
Protocol-oriented abstraction AVFSpatialCustomVideoCompositorSample/Export/ExportSessionExporter.swift:13 A local protocol and concrete conformance create an explicit capability boundary.
Builder AVFSpatialCustomVideoCompositorSample/Compositing/VideoCompositionBuilder.swift:10 A builder-named type owns incremental construction.

Naming conventions

  • Types: Builder: VideoCompositionBuilder; Model: SampleModel; View: ContentView, PlayerView, SettingsView.
  • Protocols: Exporter.
  • Methods: build, didDismissSettings, makeUIViewController, updateUIViewController, makeNSView, updateNSView, createExporter, export.
  • Files: AVFSpatialCustomVideoCompositorSample/AVFSpatialCustomVideoCompositorSample.swift, AVFSpatialCustomVideoCompositorSample/Compositing/VideoCompositionBuilder.swift, AVFSpatialCustomVideoCompositorSample/ContentView.swift, AVFSpatialCustomVideoCompositorSample/Views/PlayerView.swift, AVFSpatialCustomVideoCompositorSample/Export/Exporter.swift, AVFSpatialCustomVideoCompositorSample/SampleModel.swift.

Architecture takeaways

  • AVFSpatialCustomVideoCompositorSample is the main source-visible entry or composition anchor for this sample.
  • Framework work reaches AVFoundation, SwiftUI, AVKit, CoreImage through a deliberately small high-level chain; the detailed API graph remains inside the cited implementation files.
  • Stored-property evidence identifies lifecycle collaboration; it does not by itself prove exclusive object ownership.
  • Access-control conclusions separate verified language visibility from the likely design rationale.
  • Local protocol relationships provide an explicit substitution boundary.

Source map

Source file Relevant symbols
AVFSpatialCustomVideoCompositorSample/AVFSpatialCustomVideoCompositorSample.swift Cited implementation, os, SwiftUI, AVFSpatialCustomVideoCompositorSample
AVFSpatialCustomVideoCompositorSample/Export/Exporter.swift Exporter, ExporterType, ExporterStatus, ExportError
AVFSpatialCustomVideoCompositorSample/Compositing/VideoCompositionBuilder.swift Cited implementation, VideoCompositionBuilder, async declaration or closure, SpatialVideoCompositionInstruction, CompositorType
AVFSpatialCustomVideoCompositorSample/Export/ExportSessionExporter.swift Cited implementation, @Observable, ExportSessionExporter
AVFSpatialCustomVideoCompositorSample/Compositing/MonoOutputCompositor.swift Sendable or @Sendable, AVFoundation, MonoOutputCompositor
AVFSpatialCustomVideoCompositorSample/ContentView.swift Task, SwiftUI state property wrapper, ContentView, CoverData
AVFSpatialCustomVideoCompositorSample/Export/ReaderWriterExporter.swift @MainActor, Task closure isolated to MainActor, ReaderWriterExporter
AVFSpatialCustomVideoCompositorSample/Views/PlayerView.swift AVKit, PlayerView
AVFSpatialCustomVideoCompositorSample/Compositing/PixelBufferHelper.swift CoreImage, CompositorError, PixelBufferHelper
AVFSpatialCustomVideoCompositorSample/Export/FileManagerExtensions.swift Foundation, Feature implementation
AVFSpatialCustomVideoCompositorSample/SampleModel.swift SampleModel
AVFSpatialCustomVideoCompositorSample/Views/SettingsView.swift SettingsView
AVFSpatialCustomVideoCompositorSample/Compositing/StereoOutputCompositor.swift StereoOutputCompositor
AVFSpatialCustomVideoCompositorSample/Model/UserSettings.swift UserSettings