
Trickplay support is coming to JellySee — and to every AVPlayer-based Jellyfin client for tvOS.
The problem. AVPlayer (the native iOS/iPadOS/tvOS player behind JellySee, Infuse, MrMC, Apple TV+, etc.) renders transport-bar scrubbing thumbnails by reading #EXT-X-I-FRAME-STREAM-INF in the HLS master playlist. Jellyfin has never emitted that line — so when you grab the scrubber on Apple TV, the bar is blank. The fix. A Jellyfin server plugin that:
- Encodes a small SDR H.264 I-frame-only fMP4 per item — one frame every two seconds by default (configurable). Hardware-accelerated decode (VideoToolbox / QSV / VAAPI / NVENC / AMF / RKMPP / D3D11VA / v4l2m2m, auto-mapped from your Jellyfin hwaccel setting), software encode on libx264 ultrafast. Runs in the background via on-playback warmup, library-add events, and a nightly pre-gen task. Survives crashes, plugin upgrades, and power loss — interrupted encodes auto-resume on next boot.
- Rewrites Jellyfin's HLS playlists to advertise the I-frame variant so AVPlayer picks it up natively.
Works for both Jellyfin's transcode flow (master.m3u8 injection) and clients that build their own HLS URL pointing at main.m3u8 directly (synthetic-master wrap). Live admin dashboard: per-item cache status, real-time encoding progress with ETA and ffmpeg speed, per-library
coverage bars, search/regenerate/evict. Daily pruner with configurable orphan cleanup, age-based eviction, and total-size cap so the cache never grows unbounded. Install today and SDR trickplay works immediately on JellySee, Swiftfin, and other AVPlayer clients via HLS. No app update required. It is smooth and Apple quality.
JellySee 2.4.4 is in review with the app review team, and once released, it will enable trickplay for HDR and Dolby Vision content on the app.
Repo: https://github.com/HarshLabs/jellyfin-plugin-native-trickplay
This plugin was 100% vibe coded, as I have no C# knowledge, but works pretty darn well and solves the biggest issue with Trickplay via HLS on Apple's native video player. I hope the Jellyfin team uses this plugin as a reference to implement this kind of feature directly into the server so we wont need it.
When you watch a media that does not have the iframe playlist generated, it will automatically queue it for you and start the generation. Once complete, it will work, but you will have to restart the stream so it can be properly delivered to the client.
These iframe playlists can get large so you can control the pruning and eviction policy from the dashboard or granularly control it/having it generate automatically as the user watches content. Priority queue is also part of the system, so lets say you have 5 active encodes processing, if a user watches something, and it needs to generate the iframe playlist, it will be the next one in queue
End result: best in class scrubbing