Table of Contents |
---|
...
Overview
The player shows how to convert stream published on WCS server to HLS and play it in browser using HLS.js. HLS stream segments cut starts automatically when strea stream is requested by HLS URL, for example http`https://localhost:8082test1.flashphoner.com:8445/test/test.m3u8` on the screenshot below
Since build 2.0.244, the example supports the following parameters:
- llhls - enable Low Latency HLS support:
false
ortrue
- rc - stream full HLS URL to play, should be encoded with URI, for example
https%3A%2F%2Ftest1.flashphoner.com%3A8445%2Ftest%2Ftest.m3u8
- autoplay - automatically play the HLS URL, in this case all the input fields and buttons are hidden:
false
(by default) ortrue
The player URL example with parameters as displayed on the screenshot above (the link is available in Permalink
field)
Code Block | ||
---|---|---|
| ||
https://test1.flashphoner.com:8444/client2/examples/demo/streaming/hls-js-player/hls-js-player.html?llhls=false&src=https%3A%2F%2Ftest1.flashphoner.com%3A8445%2Ftest%2Ftest.m3u8 |
The player URL example with autoplay enabled
Code Block | ||
---|---|---|
| ||
https://test1.flashphoner.com:8444/client2/examples/demo/streaming/hls-js-player/hls-js-player.html?llhls=false&src=https%3A%2F%2Ftest1.flashphoner.com%3A8445%2Ftest%2Ftest.m3u8&autoplay=true |
In this case the stream should be played automatically with audio muted. A viewer should use a loud slider in the player interface to unmute audio.
The code of the example
The source code can be accessed on server by the following path:
...
hls-js-player.css - player page styles file
hls-js-player.html - player page
hls.js - player script (https://github.com/video-dev/hls.js/, Apache License Version 2.0)
hls-js-player.js - player launch script
hls.min.js - player script (minimized)
../hls-player/player-page.html - common player page elements for three HLS playback examples
The example can be tested using the fiollowing URL:
...
Where host is WCS server address
Analyzing the code
To analize analyze the code get hls-js-player.js file version with hash ecbadc3 1703e13 which is available here and can be downloaded in build 2.0.212244.
1. A server HLS URL detectiongetHLSUrl() Loading the player page
Code Block | ||||
---|---|---|---|---|
| ||||
function initPageconst loadPlayerPage = function() { $loadPage("#header").text("HLS.JS Player Minimal"); $("#urlServer").val(getHLSUrl()); ... } |
2. div element set up to pass to the player
...
../hls-player/player-page.html", "playerPage", initPage );
} |
2. The player HTML page initializing
If browser does not support MSE, player will not be initialized and a warning will be displayed
Code Block | ||||
---|---|---|---|---|
| ||||
const initPage = function initPage(() { if (playSrc) { setValue("fullLink", decodeURIComponent(playSrc)); } else if (autoplay) { ...console.warn("No HLS URL set, autoplay disabled"); autoplay = false; } if (llHlsEnabled) { setCheckbox("llHlsEnabled", llHlsEnabled); } remoteVideo = document.getElementById('remoteVideo'); if remoteVideo.style ="background-color: lightgrey;"; } |
3. Stream name detection (the stream should be published to server)
encodeURIComponent() code
Code Block | ||||
---|---|---|---|---|
| ||||
function playBtnClick() { if (validateForm()) (Hls.isSupported()) { console.log("Using HLS.JS " + Hls.version); if (autoplay) { // There should not be any visible item on the page unless player hideAllToAutoplay(); // The player should use all available page width setUpPlayerItem(true); // The player should be muted to automatically start playback initVideoPlayer(remoteVideo, true); playBtnClick(); } else { setText("header", "HLS.JS Player Minimal"); showItem("llHlsMode"); displayCommonItems(); setUpButtons(); enablePlaybackStats(); // The player should have a maximum fixed size setUpPlayerItem(false); // The player can be unmuted because user should click Play button initVideoPlayer(remoteVideo, false); } } else { var streamName = $('#playStream').val(setText("notifyFlash", "Your browser doesn't support MSE technology required to play video"); disableItem("applyBtn"); streamName = encodeURIComponent(streamName);toggleInputs(false); } } |
3. Video tag initializing to play
Code Block | ||||
---|---|---|---|---|
| ||||
const initVideoPlayer = function(video, muted) { if (video) { video.style.backgroundColor = "black"; video.muted = muted; } } |
4. HLS HLS stream URL forming
If authentication key and token are set, they will be inclueded to stream URL
Code Block | ||||
---|---|---|---|---|
| ||||
function playBtnClick(const getVideoSrc = function(src) { let videoSrc = src; if (validateForm()) { let streamName ...= getValue('playStream'); varstreamName = encodeURIComponent(streamName); videoSrc = $getValue("#urlServerurlServer").val() + '/' + streamName + '/' + streamName + '.m3u8'; varlet key = $getValue('#keykey').val(); varlet token = $getValue("#tokentoken").val(); if (key.length > 0 && token.length > 0) { videoSrc += "?" + key + "=" + token; } } ...setValue("fullLink", videoSrc); }return videoSrc; } |
5. Player startingHLS.js player configuration
If browser does not support MSE, player will not be started and a warning will be displayed
Code Block | ||||
---|---|---|---|---|
| ||||
function playBtnClick(const getHlsConfig = function(llHlsEnabled) { let if (validateForm())config = { ... lowLatencyMode: false, enableWorker: true, if (Hls.isSupported()) { backBufferLength: 90, manifestLoadingTimeOut: 15000 }; console.log("Low Latency HLS: "+llHlsEnabled) hlsPlayer = new Hls(getHlsConfigif(llHlsEnabled)); { // Here we configure hlsPlayer.loadSource(videoSrc); HLS.JS for lower latency config hlsPlayer.attachMedia(remoteVideo);= { hlsPlayer.on(Hls.Events.MANIFEST_PARSED, function() { lowLatencyMode: llHlsEnabled, enableWorker: true, console.log("Play with HLS.js"); backBufferLength: 90, remoteVideo.play();liveBackBufferLength: 0, liveSyncDuration: 0.5, onStarted(); liveMaxLatencyDuration: 5, });liveDurationInfinity: true, } else {highBufferWatchdogPeriod: 1, $("#notifyFlash").text("Your browser doesn't support MSE technology required to play video")manifestLoadingTimeOut: 15000 }; } } }return config; } |
6. Playback stoppingPlayer launching
Code Block | ||||
---|---|---|---|---|
| ||||
function stopBtnClickconst playBtnClick = function() { iflet (hlsPlayervideoSrc != null) {getVideoSrc(getValue("fullLink")); console.log("Stop HLS segments loading"); if (videoSrc) { llHlsEnabled = hlsPlayer.stopLoad(getCheckbox("llHlsEnabled"); hlsPlayer = null new Hls(getHlsConfig(llHlsEnabled)); } if (remoteVideo != nullhlsPlayer.on(Hls.Events.MANIFEST_PARSED, function() { console.log("StopPlay HTML5with playerHLS.js"); remoteVideo.pauseplay(); remoteVideo.currentTime = 0}); remoteVideo.removeAttribute('src'); onplaying = () => { remoteVideo.load(); } console.log("playing event onStopped(fired"); } |
7. HLS.js player configuration
Code Block | ||||
---|---|---|---|---|
| ||||
function getHlsConfig(llHlsEnabled) { var config = {displayPermalink(videoSrc); lowLatencyMode: false,} enableWorker: true,hlsPlayer.loadSource(videoSrc); backBufferLength: 90hlsPlayer.attachMedia(remoteVideo); }; ifonStarted(llHlsEnabled); { // Here we configure HLS.JS for lower latency } } |
7. Playback stopping
Code Block | ||||
---|---|---|---|---|
| ||||
const stopBtnClick = function() { if config(hlsPlayer != null) { console.log("Stop HLS lowLatencyMode: llHlsEnabled,segments loading"); enableWorker: true,hlsPlayer.stopLoad(); hlsPlayer backBufferLength: 90,= null; } if (remoteVideo != liveBackBufferLength: 0,null) { console.log("Stop liveSyncDuration: 0.5,HTML5 player"); liveMaxLatencyDuration: 5,remoteVideo.pause(); remoteVideo.currentTime liveDurationInfinity: true,= 0; highBufferWatchdogPeriod: 1,remoteVideo.removeAttribute('src'); }remoteVideo.load(); } return configonStopped(); } |