I have an AvPictureInPictureController
that should display an image while playing audio. I have created a AVSampleBufferDisplayLayer
that has a CMSampleBuffer
with an image and the two necessary delegates AVPictureInPictureSampleBufferPlaybackDelegate
& AVPictureInPictureControllerDelegate
I am setting
pictureInPictureController.requiresLinearPlayback = false
so the picture in picture window is showing the seek back, play/pause and seek forward buttons.
Here is my function for the time range:
func pictureInPictureControllerTimeRangeForPlayback(_ pictureInPictureController: AVPictureInPictureController)
-> CMTimeRange {
let duration = player.state.duration
if duration == 0 {
return CMTimeRange(start: .negativeInfinity, duration: .positiveInfinity)
}
return CMTimeRange(
start: CMTime(
seconds: .zero,
preferredTimescale: 10_000
),
duration: CMTimeMakeWithSeconds(
duration,
preferredTimescale: 10_000
)
)
}
My problem is, that seek forward is disabled on picture in picture. Seeking back is working just fine, also play/pause. But seek forward is disabled and I haven't figured out why this is happening. Any thoughts?
I tried to calculate the CMTimeRange
differently but it is always the same behaviour.
I found this project https://github.com/getsidetrack/swiftui-pipify/blob/main/Sources/PipifyController.swift#L250 where the CMTimeRange
is calculated from the CACurrentMediaTime()
and although I am not sure why there is such a big time range calculated (like taking one week in seconds) CACurrentMediaTime()
was the right hint.
So this is how the the pictureInPictureControllerTimeRangeForPlayback
looks like now:
func pictureInPictureControllerTimeRangeForPlayback(
_ pictureInPictureController: AVPictureInPictureController
) -> CMTimeRange {
if player.duration == 0 {
return CMTimeRange(start: .negativeInfinity, duration: .positiveInfinity)
}
let currentTime = CMTime(
seconds: CACurrentMediaTime(),
preferredTimescale: 60
)
let currentPosition = CMTime(
seconds: state.position,
preferredTimescale: 60
)
return CMTimeRange(
start: currentTime - currentPosition,
duration: CMTime(
seconds: player.duration,
preferredTimescale: 60
)
)
}