0

I am using an AVPlayer to play video. I would like to be able to loop sections of the video based on the user's input (while the video is playing, the user can press a button to start a loop and then press it once more to end after a few seconds pass -- then it should begin playing at the start time and continue to loop once the current time reaches the specified end time)

I can get these start/end loop times just by getting the player's currentTime

var startLoop : CMTime = player.currentTime()
// seconds pass by ....
var endLoop : CMTime = player.currentTime()

I know there is a way to cleanly loop the video back to the beginning once it has finished playing like so:

NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: self.player.currentItem, queue: .main) { [weak self] _ in
      self?.player?.seek(to: CMTime.zero)
      self?.player?.rate = self?.rate ?? 1.0
}

I was wondering if there is a way to do this with my custom startLoop and endLoop times?

spitchay
  • 89
  • 1
  • 10

1 Answers1

2

There are a few ways to do looping in AVFoundation. The simple way is like you described by listening to the notification and then calling seek(to: startLoop). you can use addBoundaryTimeObserver to listen for specific time.

https://developer.apple.com/documentation/avfoundation/avplayer/1388027-addboundarytimeobserver

However, a more advanced way to do looping is to try to add a Key Value Observer to AVQueuePlayer and try inserting 2 copies of an AVPlayerItem with the specific range of the looping asset you want. Then you can use looping techniques such as the treadmill technique or AVPlayerLooper. The key to creating custom time ranged assets is to use an AVMutableComposition and insertTimeRange.

Also, if you really want to be experimental, you can try a 3rd option which is possibly using an AVMutableComposition as your original source asset and start mutating its underlying tracks on the fly while it is playing. I've tried something similar and it can work if you are not manipulating time ranges that are being played. However, there is no docs on this approach and Apple may change code in future versions that may break this.

References:

https://developer.apple.com/videos/play/wwdc2016/503/

https://developer.apple.com/library/archive/samplecode/avloopplayer/Introduction/Intro.html

https://developer.apple.com/library/archive/samplecode/AVCustomEdit/Introduction/Intro.html

Recommended way of updating timeRange property on AVPlayerLooper

@spitchay reach out to me if you have other AVFoundation questions.

ucangetit
  • 2,595
  • 27
  • 21
  • Thank you for your answer. How would I go about doing the first method? (Creating a Notification for a custom CMTime -- in this case, endLoop) – spitchay Aug 31 '19 at 21:06
  • @spitchay I've updated my answer to include a link to https://developer.apple.com/documentation/avfoundation/avplayer/1388027-addboundarytimeobserver – ucangetit Sep 02 '19 at 22:08