Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AVPlayer - switching stream quality while playing

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.

like image 218
Eyal Avatar asked Jul 16 '14 20:07

Eyal


2 Answers

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.

like image 119
Sadiq Jaffer Avatar answered Oct 28 '22 14:10

Sadiq Jaffer


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];
like image 37
Michael Frederick Avatar answered Oct 28 '22 13:10

Michael Frederick