how my player picks video quality without a streaming engine
most players pick quality from the network speedometer. navigator.connection.downlink gives you megabits... once. mobile networks swing hard. 5g at midnight is not the same 5g at 9pm, and a reading taken at minute zero says nothing about minute forty. this is a build diary. full disclosure up front: i'm the developer of RKMovies , a tiny media player client (0.91 mb apk, system decoders, zero…
In a recent development, a media player developer revealed the secret behind the app's ability to automatically select video quality without relying on a streaming engine. The RKMovies player, weighing in at just 0.91 MB, achieves this feat by leveraging system decoders like MediaCodec on Android and NVDec and QuickSync on Windows. This approach eliminates the need for a dedicated ABR module, allowing the video element to handle playback directly.
The auto mode in RKMovies operates in two layers. The first layer uses the downlink speedometer to make an initial guess about the appropriate video quality. For instance, a 5 Mbps or higher connection starts at 1080p, while 2.5 Mbps leads to 720p, and 1 Mbps leads to 480p. For lower resolutions, the default quality is set to 360p. This strategy ensures that budget phones on 4G networks receive a reasonable start instead of attempting to load 4K content, which would likely result in poor playback.
The second layer of the auto mode is where the magic happens. A 4-second interval is used to monitor the video.buffered property and measure how many seconds of video are available ahead of the playhead. The player does not rely on the network's claims but rather focuses on what has actually arrived. If buffered ahead exceeds 22 seconds for four consecutive checks, the resolution is stepped up.
Conversely, if buffered ahead remains under 1.5 seconds for two consecutive checks, the resolution is stepped down. This approach ensures that the picture remains sharp when the network conditions are favorable, while preventing unnecessary quality jumps when the buffer is insufficient.
To strike the right balance, the developer implemented a rule that allows only one step up or down at a time, in either direction. This prevents the picture from becoming jittery and turning into a yo-yo effect between different resolutions. By taking small steps and waiting for a consistent buffer, the player can maintain a stable and high-quality viewing experience.
The smooth transition between resolutions is achieved through a function called smoothSwitchQuality(). This function captures the current playback time, swaps the video source, waits for the loadedmetadata event, seeks back to the original playback time, and then resumes playback. This process typically costs the user no more than half a second, making it nearly imperceptible. The entire switch occurs within a single frame, ensuring a seamless experience for the user.
Interestingly, the 4-second interval used for monitoring the buffer also incurs minimal costs. It involves reading a single property and performing one comparison operation. Despite its simplicity, this monitoring mechanism proved to be effective in preventing oscillation, where the player would frequently jump between resolutions due to false positives in the buffer measurements.
The buffering logic implemented in RKMovies is straightforward but effective, relying on a single property and a few comparisons. While more sophisticated approaches like per-fragment stats and bandwidth estimators exist, the developer chose this simpler method to keep the player lightweight and efficient, fitting within the 0.91 MB constraint.
For developers looking to implement a similar auto-quality feature, the ad-free 4K player for Android and a Windows desktop app with the same auto mode are available as reference implementations.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.