Understanding AVFoundation and MediaPlayer frameworks in iOS

Issue #210

Depending on what features we want to achieve, we need to go with either AVFoundation or MediaPlayer framework. As someone who worked with many apps that involve media playback, here are some of my observations

MPMoviePlayerController vs AVPlayer

At first, I use MPMoviePlayerController because it is very simple, in fact, it is a wrapper around AVPlayer. It offers a lot of useful notifications and properties.

But when my requirements change, a lot more features are needed, I need to change to AVPlayer to have more control. And that is the wisest decision I’ve ever made

You should use AVPlayer as soon as possible. Using it cost you just a little longer time than MPMoviePlayerController, but you have a lot of control.

Custom controls

When building your own player, the built in controls of MPMoviePlayerController may not satisfy your need. I see many questions on SO are about custom controls.

MPMoviePlayerController

You have to set controlStyle to MPMovieControlStyleNone, set up Timer because currentPlaybackTime is not KVO compliance

AVPlayer

AVPlayer has no built in controls, but it has addPeriodicTimeObserverForInterval:queue:usingBlock: that makes handling the current time easily. The nicer thing about periodTimeObserver is that “The block is also invoked whenever time jumps and whenever playback starts or stops”

Notification

MPMoviePlayerController

It has a lot of useful notifications, like MPMoviePlayerNowPlayingMovieDidChangeNotification, MPMoviePlayerLoadStateDidChangeNotification, MPMovieDurationAvailableNotification, …

AVPlayer

The AVPlayerItem has some notifications AVPlayerItemDidPlayToEndTimeNotification, AVPlayerItemPlaybackStalledNotification, …
If you want to have those same notifications as MPMoviePlayerController, you have to KVO some properties of AVPlayer like currentItem, currentTime, duration, … You have to read documents to make sure which property is KVO compliance

Seek

MPMoviePlayerController

You can change the currentPlaybackTime to seek, but it results in jumping, because of efficiency and buffer status. I have to manually disable slider during seeking

AVPlayer

AVPlayer has this seekToTime:toleranceBefore:toleranceAfter:completionHandler: which allows you to specify the tolerance. Very nice

Subtitle

MPMoviePlayerController

I have to schedule a timer that “wake” and “sleep” at the beginning and end time of a certain subtitle marker, respectively.

AVPlayer

AVPlayer has this addBoundaryTimeObserverForTimes:queue:usingBlock: that perfectly suits my need. I setup 2 boundary time observers, 1 for the beginning times, 1 for the end times. The beginning times is an array containing all beginning timestamps that a subtitle marker appears.

Time scale

AVPlayer uses CMTime that offers timescale, which is a more comfortable way to specify more accurate time

Volume

AVPlayer has volume property (relative to system volume) that allows me to programmatically changes the player volume

Playable duration

MPMoviePlayerController

It has playableDuration property

AVPlayer

You have to compute yourself. See http://stackoverflow.com/questions/6815316/how-can-i-get-the-playable-duration-of-avplayer

Full screen

MPMoviePlayerController achieves full screen mode by creating another UIWindow, you learn from this to support full screen using AVPlayer, too

Movie Source Type

MPMoviePlayerController

It has movieSourceType that provides clues to the playback system, hence improving load time

“ If you know the source type of the movie, setting the value of this property before playback begins can improve the load times for the movie content.”

AVPlayer

Read Handling Different Types of Asset on AV Foundation Programming Guide

“To create and prepare an HTTP live stream for playback. Initialize an instance of AVPlayerItem using the URL. (You cannot directly create an AVAsset instance to represent the media in an HTTP Live Stream.)”

AVAsset

AVPlayer allows you to access AVAsset, which provides you more information about the playback and load state

Allow a range within a video to be playable

AVPlayerItem has forwardPlaybackEndTime and reversePlaybackEndTime that is used to specify a range that the player can play. When forwardPlaybackEndTime is specified and the playhead passes this points, AVPlayerItem will trigger AVPlayerItemDidPlayToEndTimeNotification

But it doesn’t work in my case forwardPlaybackEndTime does not work

You can have many instances of AVPlayer playing at the same time

Read more

  1. AV Foundation Programming Guide
  2. WWDC 2011 Session 405 Exploring AV Foundation
  3. WWDC 2011 Session 415 Working With Media In AV Foundation
  4. WWDC 2014 Session 503 Mastering Modern Media Playback
  5. WWDC 2011 Session 406 AirPlay and External Displays in iOS apps
  6. AVPlayerDemo
  7. VKVideoPlayer
  8. ALMoviePlayerController
  9. AV Foundation Playing Videos
  10. AVPlayer and MPMoviePlayerController differences
  11. MPMoviePlayer Tips

Comments