Flowplayer · Live connection check

Show a meaningful message when the live stream is not available, and demonstrate automatic re-connection.

Also try by interrupting your internet connection.

Test without hlsjs plugin.

Live stream kindly provided by StreamShow.

<head/>

For smoother HLS playback in modern browsers we load the hlsjs plugin.

<!-- Flowplayer library -->
<script src="//releases.flowplayer.org/7.0.2/flowplayer.min.js"></script>
<!-- Flowplayer hlsjs engine -->
<script src="//releases.flowplayer.org/hlsjs/flowplayer.hlsjs.min.js"></script>

HTML

<style>

.flowplayer {
background: #00abcd;
}
.flowplayer .fp-color-play {
fill: #eee;
}
 
/* customized error display and message */
.flowplayer.is-error .fp-controls {
display: none;
}
.flowplayer.is-error .fp-message {
width: 100%;
height: 100%;
text-align: center;
background-size: contain;
background-repeat: no-repeat;
}
.flowplayer.is-error .fp-message h2,
.flowplayer.is-error .fp-message p {
font-weight: bold;
color: #000;
text-shadow: 1px 1px #fff
}
.flowplayer.is-error .fp-message h2 {
margin-top: 15%;
font-size: 120%;
}

CSS

<script>

If the stream goes offline while viewed the hlsjs engine will continue to connect. A custom xhrSetup will prevent excessive retries and trigger an intentional network error.

By default Flash HLS will retry infinitely to load HLS manifests ("playlists") if the master playlist is present. We limit the amount in the flashls clip configuration to trigger an error with a customized message.

Note: depending on your deployment and the stability of the stream you may have to tweak the timers according to your needs and wishes.

window.onload = function () {
 
var container = document.getElementById("live"),
errImage = new Image(), // to preload error image, see below
timer,
 
player = flowplayer(container, {
ratio: 9/16,
splash: true,
live: true,
clip: {
hlsjs: {
xhrSetup: function () {
if (this.stats.retry > 2) {
// intentionally throw network error
player.trigger("error", [player, {code: 2}]);
}
}
},
flashls: {
// limit amount of retries to load hls manifests in Flash
manifestloadmaxretry: 2
},
sources: [
{ type: "application/x-mpegurl",
src: "http://wms.shared.streamshow.it/canale8/canale8/playlist.m3u8" }
]
}
 
}).on("error", function (e, api, err) {
var delay = 10,
messageElement = container.querySelector(".fp-message");
 
clearInterval(timer);
 
if (err.code === 2 || err.code === 4) {
container.querySelector(".fp-message").style.backgroundImage = "url(" + errImage.src + ")";
messageElement.innerHTML = "<h2>We are sorry, currently no live stream available.</h2>";
messageElement.innerHTML += "<p>Retrying in <span>" + delay + "</span> seconds ...</p>";
 
if (flowplayer.support.flashVideo) {
api.one("flashdisabled", function () {
container.querySelector(".fp-flash-disabled").style.display = "none";
});
}
 
timer = setInterval(function () {
delay -= 1;
messageElement.querySelector("span").innerHTML = delay;
 
if (!delay) {
clearInterval(timer);
api.error = api.loading = false;
container.className = container.className.replace(/\bis-error\b/, "");
api.load(api.conf.clip);
}
 
}, 1000);
}
 
});
 
// preload error image in case of network timeouts
errImage.src = "http://demos.flowplayer.org/media/img/interruption.png";
 

/*
* the following is for demo purposes and simulation only
* do not use in production!
*/
 
var buttons = document.getElementsByTagName("button"),
i;
 
for (i = 0; i < buttons.length; i += 1) {
buttons[i].onclick = function () {
var errorstream = !this.id
? null
: this.id === "dummy"
? "//edge.flowplayer.org/dummy-live.m3u8"
: "//edge.flowplayer.org/non-existent.m3u8";
 
if (player.error) {
// clean retry
player.error = player.loading = false;
container.className = container.className.replace(/ *is-error */, "");
}
 
if (errorstream) {
player.load({
sources: [
{ type: "application/x-mpegurl", src: errorstream }
]
});
} else {
player.load(player.conf.clip);
}
};
}
 
};

JavaScript

<body/>

<div id="live"></div>
 
<!-- for demo purposes only -->
<div class="info">
<p><button id="dummy" type="button">Simulate dummy stream</button>
<button id="nonexistent" type="button">Simulate non existent stream</button>
<button type="button">Play configured stream</button></p>
</div>

HTML

See also this demo.