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

Debugging AVFoundation audio mixes, compositions, and video compositions

At a glance

Item Summary
Purpose Build a two-clip composition and visualize its tracks, transitions, opacity ramps, and audio ramps during playback.
App architecture Storyboard UIKit controller coordinates a domain-style editor, AVPlayer, and a custom diagnostic view.
Main patterns MVC, builder, framework validation delegate, and projection of media objects into drawing data.
Project style Files are grouped into Editor and DebugView, with the screen controller at the app root.

Project structure

AVCompositionDebugViewer/
├── PlayerViewController.swift       # Screen composition and playback
├── Editor/
│   ├── SimpleEditor.swift           # Composition/mix builder
│   └── SimpleEditorUtils.swift      # Asset and timestamp helpers
├── DebugView/
│   ├── CompDebugView.swift          # Timeline diagnostic view
│   ├── CompDebugViewUtils.swift     # AV object-to-drawing transforms
│   └── CompDebugViewCAUtils.swift   # Layer drawing helpers
└── Media/                           # Two bundled clips

Structure observations

  • Editing and visualization are separate subsystems connected through one AVPlayerItem.
  • Helpers are colocated by consumer (Editor versus DebugView) rather than placed in a generic utilities folder.
  • The storyboard owns the controller/view hierarchy; code owns media objects.

Overall architecture

Reference code

AVCompositionDebugViewer/PlayerViewController.swift:48 — composition assembled for two consumers

self.editor = SimpleEditor(completion: {
    self.playerItem = AVPlayerItem(asset: self.editor.composition())
    self.playerItem.videoComposition = self.editor.videoComposition()
    self.playerItem.audioMix = self.editor.audioMix()
    self.compositionDebugView.synchronize(with: self.playerItem)
})

Interpretation

PlayerViewController is the composition root and MVC controller. SimpleEditor creates the media model. The same configured player item drives playback and diagnostic rendering, so the visualizer examines the exact objects the player uses.

Ownership and state

Ownership evidence

AVCompositionDebugViewer/PlayerViewController.swift:18 and AVCompositionDebugViewer/Editor/SimpleEditor.swift:38 — controller and editor resources

private var playerViewController = AVPlayerViewController()
private var player = AVPlayer()
private var playerItem: AVPlayerItem!
private var editor: SimpleEditor!

private lazy var editorComposition: AVMutableComposition = { /* ... */ }()
private var editorAudioMix = AVMutableAudioMix()
Owner Object or state Relationship Mutation authority
Storyboard/view hierarchy PlayerViewController, outlets, debug/player views Instantiates and retains UI UIKit lifecycle; outlets are weak references
PlayerViewController Editor, player, player item, child player controller Creates and retains Controller lifecycle and editor completion
SimpleEditor Clips, composition, video composition, audio mix, time ranges Creates and builds Private editor methods
CompositionDebugView Retained player item and derived drawing arrays Receives item, derives snapshots synchronize(with:) and private drawing methods

Class and protocol design

AVCompositionDebugViewer/Editor/SimpleEditor.swift:28 — validation callback boundary

class SimpleEditor: NSObject, AVVideoCompositionValidationHandling {
    // ... builder methods ...
    func videoComposition(
        _ videoComposition: AVVideoComposition,
        shouldContinueValidatingAfterFindingEmptyTimeRange timeRange: CMTimeRange
    ) -> Bool { false }
}
Type Responsibility Depends on
PlayerViewController Orchestrate editing, playback, child containment, and debug synchronization UIKit, AVKit, SimpleEditor
SimpleEditor Load clips and construct aligned composition, transitions, and audio ramps AVFoundation
CompositionDebugView Render composition structure and synchronized scrub animation UIKit, Core Animation, AVFoundation
CompositionTrackSegmentInfo, VideoCompositionStageInfo Drawing-oriented snapshots CoreMedia and simple values
AVVideoCompositionValidationHandling Report invalid composition details during validation AVFoundation protocol

Access control

Symbol Access Verified effect Likely rationale
Controller’s player, item, editor, and child controller private Other types cannot replace playback/editing ownership. Keeps screen orchestration invariant inside the controller.
Editor clips, compositions, time ranges, queues, and builder methods private Consumers only receive the three finished AV objects. Enforces staged construction through SimpleEditor.
Debug view drawing layers, derived arrays, context, and geometry private Callers can synchronize an item but cannot manipulate rendering internals. Presents a narrow diagnostic-view API.
trackSegmentInfo(from:segments:) and ramps(from:) helpers private free functions Callable only within CompDebugViewUtils.swift. Hides lower-level transforms behind file-level functions.
App classes and top-level utility functions otherwise internal by default Reusable only in this app target. No external library surface is intended.

Reference code

AVCompositionDebugViewer/DebugView/CompDebugView.swift:62 — public operation, private render state

class CompositionDebugView: UIView {
    private var compositionTrackSegmentInfo = [[CompositionTrackSegmentInfo]]()
    private var volumeRampAsPoints = [[CGPoint]]()
    private var videoCompositionStages = [VideoCompositionStageInfo]()

    func synchronize(with playerItem: AVPlayerItem) { /* derive snapshots */ }
}

Logic ownership and placement

Logic Owning type or file Placement rationale
Screen and child-controller lifecycle PlayerViewController UIKit controller responsibility
Clip loading and timestamp suitability SimpleEditor / SimpleEditorUtils Precondition for composition construction
Track insertion and transition overlap SimpleEditor.createComposition Mutates the composition aggregate
Video instructions and audio ramps SimpleEditor.createVideoCompAndAudioMix Builds coordinated outputs from the same ranges
Convert AV objects into drawing values CompDebugViewUtils.swift Pure transformations separated from rendering
Timeline drawing and synchronized layer animation CompositionDebugView View-specific behavior

Design patterns

Pattern Source evidence Purpose or tradeoff
MVC AVCompositionDebugViewer/PlayerViewController.swift:14 Controller joins storyboard views to media model objects.
Builder AVCompositionDebugViewer/Editor/SimpleEditor.swift:251, AVCompositionDebugViewer/Editor/SimpleEditor.swift:304 Constructs several interdependent AVFoundation artifacts in defined stages.
Delegate AVCompositionDebugViewer/Editor/SimpleEditor.swift:28, AVCompositionDebugViewer/Editor/SimpleEditor.swift:376 Receives detailed validation failures through a framework protocol.
Projection/view model values AVCompositionDebugViewer/DebugView/CompDebugViewUtils.swift:25, AVCompositionDebugViewer/DebugView/CompDebugViewUtils.swift:119 Converts complex AV objects into arrays that are straightforward to draw.

Naming conventions

  • SimpleEditor signals sample-scale scope; its accessors use AV object names (composition, videoComposition, audioMix).
  • Debug types use Composition, TrackSegment, and Stage vocabulary from the visualized domain.
  • Builder methods use create...; transformation helpers name the value they return (volumeRampPoints, videoCompStageInfo).
  • Files are grouped and named by subsystem responsibility.

Architecture takeaways

  • Drive playback and diagnostics from the same configured AVPlayerItem to avoid mismatched state.
  • Keep mutable composition construction behind a small finished-object interface.
  • Convert framework graphs into simple drawing snapshots before entering rendering code.
  • Framework delegate protocols provide useful diagnostic seams even without app-defined protocols.

Source map

Source file Relevant symbols
AVCompositionDebugViewer/PlayerViewController.swift screen composition and playback
AVCompositionDebugViewer/Editor/SimpleEditor.swift SourceClip, SimpleEditor, validation callbacks
AVCompositionDebugViewer/Editor/SimpleEditorUtils.swift asset/timestamp helpers
AVCompositionDebugViewer/DebugView/CompDebugView.swift drawing value types, CompositionDebugView
AVCompositionDebugViewer/DebugView/CompDebugViewUtils.swift AV object-to-drawing transforms