Demo of using AVPictureInPictureController with an AVSampleBufferDisplayLayer
PiP Bug Demo
I believe there is an Apple-level framework issue when using AVPictureInPictureController
with an AVSampleBufferDisplayLayer
content source on macOS
or tvOS
This bug manifests itself with the following consequence: It is not possible to start a PiP session on tvOS
or macOS
when using an AVSampleBufferDisplayLayer
as a content source for AVPictureInPictureController
.
Tested on following platforms:
macOS: 12.0.1 (21A559)
iOS: 15.1 (19B74)
tvOS: 15.1.1 (19J587)
Submitted to Apple as FB9751461
PLEASE NOTE: THIS CODE MUST BE RUN ON REAL DEVICES. SIMULATORS DO NOT SUPPORT THIS NEW PIP API
This project presents 3 apps, one for iOS
, tvOS
, and macOS
– which are all setup to use Picture in Picture with AVSampleBufferDisplayLayer as the content source. This is new API available in iOS 15, tvOS 15, and macOS 12.
For iOS
and tvOS
I have added the Picture in Picture
background mode in Signing and Capabilities (Info.plist entry). There doesn’t seem to be an equivelent on macOS
.
I have also set the AVAudioSession
to .playback
on iOS
and tvOS
which is required to support Picture in Picture. Again, there seems to be no equivelent on macOS
but I could be wrong?
do {
try AVAudioSession.sharedInstance().setCategory(.playback, mode: .moviePlayback)
} catch {
print("Setting category to AVAudioSessionCategoryPlayback failed.")
}
In the relevant apps’ view controller code, the AVPictureInPictureController setup is as follows:
let contentSource = AVPictureInPictureController.ContentSource(sampleBufferDisplayLayer: videoProvider.bufferDisplayLayer, playbackDelegate: self)
pipController = AVPictureInPictureController(contentSource: contentSource)
pipController.delegate = self
On iOS
, as soon as I instantiate AVPictureInPictureController(contentSource: contentSource)
I am receiving delegate callbacks to the AVPictureInPictureSampleBufferPlaybackDelegate
methods:
IOSViewController.pictureInPictureControllerTimeRangeForPlayback(_:)
IOSViewController.pictureInPictureControllerIsPlaybackPaused(_:)
which it seems necessary for the system to call in order to setup Picture in Picture playback.
However, these methods ARE NEVER CALLED on tvOS
or macOS
As a result, pipController.isPictureInPicturePossible
is true
on iOS but is always false
on tvOS and macOS.
I suspect that somewhere in the guts of the AVKit/AVFoundation framework, these delegate methods are not being queried on tvOS
nor macOS
and so PiP setup is never completed and it will always fail.