What Happens When You Hit Play?

Whether you’re new to streaming or an iOS dev curious about how video gets from server to screen — this post is for you. Lets dive into!
🧱 1. Begins with HLS
Apple's default streaming protocol is HLS — HTTP Live Streaming. It breaks video into chunks (called segments) of a few seconds each.
When you hit play:
The app fetches a .m3u8 manifest file
This manifest lists available quality levels (bitrate ladders)
Based on your network, a suitable stream is picked
➡️ URL ➝ master.m3u8
➝ variant_720p.m3u8
➝ segment1.ts
➝ segment2.ts
🎬 2. AVPlayer Takes Over
Apple’s AVPlayer is the workhorse. Once you provide it the streaming URL:
let player = AVPlayer(url: hlsURL)
player.play()
AVPlayer automatically:
Parses the playlist
Handles adaptive bitrate (ABR) switching
Manages playback buffer
Talks to decoders behind the scenes
You don’t have to handle this manually — but understanding it helps you debug and optimize better.
📦 3. CDN Fetching and Buffering
Segments are fetched from CDNs (like Akamai, Cloudflare, or Fastly). Downloads 2–3 segments (~6–10 seconds) ahead of what’s being shown. This forms the buffer.
If the network drops:
AVPlayer plays from buffer
If recovery takes too long → stall occurs
Player switches to lower bitrate to avoid rebuffering
🧠 4. From Byte to Frame: Decoding
Once the segment arrives:
- Frames are rendered onto the screen — usually at 30 or 60 FPS
If the CPU or GPU is overwhelmed, or decoding lags, you might see:
Dropped frames
Janky playback
Lag behind live
⚠️ 5. ABR, Stall Recovery & Playback Events
AVPlayer constantly listens to:
Network conditions
Buffer status
Player timebase
It may:
Switch to a lower bitrate if bandwidth drops
Retry failed segments
Notify you via
AVPlayerItemPlaybackStalled
orAVPlayerItemDidPlayToEndTime
🧰 Bonus: Minimal AVPlayer Code Example
import AVKit
let url = URL(string: "https://yourstream.com/live.m3u8")!
let player = AVPlayer(url: url)
let playerVC = AVPlayerViewController()
playerVC.player = player
present(playerVC, animated: true) {
player.play()
}
🧭 What’s Next?
This was just the start. In the next post, we’ll go deeper into:
🎯 “What is HLS and why does Apple love it?”
You’ll learn:
The anatomy of
.m3u8
filesMaster vs Variant playlists
Bitrate ladders
How ABR really works
🧵 Part of the Streaming 101 Series
Stay tuned on Streaming Demystified for more insights into AVFoundation, video streaming, and iOS engineering at scale.
💬 Have questions, thoughts, or feedback?
Reply below or connect with me on LinkedIn if you're building or thinking about video, media, mobile tech !
Subscribe to my newsletter
Read articles from SHUBHAM SHAH directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by