An app that plays the viewer's own video files, from a folder, a USB drive, a WebDAV or SMB share, meets many containers and codecs: MKV, AVI, WMV,…

An app that plays the viewer's own video files, from a folder, a USB drive, a WebDAV or SMB share, meets many containers and codecs: MKV, AVI, WMV, disc images, 10-bit H.264, sound formats a TV box has no decoder for. Yonto Player is that kind of app, so it carries two players, and a small rule decides which one a given file starts in. This post is about the Android apps (TV, phone and tablet); Apple versions are on their way.

I think the interesting part of "two players" is not the second player, it is the seam between them. Why the platform player alone is not enough On Android the platform player is ExoPlayer (media3). In my view it is the right default. It uses the device's hardware decoders, shows HDR where the screen can, and works with picture-in-picture and casting. For H.264 and H.265 in MP4, WebM, TS and, on Android, MKV, it is, in my view, what should play.

It reads a fixed set of containers and decodes what the device's decoders decode. A library of arbitrary files goes past both limits: an AVI or a WMV is a container it does not read, and a Hi10P H.264 file or a film whose sound no decoder on the device handles is a file it reads but cannot decode. A second player built on libVLC, a software engine with its own demuxers and decoders, covers a lot of that ground.

The public statement of which player plays what is on the video formats page. The rule is one function Both apps (TV and phone) share the code that decides, in a module with no UI in it. The answer is one of three values: the platform player alone, the software player alone, the platform player first, with the software player ready to take over.

A simplified sketch of the decision (generic names, the real function has a few more inputs): enum class Players { Platform, Software, PlatformThenSoftware } fun playersFor(target: Target, hasSoftware: Boolean, prefersSoftware: Boolean): Players = when { !hasSoftware || target.isLive -> Players. Platform target.isPlaylist -> Players. Platform containerOf(target) in softwareOnly -> Players. Software prefersSoftware && target.namesAFile -> Players. Software else -> Players. PlatformThenSoftware } Reading it top to bottom is the design. A live channel stays in the platform player.

Source disclosure

This is a source-linked briefing. Read the original report from Dev Community .