Trick to switch fast between HLS qualities using VideoJs player with Nuevo plugin
Nuevo plugin for videojs player has option to detect and display available video qualities or resolutions from HLS stream automatically if only your HLS presentation (m3u8 playlist) has multiple bitrate variants for the same content.
The list of possible qualites/resolutions appears on "loadeddata" event and later user is allowed to choose video quality from dedciated menu. For many reasons that HLS is great, but it also has faults when it comes to latency. When changing an adaptive stream in HLS (changing quality/resolution), it demands a new buffer to be built. Apple defaults 10-second content chunks requires about 30 seconds to to create a meaningful playback buffer for new buffer (new quality/resolution). When latency and user-experience really matters for you, there are some methods to tune HLS chunks to make visible difference. Just read an article on Wowza Blog to learn about HLS latency problem and how to fix it or rather improove a little.
However even if you reduce the size and increase the number of your video chunks, still changing between video qualities/resolutions will result in few seconds latency. Solution for much faster quality/resolution change is to use same technique as it is used for standard MP4 video.
Video quality picker designed by Nuevolab for Nuevo plugin is pretty complex and smart code. It allows to define multiple m3u8 playlists for quality selector in same way as it is done for standard MP4 files. What's more it still alows to use a list of fallback MP4 or Webm video files! This is how it is done in video example above:
None other poblic plugin or player allows for such complex video sources setup.
- Fist video source points to main m3u8 playlist with link to specific chunks m3u8 playlists.
- Second and next video sources point to next specific bitrate single m3u8 playlist files(5 in example above).
- Next sources are mp4 video files paths, used as fallback when HLS playback is not supported by browsser.
- Finally in player initialization code setup you must disable default hlsQualities Nuevo plugin option
See the code setup example:
<video id="myplayer" class="video-js vjs-default-skin" poster="//domain.com/path/to/poster.jpg" controls preload="auto">
<source src="//domain.com/path/to/playlist.m3u8" type="application/x-mpegURL">
<source src="//domain.com/path/to/playlist_1080p.m3u8" type="application/x-mpegURL">
<source src="//domain.com/path/to/playlist_720p.m3u8" type="application/x-mpegURL">
<source src="//domain.com/path/to/playlist_540p.m3u8" type="application/x-mpegURL">
<source src="//domain.com/path/to/playlist_360p.m3u8" type="application/x-mpegURL">
<source src="//domain.com/path/to/playlist_270p.m3u8" type="application/x-mpegURL">
// MP4 Fallback
<source src="//domain.com/path/to/video_1080p.mp4" type="video/mp4">
<source src="//domain.com/path/to/video_720p.mp4" type="video/mp4">
<source src="//domain.com/path/to/video_540p.mp4" type="video/mp4">
<source src="//domain.com/path/to/video_360p.mp4" type="video/mp4">
<source src="//domain.com/path/to/video_270p.mp4" type="video/mp4">
// Optionally to override HTML native playback
videojs.options.hls.overrideNative = true;
videojs.options.html5.nativeAudioTracks = false;
videojs.options.html5.nativeTextTracks = false;
//Initialize videojs player
var player = videojs('myplayer');
The method with multiple HLS m3u8 playlists does not require much more resources. You use same chunk files, and only need to prepare m3u8 playlist variants, each separate for single resolution. Each playlist is like main playlist containing a link to specific resolution list of chunks and a link to audio stream(s).
Same rules may concern MPEG-DASH playlists and standard video fallback. For multiple Mpeg/Dash playlists you must disable default Nuevo plugin option dashQualities