Avplayer

AVPlayer

Listeners

Observer to see when the video playback started

player = AVPlayer(url: URL(fileURLWithPath: path))
player.addObserver(self, forKeyPath: "rate", options: NSKeyValueObservingOptions.new, context: nil)

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if keyPath == "rate" {
        if player.rate > 0 {
            print("video started")
        }
    }
}

Knowing when AVPlayer object is ready to play

How to detect AVPlayer actually started to play in swift

How to detect user selection of subtitles when using AVPlayerViewController

Tracks

Selecting Tracks AV Media Playback

Selecting Subtitles and Alternative Audio Tracks

AVAsset

Media playback

Subtitles

closed captioning for mobile and tv

Muting Audio

if IsMuted == false {
      IsMuted = true
      musicPlayer.volume = 0
    } else {
      IsMuted = false
      musicPlayer.volume = 1
    }
}

Optimization

You can call AVPlayer.play() even when there is no AVPlayerItem in the player yet. Player records intention and when you attach playerItem, you save few milliseconds because player doesn't need to generate static image.

Sound

A playback category should not obey the mute switch

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
	try? AVAudioSession.sharedInstance()
	.setCategory(AVAudioSession.Category.playback)
	try? AVAudioSession.sharedInstance()
	.setActive(true)
}

SO | Make sound in vibrate DND mode

In case you end up here, because this solution won't work on iPad, but only on iPhone: I just had that issue when setting the AVAudioSession category before presenting a AVPlayerViewController. If I set the category in the completion block of the presentViewController call (and before actually calling play()) it works fine on both device families.

AVPlayerLayer

3 Steps

  • Wrap it in UIViewRepresentable to have compatibility from UIKit to SwiftUI.
  • Make subclass of UIView with private instance of AVPlayerLayer()
  • Show it in some View struct swiftUI - call it from step 1 view created.

SO | avplayer in vstack swiftUI

PiP

Picture in Picture support

I don't think AVPlayer needed to do anything for PiP, too. There is audio focus handling but that's separate.
As long as appropriate flags are being set, we can utilize this native functionality provided by apple iOS / iPadOS.

Reference

Apple Old | AVFoundation Programming Guide

playing-video-avplayer-swiftui

AVPlayer SwiftUI | Github