Dunfey · Hotel WWDC as data, est. 1983
Front desk everything
Years
Topics

2021 EssentialsAudio & Video

WWDC21 · 8 min · Essentials / Audio & Video

What’s new in AVKit

Learn about enhancements to Picture in Picture and full screen improvements on macOS. Explore the new content source API, and learn how AVPictureInPictureController supports AVSampleBufferDisplayLayer, as well as recommended steps for an app to provide a seamless full screen experience on macOS or in a Mac Catalyst app.

Watch at developer.apple.com ↗

Transcript all transcripts

Code shown on screen · 12 snippets

New canStartPictureInPictureAutomaticallyFromInline property swift · at 1:16 ↗
// New property on AVPlayerViewController / AVPictureInPictureController.
var canStartPictureInPictureAutomaticallyFromInline: Bool { get set }
Setting up AVPictureInPictureController with an AVPlayerLayer swift · at 1:40 ↗
func setupPictureInPicture() {
    // Ensure PiP is supported by current device.
    if AVPictureInPictureController.isPictureInPictureSupported() {
        // Create a new controller, passing the reference to the AVPlayerLayer.
        pictureInPictureController = AVPictureInPictureController(playerLayer: playerLayer)
        pictureInPictureController.delegate = self
        
        // Observe AVPictureInPictureController.isPictureInPicturePossible to update the PiP
        // button’s enabled state.
    } else {
        // PiP isn't supported by the current device. Disable the PiP button.
        pictureInPictureButton.isEnabled = false
    }
}
Starting and stopping picture in picture swift · at 2:11 ↗
@IBAction func togglePictureInPictureMode(_ sender: UIButton) {
    if pictureInPictureController.isPictureInPictureActive {
        pictureInPictureController.stopPictureInPicture()
    } else {
        pictureInPictureController.startPictureInPicture()
    }
}
AVPictureInPictureSampleBufferPlaybackDelegate swift · at 2:56 ↗
public protocol AVPictureInPictureSampleBufferPlaybackDelegate: NSObjectProtocol{

    // Delegate is responsible for:
    //
    // - Supplying playback state information for PiP UI.
    // - Responding to user input from PiP UI.

}
Toggle playback of the video and seek back / ahead 15 seconds swift · at 3:17 ↗
func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController, setPlaying playing: Bool)

func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController, skipByInterval skipInterval: CMTime, completion completionHandler: @escaping () -› Void)
Provide elapsed time information swift · at 3:31 ↗
func pictureInPictureControllerTimeRangeForPlayback(_ pictureInPictureController: AVPictureInPictureController) -> CMTimeRange
Choose appropriate media variant for render size swift · at 3:51 ↗
func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController, didTransitionToRenderSize newRenderSize: CMVideoDimensions)
Update playback state swift · at 4:06 ↗
func pictureInPictureControllerIsPlaybackPaused(pictureInPictureController: AVPictureInPictureController) -> Bool
iOS / MacCatalyst - Persist full screen playback swift · at 6:05 ↗
func playerViewController(_ playerViewController: AVPlayerViewController, willBeginFullScreenPresentationWithAnimationCoordinator coordinator: UIViewControllerTransitionCoordinator) {
    coordinator.animate(alongsideTransition: nil) { context in
        // Keep a strong reference to the playerViewController while in full screen.
        self.detachedPlayerViewController = playerViewController
    }
}
iOS / MacCatalyst - Release the playerViewController swift · at 6:38 ↗
func playerViewController(_ playerViewController: AVPlayerViewController, willEndFullScreenPresentationWithAnimationCoordinator coordinator: UIViewControllerTransitionCoordinator){
    coordinator.animate(alongsideTransition: nil) { context in
        // Stop keeping the playerViewController alive when transition completes,
        self.detachedPlayerViewController = nil
    }
}
Persist full screen playback on macOS swift · at 6:46 ↗
func playerViewWillEnterFullScreen(_ playerView: AVPlayerView) {
    // Start keeping the player view alive while it is not in the view hierarchy.
    self.detachedPlayerView = playerView
}

func playerViewWillExitFullScreen(_ playerView: AVPlayerView) {
    // Stop keeping the player view alive.
    self.detachedPlayerView = nil
}
Restoring UI when exiting full screen swift · at 6:55 ↗
// Restoring UI when exiting full screen

// iOS / MacCatalyst
func playerViewControllerRestoreUserInterfaceForFullScreenExit(_ playerViewController: AVPlayerViewController) async -> Bool {
	// Custom UI restoration logic
	return true
}

// macOS
func playerViewRestoreUserInterfaceForFullScreenExit(_ playerView: AVPlayerView) async -> Bool {
	// custom UI restore logic here		
	return true
}

Resources