Skip to content

Instantly share code, notes, and snippets.

@mekya
Last active August 7, 2021 06:15
Show Gist options
  • Save mekya/1a8a5a77f4d9dbc9c3e3bd1483e8b6ca to your computer and use it in GitHub Desktop.
Save mekya/1a8a5a77f4d9dbc9c3e3bd1483e8b6ca to your computer and use it in GitHub Desktop.
Checks the stream speed and plays it accordingly
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Ant Media Server WebRTC/HLS Player</title>
<!-- videojs includes -->
<link href="css/external/video-js.css" rel="stylesheet">
<script src="js/external/video.js"></script>
<script
src="js/external/videojs-http-streaming.js"></script>
<!-- end of video js includes -->
<script src="js/fetch.js"></script>
<script src="js/promise.min.js"></script>
<script src="js/external/adapter-latest.js"></script>
<script src="js/external/dash.all.min.js"></script>
<link href="css/player.css" rel="stylesheet">
</head>
<body>
<div id="video_info">
Stream will start playing automatically<br />when it is live
</div>
<!-- HLS Player -->
<div id="video_container">
<video id="video-player"
class="video-js vjs-default-skin vjs-big-play-centered"
controls preload="auto">
<p class="vjs-no-js">
To view this video please enable JavaScript, and consider upgrading
to a web browser that <a
href="http://videojs.com/html5-video-support/" target="_blank">supports
HTML5 video</a>
</p>
</video>
</div>
<!-- WebRTC Player -->
<video id="remoteVideo" controls playsinline></video>
<div id="networkWarning">Your connection isn't fast enough to play this stream!</div>
<img id="play_button" src="images/play.png" onclick="playWebRTCVideo()"
style="position: absolute; top: 30px; left: 30px; display: none;" />
<script type="module">
/**
* This page accepts 4 arguments.
* 1. "id": the stream id to play.It is mandatory
* 2. "token": the token to play stream. It's mandatory if token security is enabled on server side.
* 3. "autoplay": To start playing automatically if streams is available. Optional. Default value is true
* 4. "mute": To start playing with mute if streams is available. Optional. Default value is true
* 5. "playOrder": the order which technologies is used in playing. Optional. Default value is "webrtc,hls".
* possible values are "hls,webrtc","webrtc","hls","vod","dash"
* 6. "playType": the order which play type is used in playing. Optional. Default value is "mp4,webm".
* possible values are "webm,mp4"","mp4","webm"
* 7. "targetLatency": To define target latency for the DASH player. Optional. Default value is 3.
*/
import {WebRTCAdaptor} from "./js/webrtc_adaptor.js"
import {getUrlParameter, isMobile, tryToPlay, tryToVODPlay} from "./js/fetch.stream.js"
//The play order, player tries to play according to this order, if it can not play then tries following format
var playOrder = getUrlParameter("playOrder");
if (playOrder == null) {
playOrder = ["webrtc", "hls"];
}
else {
playOrder = playOrder.split(',');
}
var streamId = getUrlParameter("id");
if (streamId == null) {
//check name variable for compatibility with older versions
streamId = getUrlParameter("name");
}
var playType = getUrlParameter("playType") ;
if (playType == null || playType=="mp4,webm"){
playType = ["mp4", "webm"];
}
else if(playType == "webm,mp4") {
playType=["webm", "mp4"];
}
else if(playType == "mp4"){
playType=["mp4"];
}
else if(playType == "webm"){
playType=["webm"];
}
var token = getUrlParameter("token");
var pAutoplay = getUrlParameter("autoplay");
var mute = getUrlParameter("mute");
var targetLatency = getUrlParameter("targetLatency");
var placeHolder = document.getElementById("video_info");
if(targetLatency == "null"){
targetLatency = 3;
}
var hlsExtension = "m3u8";
var dashExtension = "mpd";
var subscriberId = getUrlParameter("subscriberId");
var subscriberCode = getUrlParameter("subscriberCode");
var autoPlay = true;
if (pAutoplay == "false" || isMobile()) {
autoPlay = false;
}
if (mute == "true" || mute == null) {
mute = true;
}
else{
mute = false;
}
var webRTCAdaptor = null;
var streamsFolder = "streams";
function genericCallback(currentTech) {
placeHolder.innerHTML="Stream will start playing automatically<br/>when it is live";
setTimeout(function()
{
var index = playOrder.indexOf(currentTech);
if (index == -1 || index == (playOrder.length-1)) {
index = 0;
}
else {
index++;
}
var tech = playOrder[index];
if (tech == "webrtc")
{
// It means there is no HLS stream, so try to play WebRTC stream
if (webRTCAdaptor == null) {
initializeWebRTCPlayer(streamId, token, webrtcNoStreamCallback);
}
else {
webRTCAdaptor.getStreamInfo(streamId);
}
}
else if (tech == "hls")
{
tryToPlay(streamId, token, hlsExtension, subscriberId, subscriberCode, hlsNoStreamCallback);
}
else if (tech == "dash")
{
var dashFile = streamId + "/" + streamId;
tryToPlay(dashFile, token, dashExtension, subscriberId, subscriberCode, dashNoStreamCallback);
}
}, 3000);
}
function webrtcNoStreamCallback() {
/**
* If HLS is in the play order then try to play HLS, if not wait for WebRTC stream
* In some cases user may want to remove HLS from the order and force to play WebRTC only
* in these cases player only waits for WebRTC streams
*/
genericCallback("webrtc");
}
function hlsNoStreamCallback()
{
genericCallback("hls");
}
function setHLSElementsVisibility(show){
document.getElementById("video_container").style.display= show == true ? "block" : "none";
}
function hideWebRTCElements(){
setWebRTCElementsVisibility(false);
document.getElementById("play_button").style.display="none";
}
function setWebRTCElementsVisibility(show) {
document.getElementById("remoteVideo").style.display = show == true ? "block" : "none";
}
function setPlaceHolderVisibility(show) {
placeHolder.style.display = show == true ? "block" : "none";
}
function playWebRTCVideo() {
setWebRTCElementsVisibility(true);
if(mute){
document.getElementById("remoteVideo").muted=true;
}
else{
document.getElementById("remoteVideo").muted=false;
}
if(autoPlay){
document.getElementById("remoteVideo").play().then(function(value){
//autoplay started
document.getElementById("play_button").style.display="none";
}).catch(function(error) {
document.getElementById("play_button").style.display="block";
console.log("User interaction needed to start playing");
});
}
}
function initializePlayer(streamId, extension, token, subscriberId, subscriberCode) {
hideWebRTCElements();
startPlayer(streamId, extension, token, subscriberId, subscriberCode)
}
window.initializePlayer = initializePlayer
window.playWebRTCVideo = playWebRTCVideo
function getHLSPlayer() {
var preview = streamId;
if (streamId.endsWith("_adaptive")) {
preview = streamId.substring(0, streamId.indexOf("_adaptive"));
}
return videojs('video-player', {
poster: "previews/"+preview+".png"
});
}
function startPlayer(streamId, extension, token, subscriberId, subscriberCode) {
var type;
var liveStream = false;
if (extension == "mp4") {
type = "video/mp4";
liveStream = false;
}
else if (extension == "webm") {
type = "video/webm";
liveStream = false;
}
else if(extension == "mov"){
type = "video/mp4";
alert("Browsers do not support to play mov format");
liveStream = false;
}
else if(extension == "avi"){
type = "video/mp4";
alert("Browsers do not support to play avi format");
liveStream = false;
}
else if (extension == "m3u8") {
type = "application/x-mpegURL";
liveStream = true;
}
else if (extension == "mpd") {
type = "application/dash+xml";
liveStream = true;
}
else {
console.log("Unknown extension: " + extension);
return;
}
var preview = streamId;
if (streamId.endsWith("_adaptive")) {
preview = streamId.substring(0, streamId.indexOf("_adaptive"));
}
// If it's not dash, play with videojs
if(extension != dashExtension){
var player = getHLSPlayer();
player.src({
src: "streams/" + streamId + "." + extension + "?token=" + token + "&subscriberId="+subscriberId +"&subscriberCode="+subscriberCode,
type: type,
withCredentials: true,
});
player.poster("previews/"+preview+".png");
if(mute){
player.muted(true);
}
else{
player.muted(false);
}
if (autoPlay) {
player.ready(function() {
player.play();
});
}
}else{
var player = dashjs.MediaPlayer().create();
player.updateSettings({'streaming': {'lowLatencyEnabled': true}});
player.updateSettings({
'streaming': {
'liveDelay': targetLatency,
'liveCatchUpMinDrift': 0.05,
'liveCatchUpPlaybackRate': 0.5,
"liveCatchupLatencyThreshold": 30,
}
});
player.initialize(document.querySelector("#video-player"), "streams/" + streamId + "." + extension + "?token=" + token, false);
if(mute){
player.setMute(true);
}
else{
player.setMute(false);
}
if (autoPlay && player.isReady()) {
player.play();
}
setInterval(function() {
console.log("live latency: " + player.getCurrentLiveLatency());
}, 2000);
}
//Check HLS player is finished. If finished page should be reload
if (typeof player.ready != "undefined" )
{
player.ready(function(){
var player = this;
player.on('ended', function() {
console.log("Playing has been finished");
hideWebRTCElements();
setHLSElementsVisibility(false);
setPlaceHolderVisibility(true);
tryToPlay(streamId, token, hlsExtension, subscriberId, subscriberCode, hlsNoStreamCallback);
});
});
}
else {
console.log("player ready is not available. List playing may not be continous");
}
setHLSElementsVisibility(true);
setWebRTCElementsVisibility(false);
setPlaceHolderVisibility(false);
}
setInterval(function() {
var appName = location.pathname.substring(0, location.pathname.lastIndexOf("/")+1);
var path = location.hostname + ":" + location.port + appName + "rest/v2/broadcasts/" + streamId;
var httpURL = "http://" + path;
if (location.protocol.startsWith("https")) {
httpURL = "https://" + path;
}
fetch(httpURL, {method: 'GET'})
.then(function(response) {
if (response.status == 200) {
return response.json();
}
return null;
}).then(function(stream){
var player = getHLSPlayer();
if (stream != null) {
if (stream.status == "broadcasting" ) {
if (stream.speed > 0.9) {
var isPaused = player.paused();
console.log("player is paused -> " + isPaused);
if (isPaused)
{
tryToPlay(streamId, token, hlsExtension, subscriberId, subscriberCode);
}
}
else
{
player.pause();
//show placeholder
hideWebRTCElements();
setHLSElementsVisibility(false);
setPlaceHolderVisibility(true);
}
}
else {
//stop and hide all players
player.pause();
//show placeholder
hideWebRTCElements();
setHLSElementsVisibility(false);
setPlaceHolderVisibility(true);
console.log("stream is offline");
}
}
else {
//stop and hide all players
player.pause();
//show placeholder
hideWebRTCElements();
setHLSElementsVisibility(false);
setPlaceHolderVisibility(true);
console.log("there is no stream with the stream id: " + streamId);
}
});
}, 5000);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment