What Happens When You Hit Play?

SHUBHAM SHAHSHUBHAM SHAH
2 min read

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 or AVPlayerItemDidPlayToEndTime

🧰 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 files

  • Master 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 !

0
Subscribe to my newsletter

Read articles from SHUBHAM SHAH directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

SHUBHAM SHAH
SHUBHAM SHAH