Time for some video playback tips on iOS with AVFoundation.

Take these with a grain of salt. Behavior depends on media type, device, and evolves with new OS versions. A fair bit here is focused on HLS, but some suggestions are broadly applicable.
1. Create an AVURLAsset first. Don’t use a URL to initialize a AVPlayer or AVPlayerItem directly. Do this well in advance of when you want playback to start.
2. Load some property on the asset right away whether you need it or not. This triggers a bunch of work a user won’t have to wait for later.

asset.loadValuesAsynchronously(forKeys: [“duration”], … )

I wish this were the interface for _every_ property on a player & item.
3. Connect a player to a player layer before putting an item in the player. And make sure the layer is the expected size you’ll be displaying.

This helps the player load a more appropriate initial variant instead of loading a bunch of data that then has to be thrown away.
4. While not 100% true, act like every time you read a property or invoke a method on an item or a player, the thread will stall and wait for an XPC call to the “real” player in another process. Do it sparingly and try and use other mechanisms…
4.1 After issuing a command (e.g. play, pause, seek, replace item) wait before reading a property or issuing another command. If you don’t wait, AVFoundation may make you wait. Synchronously. 🙅🏽 (this is the somewhat more accurate basis for point 4 above)
4.2 Instead of reading properties on the objects, check the documentation and see if they are KVO compliant. Some are. Some aren’t.
4.3 If you want to know the current time, use periodic or boundary time observers. Don’t read the current time of an item or a player directly.

https://developer.apple.com/documentation/avfoundation/media_playback_and_selection/observing_the_playback_time
4.4 It may be tempting to move some of these occasionally blocking synchronous calls to a background thread. You probably shouldn’t. AVFoundation behaves much better if you call it consistently from the main thread. Follow points 4.1-4.3 to minimize hangs.
5. Use preferredForwardBufferDuration, preferredPeakBitRate, and similar properties to describe your needs and expectations. AVFoundation doesn’t know what type of app it’s in. Consider that Twitter and Netflix users have wildly different expectations.
6. Put an AVPlayerItem in an AVPlayer early to pre-load media.
6.1 Keep an item in a player if the user is likely to see the video again.

Taking an item out of a player purges data that needs to be downloaded again if the video replays. It’s not enough to keep an item or asset around.
6.2 But don’t keep more than a few of these player+playerItem around. They take up memory (with all that cached data) and use a limited pool of decoders. Keep enough of these around, and later video playback will fail.
And finally, don’t sweat it if you can’t follow all these suggestions. You can build a good video experience without them. It all depends what what you’re trying to accomplish.
You can follow @fcanas.
Tip: mention @twtextapp on a Twitter thread with the keyword “unroll” to get a link to it.

Latest Threads Unrolled: