0

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.

ksysha
  • 312
  • 6
  • 8

1 Answers1

1

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
        )
    )
}
ksysha
  • 312
  • 6
  • 8