6

I'm using AVPlayer to play youtube videos, for each youtube video id I retrieve a couple of stream urls in different qualities.

I want to play a particular stream quality according to the network state. For example if user is on 3G I want to play the lowest quality URL but if user moves to wifi I want to seamlessly switch to the better quality stream.

This is nothing new, youtube is doing that in their app and many others.

So I wonder what is the best way to do this kind of switching with AVPlayer, I don't want the user to notice the switching as possible, without pausing the video playback or buffering.
Any advices?

I'm not sure if this kind of functionality is supported on the youtube servers or if I need to do it on client side.

pedros
  • 1,197
  • 10
  • 18
Eyal
  • 10,777
  • 18
  • 78
  • 130

3 Answers3

9

You should have a look at the Apple documentation on HTTP live streaming.

The only way to achieve the type of switching that you want and is talked about in the documentation is the use of m3u index files and TS files containing the video data.

You connect to the index file and store its contents, which will be multiple URL's along with bandwidth requirements. See the examples here. Then use the Reachability class to check network status and connect to the appropriate stream. Start the Reachability notifier and react to events by changing the stream you're connected to. This will cause the TS file that belongs to the stream to be downloaded and buffered for playback, achieving the type of switching you want.

As I previously said, the drawback is the requirement to use TS files. This would mean you video files would have to be downloaded from Youtube, prepared using the Apple provided mediafilesegmenter command line tool and the stored on an FTP server! Not ideal at all but as far as I'm aware the only way to do this.

Sadiq Jaffer
  • 500
  • 2
  • 10
3

Check out the AVPlayer replaceCurrentItemWithPlayerItem: method. If I were you, I would use Reachbility to observe the user's network status. When the network reachability degrades, you can do something like this:

AVPlayerItem *item = [AVPlayerItem playerItemWithURL:urlOfLowerQuality];
[item seekToTime:player.currentTime];
[player replaceCurrentItemWithPlayerItem:item];
vishal dharankar
  • 7,536
  • 7
  • 57
  • 93
Michael Frederick
  • 16,664
  • 3
  • 43
  • 58
  • 1
    Might be better to use - (void)seekToTime:(CMTime)time completionHandler:(void (^)(BOOL finished))completionHandler and then call [player replaceCurrentItemWithPlayerItem:playerItem]; as part of the completion handler – Sadiq Jaffer Jul 28 '14 at 09:07
  • keep in mind you have to call it on main thread and unregister kvo before calling replaceCurrentItemWithPlayerItem other wise application will crash for further details checkout http://stackoverflow.com/questions/14579458/avplayeritem-replacecurrentitemwithplayeritem-blocking/32728640 – Fahad Rehman Aug 24 '16 at 07:15
  • hello. can you explain how to use Reachbility to observe the user's network status. – famfamfam Sep 30 '19 at 08:09
0

Use ReachabilityManager to check current status of data type either wifi or 3G. According to data mode switch url type.While Switching url take current time of video and need to set seek time of video.

user3279053
  • 187
  • 1
  • 10