What happened?
Description:
I am building a custom video player UI on top of AetherEngine (tvOS 26, SwiftUI). I used native Menu with .menuStyle(.button) for subtitle/audio track selection during playback. The menu dropdown flickers — the focused item's highlight blinks on and off while the video is playing.
Root cause: AetherEngine publishes @published var currentTime at ~10 Hz (via addPeriodicTimeObserver(forInterval: 0.1)). Any SwiftUI view that observes the engine (via @EnvironmentObject or mirrored through an @ObservedObject PlayerViewModel) re-renders its body on every tick. This causes SwiftUI to recreate the Menu struct, which tears down the native UIMenu on tvOS and rebuilds it — that's the flicker.
I've tried throttling currentTime in our view model, isolating the menu into a separate ObservableObject, .equatable(), UIViewRepresentable wrappers, and suppressing UI updates while the menu is open. None fully fix it — tvOS treats the native UIMenu as a black box that gets torn down on any parent view-tree update.
Questions:
- Is there a recommended way to attach custom UI (like track selection menus) alongside AetherEngine on tvOS that avoids this?
- Should I be using AVPlayerViewController (the system player) instead of a fully custom UI? Does AetherEngine recommend embedding in AVPlayerViewController?
- Is there a way to observe playback time without getting per-frame @published updates — e.g., a lower-frequency callback or a read-only polling API?
Steps to reproduce
- Load any video with multiple audio/subtitle tracks using AetherEngine
- Build a SwiftUI overlay with a native Menu (.menuStyle(.button)) that reads engine.audioTracks and calls engine.selectAudioTrack(index:)
- Observe the engine via @EnvironmentObject or @ObservedObject in the view that contains the Menu
- Play the video, focus the menu button, press select to open the dropdown
- The focused item inside the dropdown flickers at the engine's currentTime publish rate
AetherEngine version or commit SHA
639fc95
Host app
Custom / my own integration
Platform
tvOS
OS version
tvOS 26.5
Device / chip
Apple TV 4K (3rd Gen)
Playback path
Native AVPlayer
Source media (for playback bugs)
No response
Error codes / log lines
Anything else
No response
What happened?
Description:
I am building a custom video player UI on top of AetherEngine (tvOS 26, SwiftUI). I used native Menu with .menuStyle(.button) for subtitle/audio track selection during playback. The menu dropdown flickers — the focused item's highlight blinks on and off while the video is playing.
Root cause: AetherEngine publishes @published var currentTime at ~10 Hz (via addPeriodicTimeObserver(forInterval: 0.1)). Any SwiftUI view that observes the engine (via @EnvironmentObject or mirrored through an @ObservedObject PlayerViewModel) re-renders its body on every tick. This causes SwiftUI to recreate the Menu struct, which tears down the native UIMenu on tvOS and rebuilds it — that's the flicker.
I've tried throttling currentTime in our view model, isolating the menu into a separate ObservableObject, .equatable(), UIViewRepresentable wrappers, and suppressing UI updates while the menu is open. None fully fix it — tvOS treats the native UIMenu as a black box that gets torn down on any parent view-tree update.
Questions:
Steps to reproduce
AetherEngine version or commit SHA
639fc95
Host app
Custom / my own integration
Platform
tvOS
OS version
tvOS 26.5
Device / chip
Apple TV 4K (3rd Gen)
Playback path
Native AVPlayer
Source media (for playback bugs)
No response
Error codes / log lines
Anything else
No response