0

I have two AVPlayer() items playing videos of the same duration (10 seconds). The goal is to have them loop and stay in sync with one another. I add them as sublayers of the same UIView and then call player.play() on each one of them.

The problem though is that as code execution obviously has the slightest delay as one is called after the other one, the videos are out of sync (although only a few milliseconds, it is noticeable).

I do not have the option to create an AVMutableComposition as I have seen other posts suggest, so is there anyway to have two separate players truly stay in sync and play EXACTLY at the same time?

Thank you!

simplexity
  • 1,527
  • 1
  • 13
  • 31
  • Possible duplicate of [How to schedule iOS method call at exact time](https://stackoverflow.com/questions/22866066/how-to-schedule-ios-method-call-at-exact-time) – Tamás Sengel Aug 07 '17 at 15:13
  • as per my understanding, create two views with respectively classes having avplayer implemented with functionToPlayVideo in both classes. add both views to your viewcontroller you are using. Now add oberserver in both view classes having selector "functionToPlayVideo". now post notification should work. – Aadil Ali Aug 07 '17 at 15:16
  • @AadilAli Very interesting idea indeed. I never thought of using the notification listeners to be used in this way. I'll give it a try. – simplexity Aug 07 '17 at 15:20
  • @simplexity pls acknowledge. Don't forget to remove observer. – Aadil Ali Aug 07 '17 at 15:31
  • @AadilAli Perhaps I am not understanding how notifications work in this manner. Could you provide an answer with some kind of example that could help get me started with multiple notification listeners. Trying to search SO without avail... – simplexity Aug 07 '17 at 16:11

1 Answers1

5

If you want to achieve the sync, you should load the videos separately with AVPlayer and observe the AVPlayerItemStatus property of each player. Only when all of the players have the status .readyToPlay you can loop through the players and set the .rate property.

Edit:

You can also synchronize them by using setRate(_:time:atHostTime:). Don't forget begin loading media data using preroll(atRate:completionHandler:) before calling setRate. Basically:

  • wait for readyToPlay
  • preroll(atRate:completionHandler:) when all players are ready
  • setRate(_:time:atHostTime:) when all players were prerolled
Andrey Gershengoren
  • 896
  • 1
  • 5
  • 18
  • so when I loop through the players and set the rates, as long as the .readytoplay is good, it wouldn't have that same synchronous processing delay? – simplexity Aug 07 '17 at 17:08