Skip to content

SharePlay Coordinated Playback

When a SharePlay activity plays media, AVFoundation owns the timeline — not your messenger. A playback coordinator negotiates play, pause, seek, rate, stalls, and interruptions across every participant, and hands you an absolute host-clock time to start at.

Part of Axiom's SharePlay coverage — start at the SharePlay overview if you're not sure which page you need.

One skill in the axiom-media suite: skills/shareplay-playback.md. Session lifecycle, activation, and non-media state live in shareplay.

When to Use

Use this skill when you're:

  • Adding SharePlay to an audio or video app
  • Adapting a custom playback engine (AVAudioEngine, SFBAudioEngine, a game mixer) to AVDelegatingPlaybackCoordinator
  • Debugging playback that drifts, starts late, or won't start until someone seeks
  • Handling a participant who stalls while everyone else keeps playing
  • Deciding what belongs on the coordinator versus the messenger

Example Prompts

  • "How do I sync playback across SharePlay participants?"
  • "How do I adopt AVDelegatingPlaybackCoordinator with my custom audio engine?"
  • "My coordinated playback drifts between devices."
  • "When should I begin an AVCoordinatedPlaybackSuspension?"
  • "Why does playback stay local when I call play()?"

Key Concepts

The coordinator is a clock agreement protocol

It is not a message bus with play and pause verbs. AVDelegatingPlaybackCoordinatorPlayCommand.hostClockTime tells you when, in CMClockGetHostTimeClock() terms, playback should begin at a given item time. That is why broadcasting positions over GroupSessionMessenger cannot reach parity — the messenger has no clock.

Two paths, and the difference is large

With AVPlayer the coordinator already exists at player.playbackCoordinator; connect it with coordinateWithSession(_:), keep driving the player normally, and interruptions, stalls, and interstitials produce automatic suspensions.

With a custom engine you adopt AVDelegatingPlaybackCoordinator, which adds no automatic suspensions. You begin and end every one yourself.

The custom-engine contract is four methods

AVPlaybackCoordinatorPlaybackControlDelegate requires play, pause, seek, and buffering handlers — all sharing one overloaded Swift name, playbackCoordinator(_:didIssue:). There is no rate-change callback. The coordinator holds the delegate weakly, so an adapter nothing else retains stops receiving commands silently.

A suspension you never end can hang the group

Six built-in reasons cover the cases — audio session interruption, stall recovery, interstitials, coordinated playback not possible, user action required, and scrubbing — and the type is extensible, so custom strings are allowed. Blocking happens only for reasons listed in suspensionReasonsThatTriggerWaiting, and only below that reason's limit set via setParticipantLimit(_:forWaitingOutSuspensionsWithReason:); those are the levers if you need to stop blocking others. To decide whether it is safe to end one while others kept playing, ask expectedItemTime(atHostTime:) where the group is now.

AVPlaybackCoordinationMedium is not your transport

It synchronizes several local players (multiview, camera angles, commentary). It excludes delegating coordinators entirely, and it is mutually exclusive with a group session on the same coordinator.

Common Mistakes

MistakeCostFix
Broadcasting current time on a timerReinvents clock agreement, badlyUse the playback coordinator
Starting playback immediately on a play commandDrift on every deviceSchedule to hostClockTime
Resuming after a seek commandDesynchronizes the groupWait for the next play command
Beginning a suspension and never ending itOther participants wait on you, for the waiting-triggering reasonsAlways pair begin with end
Letting the adapter be deallocatedPlayback silently goes localRetain it; the coordinator won't
Acting on stale commandsWrong track playsCheck expectedCurrentItemIdentifier
  • shareplay – Session lifecycle and activation, which you need before any playback coordination happens
  • GroupActivities referencecoordinateWithSession(_:) and the surrounding session API
  • avfoundation-ref – The wider AVFoundation playback surface

Resources

WWDC: 2021-10225, 2023-10239, 2024-10114, 2025-302

Docs: /avfoundation/avplaybackcoordinator, /avfoundation/avdelegatingplaybackcoordinator, /avfoundation/avcoordinatedplaybacksuspension

Released under the MIT License