Building a Custom AVPlayer on tvOS: Tips and Best Practices

03 / Sep / 2025 by Chandra Shekhar Rai 0 comments

Introduction

Apple’s AVPlayer is the core of media playback on iOS, macOS, and tvOS. On Apple TV, most developers start with AVPlayerViewController for its built-in controls, subtitles, and “Up Next.”
But when you need custom branding, interactive overlays, or advanced analytics, its limitations quickly appear. That’s when building a custom AVPlayer experience becomes essential along with managing performance, focus, and UX. In this guide, we’ll explore the best practices for crafting a polished tvOS player.

1. Architecture: Choosing the Right Setup

There are two common patterns:

  • AVPlayerViewController: Good for quick setup.
  • AVPlayer + AVPlayerLayer (custom UI): Needed for branded OTT apps.

Recommended Approach:

Start with AVPlayer and attach it to an AVPlayerLayer inside your own UIView (or UIViewController).
Build your controls/UI separately, so you can update them independently of playback logic.

This separation keeps responsibilities clear and makes your player easier to extend.

  • PlayerEngine: Manages playback state, observers, bitrate, etc.
  • PlayerUI: Handles visuals like buttons, scrubbers, and skip-intro prompts.

2. Performance & Memory Management:

On tvOS, performance is crucial. Unlike iPhones, Apple TV apps run on limited hardware optimised for streaming, not heavy multitasking.

Recommended Approach:

  • Use one AVPlayer instance whenever possible. Multiple instances = high GPU/CPU load.
  • Use AVQueuePlayer if you need sequential playback instead of juggling multiple AVPlayers.
  • Always call replaceCurrentItem(with:) instead of creating new players for every video.
  • Release old AVPlayerItems to avoid memory leaks.

Profiling in Instruments > Allocations shows if your AVPlayerItems are still in memory after switching videos. If they are, check for forgotten observers or strong reference cycles.

3. Adaptive Bitrate (ABR) Tuning

By default, AVPlayer handles HLS quality shifts automatically, adapting to network and CPU conditions.
However, there are cases where you’ll want more control, such as:

  • Enabling data-saver modes
  • High-quality defaults for premium subscribers
  • Analytics correlation with bitrate switching

Recommended Approach:

  • Use preferredPeakBitRate to guide the max quality.
  • Observe AVPlayerItemAccessLog for stalls and bitrate switches to detect network issues.

Don’t hardcode bitrates. Instead, let users choose (Auto / Medium / High) and map that to dynamic preferredPeakBitRate thresholds. This balances user control with ABR intelligence.

4. Custom Controls & Focus Engine

On tvOS, the Focus Engine is central to navigation. Improper handling can severely impact usability.

Recommended Approach:

  • Always define a logical navigation flow between play/pause, scrub bar, and overlays.
  • Use UIFocusGuide to connect UI elements that aren’t visually adjacent but should be reachable.
  • Handle remote gestures separately:
    • Tap → Play/Pause
    • Swipe → Seek/Skip
    • Long press → Context menu (e.g., audio/subtitles)

Focus conflicts often occur when custom buttons are placed over an AVPlayerLayer. To avoid this, set canBecomeFocused = false on non-interactive UI elements to help reduce focus chaos.

5. Subtitle & Audio Track Management

Viewers expect smooth subtitle and audio track switching.

Recommended Approach:

  • Fetch media groups directly from the asset by using below code:

if let audiogroup = asset.mediaSelectionGroup(forMediaCharacteristic: .audible) {
player.currentItem?.select(group.options[0], in: group)
}

if let subtitleGroup = asset.mediaSelectionGroup(forMediaCharacteristic: .legible) {
player.currentItem?.select(group.options[0], in: group)
}

  • Provide a custom, branded selector instead of relying on Apple’s small default menu.
  • Persist user preferences across sessions (e.g., last-used subtitle language).

For multi-language OTT platforms, consider preloading subtitle files (WebVTT/TTML) from your CMS rather than only using HLS-embedded captions. This gives you more flexibility in styling and control.

6. Seamless Next Episode & Recommendations

Recommended Approach:

  • Use AVContentProposal to show episode previews before playback ends.
  • Preload the next AVPlayerItem during the last 30s of the current video for instant transition.

Test memory usage while preloading. If you preload too early or buffer too much, tvOS will aggressively reclaim memory, possibly evicting your cached items.

7. Overlays & Interactivity

Overlays like ads, polls, or sports stats can be powerful, but if not tuned well, they quickly ruin the viewing experience.

Recommended Approach:

  • Keep overlays GPU-friendly (simple views, avoid heavy blur effects).
  • Hide overlays automatically if the user doesn’t interact.
  • Ensure smooth Siri Remote swipe navigation and avoid trapping focus where it isn’t needed.

For live streams, consider showing overlays as time-synced events using AVPlayerItemMetadataCollector. This avoids drift in long live streams.

8. Playback State Handling

A robust player must gracefully handle every edge case.

Recommended Approach:

  • Observe “AVPlayerItem.status” to detect readiness.
  • Listen for “.AVPlayerItemDidPlayToEndTime” observer for next-episode logic.
  • Catch stalls with “.AVPlayerItemPlaybackStalled” and trigger UI feedback (“Reconnecting…”).

For live streams, always expose a “jump to live” button. Use seek(to: playerItem.duration) when users drift behind real-time.

9. Testing & Debugging

Most playback issues appear on real devices, not in the simulator

Recommended Approach:

  • Always test on actual Apple TV hardware.
  • Simulate weak or unstable networks with Charles Proxy or Network Link Conditioner.
  • Validate long-duration playback (e.g., multi-hour streams).
  • Monitor memory and CPU with Instruments while scrubbing aggressively

10. UX Considerations

TV apps are experienced from 6–10 feet away, not up close like mobile.

Recommended Approach:

  • Design large, high-contrast, minimal buttons for readability.
  • Give clear feedback on remote actions (e.g., “+10s”, “-10s”).
  • Keep the playback screen uncluttered and make overlays contextual and easy to dismiss.
  • Follow Apple’s tvOS HIG to align with user expectations.

Conclusion

Customizing AVPlayer on tvOS is both a technical and design challenge. When done well, it unlocks:

  • Smooth performance: memory-efficient, stable, and crash-free playback.
  • Branded experiences: custom UIs, interactive overlays, and distinctive player features.
  • Higher engagement: seamless next-episode transitions, recommendations, and binge-friendly flows.
  • User trust: predictable remote interactions, consistent focus handling, and reliable playback. The key is striking the right balance between freedom and discipline. By following best practices, you can build a player that not only looks and feels premium but also delivers a fluid, professional, OTT-grade experience ready to scale to millions of viewers.
FOUND THIS USEFUL? SHARE IT

Leave a Reply

Your email address will not be published. Required fields are marked *