You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
RTSPtoWeb/web/templates/fullscreenmulti.tmpl

982 lines
31 KiB
Cheetah

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>RTSPtoWEB</title>
<link rel="stylesheet" href="/../static/plugins/fontawesome-free/css/all.min.css">
<link rel="stylesheet" href="/../static/css/adminlte.min.css">
<link rel="stylesheet" href="/../static/plugins/sweetalert2/sweetalert2.min.css">
<link rel="stylesheet" href="/../static/css/index.css">
<link rel="stylesheet" href="/../static/css/fullmulti.css">
<link href="/../static/css/google-fonts.css" rel="stylesheet">
</head>
<body class="hold-transition layout-top-nav img-background">
<div class="wrapper">
<!-- Navbar -->
<nav class="main-header navbar navbar-expand-md navbar-light navbar-dark">
<div class="container-fluid">
<button class="navbar-toggler order-1" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse order-3" id="navbarCollapse">
<ul class="order-1 order-md-3 navbar-nav navbar-no-expand ml-auto">
{{ if .query.controls}}
<li class="nav-item dropdown">
<a href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="nav-link dropdown-toggle"><i class="fas fa-photo-video"></i></a>
<div class="dropdown-menu dropdown-menu-right custom-dropdown">
<div class="custom-dropdown-item with-img" onclick="changeBackground('back')">
<img src="/../static/img/back.jpg" />
</div>
<div class="custom-dropdown-item with-img" onclick="changeBackground('red')">
<img src="/../static/img/red.jpg" />
</div>
<div class="custom-dropdown-item with-img" onclick="changeBackground('green')">
<img src="/../static/img/green.jpg" />
</div>
<div class="custom-dropdown-item with-img" onclick="changeBackground('white')">
<img src="/../static/img/white.jpg" />
</div>
</div>
</li>
{{end}}
<li class="nav-item dropdown">
<a id="defaultGrid" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="nav-link dropdown-toggle"><i class="fas fa-th-large"></i></a>
<div aria-labelledby="defaultGrid" class="dropdown-menu dropdown-menu-right custom-dropdown">
<div class="custom-dropdown-item grid-maker" grid="1" onclick="gridMaker(1)">
1 x 1
</div>
<div class="custom-dropdown-item grid-maker" grid="4" onclick="gridMaker(4)">
2 x 2
</div>
<div class="custom-dropdown-item grid-maker" grid="6" onclick="gridMaker(6)">
3 x 2
</div>
<div class="custom-dropdown-item grid-maker" grid="9" onclick="gridMaker(9)">
3 x 3
</div>
<div class="custom-dropdown-item grid-maker" grid="12" onclick="gridMaker(12)">
4 x 3
</div>
<div class="custom-dropdown-item grid-maker" grid="16" onclick="gridMaker(16)">
4 x 4
</div>
<div class="custom-dropdown-item grid-maker" grid="25" onclick="gridMaker(25)">
5 x 5
</div>
<div class="custom-dropdown-item grid-maker" grid="36" onclick="gridMaker(36)">
6 x 6
</div>
<div class="custom-dropdown-item grid-maker" grid="49" onclick="gridMaker(49)">
7 x 7
</div>
</div>
</li>
{{ if .query.controls}}
<li class="nav-item dropdown">
<input type="hidden" id="defaultPlayer" value="mse" />
<a id="defaultPlayerMenu" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="nav-link dropdown-toggle">MSE</a>
<ul aria-labelledby="defaultPlayerMenu" class="dropdown-menu custom-dropdown">
<li><a href="#" class="dropdown-item" onclick="defaultPlayer('mse',this)">MSE</a></li>
<li><a href="#" class="dropdown-item" onclick="defaultPlayer('hls',this)">HLS</a></li>
<li><a href="#" class="dropdown-item" onclick="defaultPlayer('webrtc',this)">WebRTC</a></li>
</ul>
</li>
<li class="nav-item">
<a class="nav-link" href="/" role="button"><i class="fas fa-times"></i> Close</a>
</li>
{{end}}
</ul>
</div>
</div>
</nav>
<!-- /.navbar -->
<div class="content-wrapper p-0">
<div class="content p-0">
<div class="container-fluid p-0" style="overflow: hidden;">
<div class="grid-wrapper" id="grid-wrapper">
</div>
<div class="main-player-wrapper d-none">
<div class="main-player" data-player="none" data-uuid="0">
<video class="main-video-player" id="videoPlayer" autoplay muted playsinline></video>
<div class="play-info"> </div>
<img class="loader d-none" src="/../static/img/loader.svg" />
<canvas id="canvas" class="d-none"></canvas>
<input type="hidden" id="uuid" value="0" />
</div>
<a onclick="closeMain()"><i class="fas fa-times"></i></a>
</div>
</div>
</div>
<!-- foot -->
</div>
<!-- content-wrapper -->
<!-- STREAMS LIST -->
<aside class="control-sidebar custom">
<!-- Control sidebar content goes here -->
<p>
<a class="control-sidebar-close-btn pull-right" href="#" onclick="$('.control-sidebar').ControlSidebar('collapse')"><i class="fas fa-times"></i></a>
</p>
<h5>Available streams:</h5>
<input type="hidden" id="player-index" value="0" />
<div class="row">
{{ range $key, $value := .streams }}
<div class="col-12" id="{{ $key }}">
<div class="card card-success">
<div id="carousel_{{$key}}" class="carousel slide" data-ride="carousel">
<div class="carousel-inner">
{{if eq (len $value.Channels) 1}}
<div class="carousel-item active">
<a onclick="play('{{ $key }}',null,0)" href="#"><img class="d-block w-100 stream-img" channel="0" src="/../static/img/noimage.svg"></a>
<div class="carousel-caption d-none d-md-block">
<h5>{{$value.Name}}</h5>
</div>
</div>
{{else}}
{{ range $k, $v := .Channels }}
{{ if eq $k "1"}}
<div class="carousel-item active">
<a onclick="play('{{ $key }}',null,{{$k}})" href="#"><img class="d-block w-100 stream-img" channel="{{$k}}" src="/../static/img/noimage.svg"></a>
<div class="carousel-caption d-none d-md-block">
<h5>{{$value.Name}}</h5>
</div>
</div>
{{end}}
{{end}}
{{end}}
</div>
</div>
</div>
</div>
{{ end }}
</div>
</aside>
</div>
<!-- ./wrapper -->
<script>
let streams = {{ .streams }};
let presetOptions = {{ .options }};
let get_query={{.query}};
</script>
<script src="/../static/plugins/jquery/jquery.min.js"></script>
<script src="/../static/plugins/bootstrap/js/bootstrap.bundle.min.js"></script>
<script src="/../static/js/adminlte.min.js"></script>
<script src="/../static/plugins/sweetalert2/sweetalert2.min.js"></script>
<script src="/../static/js/index.js"></script>
</body>
</html>
<!-- end foot -->
<script src="/../static/plugins/hlsjs/hls.min.js"></script>
<script>
let colordebug = false;
let players = {};
$(document).ready(() => {
logger(9, 'page is ready')
changeBackground(localStorage.getItem('backgroundImage'));
if('grid' in get_query){
let get_grid=get_query.grid[0]||4;
multiviewGrid('set', get_grid);
}
if (presetOptions.grid != 0) {
multiviewGrid('set', presetOptions.grid);
}
if (presetOptions.player != null) {
localStorage.setItem('multiviewPlayers', JSON.stringify(presetOptions.player));
}
gridMaker(multiviewGrid('get'));
restoreStreams();
});
function defaultPlayer(type, el) {
$('#defaultPlayer').val(type);
$(el).closest('.nav-item').children('a').html($(el).text());
}
function gridMaker(col = 4) {
let grid_sizes=[1,4,6,9,12,16,25,36,49];
col = parseInt(col);
col=grid_sizes.filter(v => v >= col)[0]||4;
let colW;
switch (col) {
case 1:
colW = 'grid-1';
break;
case 6:
colW = 'grid-6';
break;
case 9:
colW = 'grid-9';
break;
case 12:
colW = 'grid-12';
break;
case 16:
colW = 'grid-16';
break;
case 25:
colW = 'grid-25';
break;
case 36:
colW = 'grid-36';
break;
case 49:
colW = 'grid-49';
break;
default:
colW = '';
break;
}
let memory = localStorage.getItem('multiviewPlayers');
destroyGrid();
for (var i = 0; i < col; i++) {
$('#grid-wrapper').append(
`<div class=" player ` + colW + ` empty" data-player="none" data-uuid="0">
<div class="play-info"></div>
<video class="video-class empty" autoplay muted playsinline></video>
` +
`<a class="remove-btn" onclick="destoyPlayer(` + i + `)"><i class="fas fa-times"></i></a>` +
`<a class="add-stream-btn" onclick="openChoise(this)"><i class="fas fa-plus"></i><br />Click to select stream</a>` +
`<a href="#" class="btn btn-info btn-xs btn-play-main d-none" onclick="playMainStream(this)"><i class="fas fa-expand"></i> Expand</a>` +
`<img class="loader d-none" src="/../static/img/loader.svg" />` +
`</div>`);
}
multiviewGrid('set', col);
addEventListenerToVideo();
$('.grid-maker').removeClass('active');
$('.grid-maker[grid="' + col + '"]').addClass('active');
if (memory != null) {
localStorage.setItem('multiviewPlayers', memory);
restoreStreams();
}
}
function addEventListenerToVideo() {
$('.video-class').each(function() {
let _this = this;
let index = $(this).closest('.player').index();
let uuid = $(this).closest('.player').attr('data-uuid');
this.addEventListener('loadeddata', () => {
_this.play();
makePic(this, $(_this).closest('.player').attr('data-uuid'), 1);
logger(index, '[video]: loadeddata');
});
this.addEventListener('stalled', () => {
logger(index, '[video]: stalled');
});
this.addEventListener('pause', () => {
if (_this.currentTime > _this.buffered.end(_this.buffered.length - 1)) {
_this.currentTime = _this.buffered.end(_this.buffered.length - 1) - 0.1;
_this.play();
}
logger(index, '[video]: pause');
});
this.addEventListener('error', (e) => {
logger(index, '[video]: error', e);
//console.log(e);
});
this.addEventListener('abort', () => {
logger(index, '[video]: abort');
});
this.addEventListener('emptied', (e) => {
logger(index, '[video]: emptied');
});
this.addEventListener('ended', (e) => {
logger(index, '[video]: ended');
});
this.addEventListener('play', (e) => {
logger(index, '[video]: play');
});
this.addEventListener('suspend', (e) => {
logger(index, '[video]: suspend');
});
this.addEventListener('waiting', (e) => {
logger(index, '[video]: waiting');
});
this.addEventListener('canplaythrough', (e) => {
$(_this).closest('div').find('.loader').addClass('d-none');
logger(index, '[video]: canplaythrough');
});
this.addEventListener('playing', (e) => {
$(_this).closest('div').find('.loader').addClass('d-none');
logger(index, '[video]: playing');
});
this.addEventListener('loadedmetadata', (e) => {
logger(index, '[video]: loadedmetadata');
});
this.addEventListener('loadstart', (e) => {
logger(index, '[video]: loadstart');
});
});
}
$('.main-video-player')[0].addEventListener('canplaythrough', (e) => {
$('.main-player').find('.loader').addClass('d-none');
logger(0, '[video]: canplaythrough');
});
$('.main-video-player')[0].addEventListener('playing', (e) => {
$('.main-player').find('.loader').addClass('d-none');
logger(0, '[video]: canplaythrough');
});
$("#videoPlayer")[0].addEventListener('loadeddata', () => {
$("#videoPlayer")[0].play();
let browser = browserDetector();
if (!browser.safari) {
makePic();
}
});
function destroyGrid() {
$('.player').each(function(index) {
destoyPlayer(index);
});
$('#grid-wrapper').empty();
}
function openChoise(dom) {
$('#player-index').val($(dom).closest('.player').index());
$('.control-sidebar').ControlSidebar('show')
}
function play(uuid, index, chan, typePlayer) {
$('#uuid').val(uuid);
if (typeof(index) == 'undefined' || index == null) {
index = $('#player-index').val();
}
let videoPlayerVar = $('.main-player');
if (index != 'main') {
videoPlayerVar = $('.player').eq(index);
}
$('.control-sidebar').ControlSidebar('collapse');
destoyPlayer(index);
videoPlayerVar.removeClass('empty');
videoPlayerVar.find('video').removeClass('empty');
let playerType = $('#defaultPlayer').val();
if (!!typePlayer) {
playerType = typePlayer;
}
videoPlayerVar.attr('data-player', playerType);
videoPlayerVar.attr('data-uuid', uuid);
let channel = 0;
if (typeof(streams[uuid].channels[1]) !== "undefined") {
channel = 1;
}
if (index == 'main') {
channel = 0;
} else {
packStreamms(index, uuid, chan, playerType);
}
if (colordebug) {
videoPlayerVar.find('.play-info').html('Stream: ' + streams[uuid].name + ' | player type:' + playerType + ' | channel: ' + channel);
}
videoPlayerVar.find('.loader').removeClass('d-none');
//fix stalled video in safari
videoPlayerVar.find('video')[0].addEventListener('pause', () => {
if (videoPlayerVar.find('video')[0].currentTime > videoPlayerVar.find('video')[0].buffered.end((videoPlayerVar.find('video')[0].buffered.length - 1))) {
videoPlayerVar.find('video')[0].currentTime = videoPlayerVar.find('video')[0].buffered.end((videoPlayerVar.find('video')[0].buffered.length - 1)) - 0.1;
videoPlayerVar.find('video')[0].play();
}
});
switch (playerType) {
case 'hls':
let url = '/stream/' + uuid + '/channel/' + channel + '/hls/live/index.m3u8';
if (videoPlayerVar.find('video')[0].canPlayType('application/vnd.apple.mpegurl')) {
videoPlayerVar.find('video')[0].src = url;
videoPlayerVar.find('video')[0].load();
} else if (Hls.isSupported()) {
players[index] = new Hls({
manifestLoadingTimeOut: 60000
});
players[index].loadSource(url);
players[index].attachMedia(videoPlayerVar.find('video')[0]);
} else {
Swal.fire({
icon: 'error',
title: 'Oops...',
text: 'Your browser don`t support hls '
});
}
break;
case 'webrtc':
players[index] = new WebRTCPlayer(uuid, videoPlayerVar, channel);
players[index].playWebrtc();
break;
case 'mse':
default:
players[index] = new msePlayer(uuid, videoPlayerVar, channel);
players[index].playMse();
break;
}
}
function destoyPlayer(index) {
let videoPlayerVar = $('.main-player');
if (index != 'main') {
videoPlayerVar = $('.player').eq(index);
}
let type = videoPlayerVar.attr('data-player');
videoPlayerVar.addClass('empty');
videoPlayerVar.find('video').addClass('empty')
switch (type) {
case 'hls':
if (!!players[index]) {
players[index].destroy();
delete players[index];
}
break;
case 'mse':
players[index].destroy();
delete players[index];
break;
case 'webrtc':
players[index].destroy();
delete players[index];
break;
default:
break;
}
videoPlayerVar.attr('data-player', 'none');
videoPlayerVar.attr('data-uuid', 0);
videoPlayerVar.find('.play-info').html('');
videoPlayerVar.find('video')[0].src = '';
videoPlayerVar.find('video')[0].load();
videoPlayerVar.find('.loader').addClass('d-none');
unpackStreams(index);
}
function expand(element) {
fullscreenOn($('#grid-wrapper').parent()[0]);
}
function playMainStream(element) {
let uuid = $(element).closest('.player').attr('data-uuid');
if (uuid == 0) {
return;
}
$('.main-player-wrapper').removeClass('d-none');
play(uuid, 'main');
}
function closeMain() {
destoyPlayer('main');
$('.main-player-wrapper').addClass('d-none');
}
/*************************mse obect **************************/
function msePlayer(uuid, videoPlayerVar, channel) {
this.ws = null,
this.video = videoPlayerVar.find('video')[0],
this.sound=false,
this.mseSourceBuffer = null,
this.mse = null,
this.mseQueue = [],
this.mseStreamingStarted = false,
this.uuid = uuid,
this.channel = channel || 0;
this.timeout = null;
this.checktime = null;
this.checktimecounter = 0;
this.playMse = function() {
let _this = this;
logger(videoPlayerVar.index(),
'func playMse',
'streams: ' + uuid,
'channel: ' + channel);
this.mse = new MediaSource();
this.video.src = window.URL.createObjectURL(this.mse);
let potocol = 'ws';
if (location.protocol == 'https:') {
potocol = 'wss';
}
let ws_url = potocol + '://' + location.host + '/stream/' + this.uuid + '/channel/' + this.channel + '/mse?uuid=' + this.uuid + '&channel=' + this.channel;
this.mse.addEventListener('sourceopen', function() {
logger(videoPlayerVar.index(),
uuid,
channel,
'[MSE]: sourceopen');
_this.ws = new WebSocket(ws_url);
_this.ws.binaryType = "arraybuffer";
_this.ws.onopen = function(event) {
logger(videoPlayerVar.index(),
uuid,
channel,
'[websocket]: connected');
}
_this.ws.onclose = function(event) {
logger(videoPlayerVar.index(),
uuid,
channel,
'[websocket]: closed');
if (_this.timeout != null) {
clearInterval(_this.timeout);
_this.timeout = null;
}
_this.timeout = setTimeout(() => {
logger(videoPlayerVar.index(),
uuid,
channel,
'[websocket]: timeouted func play');
play(uuid, videoPlayerVar.index(), channel, 'mse')
}, 15000)
}
_this.ws.onerror = (e) => {
logger(videoPlayerVar.index(),
uuid,
channel,
'[websocket]: error');
}
_this.ws.onmessage = function(event) {
_this.checkStalled();
let data = new Uint8Array(event.data);
if (data[3] == 24) {
logger(videoPlayerVar.index(),
uuid,
channel,
'[data]: init_file');
}
if (data[0] == 9) {
decoded_arr = data.slice(1);
if (window.TextDecoder) {
mimeCodec = new TextDecoder("utf-8").decode(decoded_arr);
} else {
mimeCodec = Utf8ArrayToStr(decoded_arr);
}
if(mimeCodec.indexOf(',')>0){
_this.sound=true;
}
logger(videoPlayerVar.index(),
uuid,
channel,
'[codec]: ' + mimeCodec);
//console.log(mimeCodec);
_this.mseSourceBuffer = _this.mse.addSourceBuffer('video/mp4; codecs="' + mimeCodec + '"');
_this.mseSourceBuffer.mode = "segments"
_this.mseSourceBuffer.addEventListener("updateend", _this.pushPacket.bind(_this));
} else {
_this.readPacket(event.data);
}
};
}, false);
this.mse.addEventListener('sourceended', function() {
logger(videoPlayerVar.index(),
uuid,
channel,
'[MSE]: sourceended');
})
this.mse.addEventListener('sourceclose', function() {
logger(videoPlayerVar.index(),
uuid,
channel,
'[MSE]: sourceclose');
})
this.mse.addEventListener('error', function() {
logger(videoPlayerVar.index(),
uuid,
channel,
'[MSE]: error');
})
this.mse.addEventListener('abort', function() {
logger(videoPlayerVar.index(),
uuid,
channel,
'[MSE]: abort');
})
this.mse.addEventListener('updatestart', function() {
logger(videoPlayerVar.index(),
uuid,
channel,
'[MSE]: updatestart');
})
this.mse.addEventListener('update', function() {
logger(videoPlayerVar.index(),
uuid,
channel,
'[MSE]: update');
})
this.mse.addEventListener('updateend', function() {
logger(videoPlayerVar.index(),
uuid,
channel,
'[MSE]: updateend');
})
this.mse.addEventListener('addsourcebuffer', function() {
logger(videoPlayerVar.index(),
uuid,
channel,
'[MSE]: addsourcebuffer');
})
this.mse.addEventListener('removesourcebuffer', function() {
logger(videoPlayerVar.index(),
uuid,
channel,
'[MSE]: removesourcebuffer');
})
}
this.readPacket = function(packet) {
if (!this.mseStreamingStarted) {
try {
this.mseSourceBuffer.appendBuffer(packet);
this.mseStreamingStarted = true;
} catch (e) {
logger(videoPlayerVar.index(),
'readPacket error',
'streams: ' + uuid,
'channel: ' + channel);
console.log(e);
play(uuid, videoPlayerVar.index(), channel, 'mse');
} finally {
return;
}
}
this.mseQueue.push(packet);
if (!this.mseSourceBuffer.updating) {
this.pushPacket();
}
},
this.pushPacket = function() {
let _this = this;
if (!_this.mseSourceBuffer.updating) {
if (_this.mseQueue.length > 0) {
packet = _this.mseQueue.shift();
try {
_this.mseSourceBuffer.appendBuffer(packet)
} catch (e) {
logger(videoPlayerVar.index(),
'pushPacket error',
'streams: ' + uuid,
'channel: ' + channel);
console.log(e);
play(uuid, videoPlayerVar.index(), channel, 'mse');
} finally {
}
} else {
_this.mseStreamingStarted = false;
}
}
if (_this.video.buffered.length > 0) {
if (typeof document.hidden !== "undefined" && document.hidden) {
if(!_this.sound){
_this.video.currentTime = _this.video.buffered.end((_this.video.buffered.length - 1)) - 0.5;
}
} else {
if ((_this.video.buffered.end((_this.video.buffered.length - 1)) - _this.video.currentTime) > 60) {
_this.video.currentTime = _this.video.buffered.end((_this.video.buffered.length - 1)) - 0.5;
}
}
}
}
this.checkStalled = function() {
if (!!this.video.currentTime) {
if (this.video.currentTime == this.checktime) {
this.checktimecounter += 1;
} else {
this.checktimecounter = 0;
}
}
if (this.checktimecounter > 10) {
logger(videoPlayerVar.index(),
uuid,
channel,
'[FIX]: player not move');
play(uuid, videoPlayerVar.index(), channel, 'mse');
}
this.checktime = this.video.currentTime;
},
this.destroy = function() {
if (this.timeout != null) {
clearInterval(this.timeout);
}
if (this.ws != null) {
this.ws.onclose = null;
this.ws.close(1000, "stop streaming");
}
logger(videoPlayerVar.index(),
'Event: PlayerDestroy',
'streams: ' + uuid,
'channel: ' + channel);
}
}
/*************************end mse obect **************************/
/*************************WEBRTC obect **************************/
function WebRTCPlayer(uuid, videoPlayerVar, channel) {
this.webrtc = null;
this.webrtcSendChannel = null;
this.webrtcSendChannelInterval = null;
this.uuid = uuid;
this.video = videoPlayerVar.find('video')[0];
this.channel = channel || 0;
this.playWebrtc = function() {
var _this = this;
this.webrtc = new RTCPeerConnection({
iceServers: [{
urls: ["stun:stun.l.google.com:19302"]
}]
});
this.webrtc.onnegotiationneeded = this.handleNegotiationNeeded.bind(this);
this.webrtc.ontrack = function(event) {
console.log(event.streams.length + ' track is delivered');
_this.video.srcObject = event.streams[0];
_this.video.play();
}
this.webrtc.addTransceiver('video', {
'direction': 'sendrecv'
});
this.webrtcSendChannel = this.webrtc.createDataChannel('foo');
this.webrtcSendChannel.onclose = (e) => console.log('sendChannel has closed', e);
this.webrtcSendChannel.onopen = () => {
console.log('sendChannel has opened');
this.webrtcSendChannel.send('ping');
this.webrtcSendChannelInterval = setInterval(() => {
this.webrtcSendChannel.send('ping');
}, 1000)
}
this.webrtcSendChannel.onmessage = e => console.log(e.data);
},
this.handleNegotiationNeeded = async function() {
var _this = this;
offer = await _this.webrtc.createOffer();
await _this.webrtc.setLocalDescription(offer);
$.post("/stream/" + _this.uuid + "/channel/" + this.channel + "/webrtc?uuid=" + _this.uuid + "&channel=" + this.channel, {
data: btoa(_this.webrtc.localDescription.sdp)
}, function(data) {
try {
_this.webrtc.setRemoteDescription(new RTCSessionDescription({
type: 'answer',
sdp: atob(data)
}))
} catch (e) {
console.warn(e);
}
});
}
this.destroy = function() {
clearInterval(this.webrtcSendChannelInterval);
this.webrtc.close();
this.video.srcObject = null;
}
}
/*********************FULSCREEN******************/
function fullscreenEnabled() {
return !!(
document.fullscreenEnabled ||
document.webkitFullscreenEnabled ||
document.mozFullScreenEnabled ||
document.msFullscreenEnabled
);
}
function fullscreenOn(elem) {
if (elem.requestFullscreen) {
elem.requestFullscreen();
} else if (elem.mozRequestFullScreen) {
elem.mozRequestFullScreen();
} else if (elem.webkitRequestFullscreen) {
elem.webkitRequestFullscreen();
} else if (elem.msRequestFullscreen) {
elem.msRequestFullscreen();
}
}
function fullscreenOff() {
if (document.requestFullscreen) {
document.requestFullscreen();
} else if (document.webkitRequestFullscreen) {
document.webkitRequestFullscreen();
} else if (document.mozRequestFullscreen) {
document.mozRequestFullScreen();
}
}
function packStreamms(index, uuid, channel, type) {
let multiviewPlayers;
if (localStorage.getItem('multiviewPlayers') != null) {
multiviewPlayers = JSON.parse(localStorage.getItem('multiviewPlayers'));
} else {
multiviewPlayers = {};
}
multiviewPlayers[index] = {
uuid: uuid,
channel: channel,
playerType: type
}
localStorage.setItem('multiviewPlayers', JSON.stringify(multiviewPlayers));
}
function unpackStreams(index) {
if (localStorage.getItem('multiviewPlayers') != null) {
let multiviewPlayers = JSON.parse(localStorage.getItem('multiviewPlayers'));
delete multiviewPlayers[index];
localStorage.setItem('multiviewPlayers', JSON.stringify(multiviewPlayers));
}
}
function restoreStreams() {
if (localStorage.getItem('multiviewPlayers') != null) {
let multiviewPlayers = JSON.parse(localStorage.getItem('multiviewPlayers'));
if (Object.keys(multiviewPlayers).length > 0) {
$.each(multiviewPlayers, function(key, val) {
if (val.uuid in streams && val.channel in streams[val.uuid].channels) {
if ($('.player').eq(key).length > 0) {
play(val.uuid, key, val.channel, val.playerType);
}
} else {
unpackStreams(key);
}
})
}
} else {
if (Object.keys(streams).length > 0) {
gridMaker(Object.keys(streams).length);
let playerIndex = 0;
let gridSize = $('.player').length;
$.each(streams, function(uuid, params) {
//console.log(i,uuid);
if (playerIndex < gridSize) {
let channel = 0;
if ('1' in params.channels) {
channel = 1;
}
play(uuid, playerIndex, channel, 'mse');
playerIndex++;
} else {
return;
}
})
}
}
}
function multiviewGrid(type, grid) {
let defGrid = 25;
switch (type) {
case 'set':
localStorage.setItem('multiviewGrid', grid);
break;
case 'get':
if (localStorage.getItem('multiviewGrid') != null) {
return localStorage.getItem('multiviewGrid');
} else {
return defGrid
}
break;
default:
return defGrid
}
return defGrid
}
$('#grid-wrapper').on('dblclick', '.player', function() {
$(this).find('.btn-play-main').click();
});
$('.main-player').on('dblclick', function() {
closeMain()
});
function changeBackground(num) {
let back = '/../static/img/';
localStorage.setItem('backgroundImage', num);
switch (num) {
case 'green':
back += 'green.jpg'
break;
case 'red':
back += 'red.jpg'
break;
case 'white':
back += 'white.jpg'
break;
default:
back += 'back.jpg'
}
$('.img-background').css('background-image', 'url("' + back + '")');
}
</script>