This commit is contained in:
dongchangxi committed 2024-02-04 14:45:05 +08:00
1 parent af2f967059
commit 754c24615c
166 files changed
+81865 -2

No files matched your search

@@ -0,0 +1,218 @@
var rtspPlayer={
active:false,
type:'live',
hls:null,
ws:null,
mseSourceBuffer:null,
mse:null,
mseQueue:[],
mseStreamingStarted:false,
webrtc:null,
webrtcSendChannel:null,
webrtcSendChannelInterval:null,
uuid:null,
clearPlayer:function(){
if(this.active){
if(this.hls!=null){
this.hls.destroy();
this.hls=null;
}
if(this.ws!=null){
//close WebSocket connection if opened
this.ws.close(1000);
this.ws=null;
}
if(this.webrtc!=null){
clearInterval(this.webrtcSendChannelInterval);
this.webrtc=null;
}
$('#videoPlayer')[0].src = '';
$('#videoPlayer')[0].load();
this.active=false;
}
},
livePlayer:function(type,uuid){
this.clearPlayer();
this.uuid=uuid;
this.active=true;
$('.streams-vs-player').addClass('active-player');
if(type==0){
type=$('input[name=defaultPlayer]:checked').val()
}
switch (type) {
case 'hls':
this.playHls();
break;
case 'mse':
this.playMse();
break;
case 'webrtc':
this.playWebrtc();
break;
default:
Swal.fire(
'Sorry',
'This option is still under development',
'question'
)
return;
}
},
playHls:function(){
if(this.hls==null && Hls.isSupported()){
this.hls = new Hls();
}
if ($("#videoPlayer")[0].canPlayType('application/vnd.apple.mpegurl')) {
$("#videoPlayer")[0].src = this.streamPlayUrl('hls');
$("#videoPlayer")[0].load();
} else {
if (this.hls != null) {
this.hls.loadSource(this.streamPlayUrl('hls'));
this.hls.attachMedia($("#videoPlayer")[0]);
} else {
Swal.fire({
icon: 'error',
title: 'Oops...',
text: 'Your browser don`t support hls '
})
}
}
},
playWebrtc:function(){
var _this=this;
this.webrtc=new RTCPeerConnection({
iceServers: [{
urls: ["stun:stun.l.google.com:19302"]
}]
});
this.webrtc.onnegotiationneeded = this.handleNegotiationNeeded;
this.webrtc.ontrack = function(event) {
console.log(event.streams.length + ' track is delivered');
$("#videoPlayer")[0].srcObject = event.streams[0];
$("#videoPlayer")[0].play();
}
this.webrtc.addTransceiver('video', {
'direction': 'sendrecv'
});
this.webrtcSendChannel = this.webrtc.createDataChannel('foo');
this.webrtcSendChannel.onclose = () => console.log('sendChannel has closed');
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);
},
handleNegotiationNeeded: async function(){
var _this=rtspPlayer;
offer = await _this.webrtc.createOffer();
await _this.webrtc.setLocalDescription(offer);
$.post(_this.streamPlayUrl('webrtc'), {
data: btoa(_this.webrtc.localDescription.sdp)
}, function(data) {
//console.log(data)
try {
_this.webrtc.setRemoteDescription(new RTCSessionDescription({
type: 'answer',
sdp: atob(data)
}))
} catch (e) {
console.warn(e);
}
});
},
playMse:function(){
//console.log(this.streamPlayUrl('mse'));
var _this=this;
this.mse = new MediaSource();
$("#videoPlayer")[0].src=window.URL.createObjectURL(this.mse);
this.mse.addEventListener('sourceopen', function(){
_this.ws=new WebSocket(_this.streamPlayUrl('mse'));
_this.ws.binaryType = "arraybuffer";
_this.ws.onopen = function(event) {
console.log('Connect to ws');
}
_this.ws.onmessage = function(event) {
var data = new Uint8Array(event.data);
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);
}
console.log(mimeCodec);
_this.mseSourceBuffer = _this.mse.addSourceBuffer('video/mp4; codecs="' + mimeCodec + '"');
_this.mseSourceBuffer.mode = "segments"
_this.mseSourceBuffer.addEventListener("updateend", _this.pushPacket);
} else {
_this.readPacket(event.data);
}
};
}, false);
},
readPacket:function(packet){
if (!this.mseStreamingStarted) {
this.mseSourceBuffer.appendBuffer(packet);
this.mseStreamingStarted = true;
return;
}
this.mseQueue.push(packet);
if (!this.mseSourceBuffer.updating) {
this.pushPacket();
}
},
pushPacket:function(){
var _this=rtspPlayer;
if (!_this.mseSourceBuffer.updating) {
if (_this.mseQueue.length > 0) {
packet = _this.mseQueue.shift();
var view = new Uint8Array(packet);
_this.mseSourceBuffer.appendBuffer(packet);
} else {
_this.mseStreamingStarted = false;
}
}
},
streamPlayUrl:function(type){
switch (type) {
case 'hls':
return '/stream/' + this.uuid + '/hls/live/index.m3u8';
break;
case 'mse':
var potocol = 'ws';
if (location.protocol == 'https:') {
potocol = 'wss';
}
return potocol+'://'+location.host+'/stream/' + this.uuid +'/mse?uuid='+this.uuid;
//return 'ws://sr4.ipeye.ru/ws/mp4/live?name=d4ee855e40874ef7b7149357a42f18f0';
break;
case 'webrtc':
return "/stream/"+this.uuid+"/webrtc?uuid=" + this.uuid;
break;
default:
return '';
}
}
}
+7
View File
@@ -0,0 +1,7 @@
/*!
* AdminLTE v3.0.5 (https://adminlte.io)
* Copyright 2014-2020 Colorlib <http://colorlib.com>
* Licensed under MIT (https://github.com/ColorlibHQ/AdminLTE/blob/master/LICENSE)
*/
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t=t||self).adminlte={})}(this,(function(t){"use strict";var e=function(t){var e="ControlSidebar",i="lte.controlsidebar",n=t.fn[e],s={COLLAPSED:"collapsed.lte.controlsidebar",EXPANDED:"expanded.lte.controlsidebar"},o=".control-sidebar",a=".control-sidebar-content",r='[data-widget="control-sidebar"]',l=".main-header",c=".main-footer",d="control-sidebar-animate",h="control-sidebar-open",f="control-sidebar-slide-open",u="layout-fixed",g="layout-navbar-fixed",p="layout-sm-navbar-fixed",_="layout-md-navbar-fixed",m="layout-lg-navbar-fixed",v="layout-xl-navbar-fixed",C="layout-footer-fixed",y="layout-sm-footer-fixed",b="layout-md-footer-fixed",w="layout-lg-footer-fixed",x="layout-xl-footer-fixed",E={controlsidebarSlide:!0,scrollbarTheme:"os-theme-light",scrollbarAutoHide:"l"},A=function(){function e(t,e){this._element=t,this._config=e,this._init()}var n=e.prototype;return n.collapse=function(){this._config.controlsidebarSlide?(t("html").addClass(d),t("body").removeClass(f).delay(300).queue((function(){t(o).hide(),t("html").removeClass(d),t(this).dequeue()}))):t("body").removeClass(h);var e=t.Event(s.COLLAPSED);t(this._element).trigger(e)},n.show=function(){this._config.controlsidebarSlide?(t("html").addClass(d),t(o).show().delay(10).queue((function(){t("body").addClass(f).delay(300).queue((function(){t("html").removeClass(d),t(this).dequeue()})),t(this).dequeue()}))):t("body").addClass(h);var e=t.Event(s.EXPANDED);t(this._element).trigger(e)},n.toggle=function(){t("body").hasClass(h)||t("body").hasClass(f)?this.collapse():this.show()},n._init=function(){var e=this;this._fixHeight(),this._fixScrollHeight(),t(window).resize((function(){e._fixHeight(),e._fixScrollHeight()})),t(window).scroll((function(){(t("body").hasClass(h)||t("body").hasClass(f))&&e._fixScrollHeight()}))},n._fixScrollHeight=function(){var e={scroll:t(document).height(),window:t(window).height(),header:t(l).outerHeight(),footer:t(c).outerHeight()},i=Math.abs(e.window+t(window).scrollTop()-e.scroll),n=t(window).scrollTop(),s=!1,r=!1;t("body").hasClass(u)&&((t("body").hasClass(g)||t("body").hasClass(p)||t("body").hasClass(_)||t("body").hasClass(m)||t("body").hasClass(v))&&"fixed"===t(l).css("position")&&(s=!0),(t("body").hasClass(C)||t("body").hasClass(y)||t("body").hasClass(b)||t("body").hasClass(w)||t("body").hasClass(x))&&"fixed"===t(c).css("position")&&(r=!0),0===n&&0===i?(t(o).css("bottom",e.footer),t(o).css("top",e.header),t(o+", "+o+" "+a).css("height",e.window-(e.header+e.footer))):i<=e.footer?!1===r?(t(o).css("bottom",e.footer-i),t(o+", "+o+" "+a).css("height",e.window-(e.footer-i))):t(o).css("bottom",e.footer):n<=e.header?!1===s?(t(o).css("top",e.header-n),t(o+", "+o+" "+a).css("height",e.window-(e.header-n))):t(o).css("top",e.header):!1===s?(t(o).css("top",0),t(o+", "+o+" "+a).css("height",e.window)):t(o).css("top",e.header))},n._fixHeight=function(){var e=t(window).height(),i=t(l).outerHeight(),n=t(c).outerHeight();if(t("body").hasClass(u)){var s=e-i;(t("body").hasClass(C)||t("body").hasClass(y)||t("body").hasClass(b)||t("body").hasClass(w)||t("body").hasClass(x))&&"fixed"===t(c).css("position")&&(s=e-i-n),t(o+" "+a).css("height",s),"undefined"!=typeof t.fn.overlayScrollbars&&t(o+" "+a).overlayScrollbars({className:this._config.scrollbarTheme,sizeAutoCapable:!0,scrollbars:{autoHide:this._config.scrollbarAutoHide,clickScrolling:!0}})}},e._jQueryInterface=function(n){return this.each((function(){var s=t(this).data(i),o=t.extend({},E,t(this).data());if(s||(s=new e(this,o),t(this).data(i,s)),"undefined"===s[n])throw new Error(n+" is not a function");s[n]()}))},e}();return t(document).on("click",r,(function(e){e.preventDefault(),A._jQueryInterface.call(t(this),"toggle")})),t.fn[e]=A._jQueryInterface,t.fn[e].Constructor=A,t.fn[e].noConflict=function(){return t.fn[e]=n,A._jQueryInterface},A}(jQuery),i=function(t){var e="Layout",i=t.fn[e],n=".main-header",s=".main-sidebar",o=".main-sidebar .sidebar",a=".content-wrapper",r=".control-sidebar-content",l='[data-widget="control-sidebar"]',c=".main-footer",d='[data-widget="pushmenu"]',h=".login-box",f=".register-box",u="sidebar-focused",g="layout-fixed",p="control-sidebar-slide-open",_="control-sidebar-open",m={scrollbarTheme:"os-theme-light",scrollbarAutoHide:"l",panelAutoHeight:!0,loginRegisterAutoHeight:!0},v=function(){function e(t,e){this._config=e,this._element=t,this._init()}var i=e.prototype;return i.fixLayoutHeight=function(e){void 0===e&&(e=null);var i=0;(t("body").hasClass(p)||t("body").hasClass(_)||"control_sidebar"==e)&&(i=t(r).height());var s={window:t(window).height(),header:0!==t(n).length?t(n).outerHeight():0,footer:0!==t(c).length?t(c).outerHeight():0,sidebar:0!==t(o).length?t(o).height():0,control_sidebar:i},l=this._max(s),d=this._config.panelAutoHeight;!0===d&&(d=0),!1!==d&&(l==s.control_sidebar?t(a).css("min-height",l+d):l==s.window?t(a).cssLine truncated
//# sourceMappingURL=adminlte.min.js.map
@@ -0,0 +1 @@
{"version":3,"sources":["../../build/js/ControlSidebar.js","../../build/js/Layout.js","../../build/js/PushMenu.js","../../build/js/Treeview.js","../../build/js/DirectChat.js","../../build/js/TodoList.js","../../build/js/CardWidget.js","../../build/js/CardRefresh.js","../../build/js/Dropdown.js","../../build/js/Toasts.js"],"names":["ControlSidebar","$","NAME","DATA_KEY","JQUERY_NO_CONFLICT","fn","Event","COLLAPSED","EXPANDED","Selector","ClassName","Default","controlsidebarSlide","scrollbarTheme","scrollbarAutoHide","element","config","this","_element","_config","_init","_proto","prototype","collapse","addClass","removeClass","delay","queue","hide","dequeue","collapsedEvent","trigger","show","expandedEvent","toggle","hasClass","_this","_fixHeight","_fixScrollHeight","window","resize","scroll","heights","document","height","header","outerHeight","footer","positions","Math","abs","scrollTop","navbarFixed","footerFixed","css","sidebarHeight","overlayScrollbars","className","sizeAutoCapable","scrollbars","autoHide","clickScrolling","_jQueryInterface","operation","each","data","_options","extend","Error","on","event","preventDefault","call","Constructor","noConflict","jQuery","Layout","panelAutoHeight","loginRegisterAutoHeight","fixLayoutHeight","extra","control_sidebar","length","sidebar","max","_max","offset","_isFooterFixed","parseFloat","fixLoginRegisterHeight","box_height","Number","isInteger","setInterval","setTimeout","numbers","Object","keys","forEach","key","PushMenu","EVENT_KEY","SHOWN","autoCollapseSize","enableRemember","noTransitionAfterReload","options","_addOverlay","expand","width","localStorage","setItem","shownEvent","autoCollapse","remember","getItem","_this2","overlay","id","append","match","button","currentTarget","closest","Treeview","SELECTED","LOAD_DATA_API","animationSpeed","accordion","expandSidebar","sidebarButtonSelector","init","_setupListeners","treeviewMenu","parentLi","openMenuLi","siblings","first","openTreeview","find","stop","slideDown","_expandSidebar","slideUp","$relativeTarget","$parent","parent","is","parents","_this3","DirectChat","toggleClass","toggledEvent","TodoList","onCheck","item","onUnCheck","prop","check","unCheck","that","target","CardWidget","MAXIMIZED","MINIMIZED","REMOVED","DATA_REMOVE","DATA_COLLAPSE","DATA_MAXIMIZE","CARD","CARD_HEADER","CARD_BODY","CARD_FOOTER","collapseTrigger","removeTrigger","maximizeTrigger","collapseIcon","expandIcon","maximizeIcon","minimizeIcon","settings","_parent","_settings","children","collapsed","expanded","remove","removed","maximize","transition","maximized","minimize","style","toggleMaximize","card","click","CardRefresh","LOADED","OVERLAY_ADDED","OVERLAY_REMOVED","DATA_REFRESH","source","sourceSelector","params","content","loadInContent","loadOnInit","responseType","overlayTemplate","onLoadStart","onLoadDone","response","_overlay","load","get","html","_removeOverlay","bind","loadedEvent","overlayAddedEvent","overlayRemovedEvent","ready","Dropdown","toggleSubmenu","next","e","fixPosition","elm","visiblePart","left","stopPropagation","Toasts","INIT","CREATED","Position","position","fixed","autohide","autoremove","fade","icon","image","imageAlt","imageHeight","title","subtitle","close","body","class","_prepareContainer","initEvent","create","toast","toast_header","toast_image","attr","toast_close","_getContainerId","prepend","createdEvent","removedEvent","container","replace","option"],"mappings":";;;;;sMAOA,IAAMA,EAAkB,SAACC,GAMvB,IAAMC,EAAqB,iBACrBC,EAAqB,qBAErBC,EAAqBH,EAAEI,GAAGH,GAG1BI,EAAQ,CACZC,UAAS,+BACTC,SAAQ,+BAGJC,EACa,mBADbA,EAEqB,2BAFrBA,EAGS,kCAHTA,EAKI,eALJA,EAMI,eAGJC,EACqB,0BADrBA,EAEkB,uBAFlBA,EAGmB,6BAHnBA,EAIU,eAJVA,EAKU,sBALVA,EAMa,yBANbA,EAOa,yBAPbA,EAQa,yBARbA,EASa,yBATbA,EAUU,sBAVVA,EAWa,yBAXbA,EAYa,yBAZbA,EAaa,yBAbbA,EAca,yBAGbC,EAAU,CACdC,qBAAqB,EACrBC,eAAiB,iBACjBC,kBAAmB,KAQfd,EAtDuB,WAuD3B,SAAAA,EAAYe,EAASC,GACnBC,KAAKC,SAAWH,EAChBE,KAAKE,QAAWH,EAEhBC,KAAKG,QA3DoB,IAAAC,EAAArB,EAAAsB,UAAA,OAAAD,EAgE3BE,SAAA,WAEMN,KAAKE,QAAQP,qBACfX,EAAE,QAAQuB,SAASd,GACnBT,EAAE,QAAQwB,YAAYf,GAAiCgB,MAAM,KAAKC,OAAM,WACtE1B,EAAEQ,GAA0BmB,OAC5B3B,EAAE,QAAQwB,YAAYf,GACtBT,EAAEgB,MAAMY,cAGV5B,EAAE,QAAQwB,YAAYf,GAGxB,IAAMoB,EAAiB7B,EAAEK,MAAMA,EAAMC,WACrCN,EAAEgB,KAAKC,UAAUa,QAAQD,IA9EAT,EAiF3BW,KAAA,WAEMf,KAAKE,QAAQP,qBACfX,EAAE,QAAQuB,SAASd,GACnBT,EAAEQ,GAA0BuB,OAAON,MAAM,IAAIC,OAAM,WACjD1B,EAAE,QAAQuB,SAASd,GAAiCgB,MAAM,KAAKC,OAAM,WACnE1B,EAAE,QAAQwB,YAAYf,GACtBT,EAAEgB,MAAMY,aAEV5B,EAAEgB,MAAMY,cAGV5B,EAAE,QAAQuB,SAASd,GAGrB,IAAMuB,EAAgBhC,EAAEK,MAAMA,EAAME,UACpCP,EAAEgB,KAAKC,UAAUa,QAAQE,IAjGAZ,EAoG3Ba,OAAA,WACsBjC,EAAE,QAAQkC,SAASzB,IAAmCT,EAAE,QACzEkC,SAASzB,GAGVO,KAAKM,WAGLN,KAAKe,QA5GkBX,EAkH3BD,MAAA,WAAQ,IAAAgB,EAAAnB,KACNA,KAAKoB,aACLpB,KAAKqB,mBAELrC,EAAEsC,QAAQC,QAAO,WACfJ,EAAKC,aACLD,EAAKE,sBAGPrC,EAAEsC,QAAQE,QAAO,YACXxC,EAAE,QAAQkC,SAASzB,IAAmCT,EAAE,QAAQkC,SAASzB,KACzE0B,EAAKE,uBA7HcjB,EAkI3BiB,iBAAA,WACE,IAAMI,EAAU,CACdD,OAAQxC,EAAE0C,UAAUC,SACpBL,OAAQtC,EAAEsC,QAAQK,SAClBC,OAAQ5C,EAAEQ,GAAiBqC,cAC3BC,OAAQLine truncated
@@ -0,0 +1,531 @@
$(document).ready(() => {
localImages();
if (localStorage.getItem('defaultPlayer') != null) {
$('input[name=defaultPlayer]').val([localStorage.getItem('defaultPlayer')]);
}
})
$('input[name=defaultPlayer]').on('change', function() {
localStorage.setItem('defaultPlayer', $(this).val());
})
var activeStream = null;
function showAddStream(streamName, streamUrl) {
streamName = streamName || '';
streamUrl = streamUrl || '';
Swal.fire({
title: 'Add stream',
html: '<form class="text-left"> ' +
'<div class="form-group">' +
'<label>Name</label>' +
'<input type="text" class="form-control" id="stream-name">' +
'<small class="form-text text-muted"></small>' +
'</div>' +
'<div class="form-group">' +
' <label>URL</label>' +
' <input type="text" class="form-control" id="stream-url">' +
' </div>' +
'<div class="form-group form-check">' +
'<input type="checkbox" class="form-check-input" id="stream-ondemand">' +
'<label class="form-check-label">ondemand</label>' +
'</div>' +
'</form>',
focusConfirm: true,
showCancelButton: true,
preConfirm: () => {
var uuid = randomUuid(),
name = $('#stream-name').val(),
url = $('#stream-url').val(),
ondemand = $('#stream-ondemand').val();
if (!validURL(url)) {
Swal.fire({
icon: 'error',
title: 'Oops...',
text: 'wrong url',
confirmButtonText: 'return back',
preConfirm: () => {
showAddStream(name, url)
}
})
} else {
goRequest('add', uuid, {
name: name,
url: url,
ondemand: ondemand
});
}
}
})
}
function showEditStream(uuid) {
console.log(streams[uuid]);
}
function deleteStream(uuid) {
activeStream = uuid;
Swal.fire({
title: 'Are you sure?',
text: "Do you want delete stream " + streams[uuid].name + " ?",
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: 'Yes, delete it!'
}).then((result) => {
if (result.value) {
goRequest('delete', uuid)
}
})
}
function renewStreamlist() {
goRequest('streams');
}
function goRequest(method, uuid, data) {
data = data || null;
uuid = uuid || null;
var path = '';
var type = 'GET';
switch (method) {
case 'add':
path = '/stream/' + uuid + '/add';
type = 'POST';
break;
case 'edit':
path = '/stream/' + uuid + '/edit';
type = 'POST';
break;
case 'delete':
path = '/stream/' + uuid + '/delete';
break;
case 'reload':
path = '/stream/' + uuid + '/reload';
break;
case 'info':
path = '/stream/' + uuid + '/info';
break;
case 'streams':
path = '/streams';
break;
default:
path = '';
type = 'GET';
}
if (path == '') {
Swal.fire({
icon: 'error',
title: 'Oops...',
text: 'It`s goRequest function mistake',
confirmButtonText: 'Close',
})
return;
}
var ajaxParam = {
url: path,
type: type,
dataType: 'json',
beforeSend: function(xhr) {
xhr.setRequestHeader("Authorization", "Basic " + btoa("demo:demo"));
},
success: function(response) {
goRequestHandle(method, response, uuid);
},
error: function(e) {
console.log(e);
}
};
if (data != null) {
ajaxParam.data = JSON.stringify(data);
}
$.ajax(ajaxParam);
}
function goRequestHandle(method, response, uuid) {
switch (method) {
case 'add':
if (response.status == 1) {
renewStreamlist();
Swal.fire(
'Added!',
'Your stream has been Added.',
'success'
);
} else {
Swal.fire({
icon: 'error',
title: 'Oops...',
text: 'Same mistake issset',
})
}
break;
case 'edit':
if (response.status == 1) {
renewStreamlist();
Swal.fire(
'Success!',
'Your stream has been modified.',
'success'
);
} else {
Swal.fire({
icon: 'error',
title: 'Oops...',
text: 'Same mistake issset',
})
}
break;
case 'delete':
if (response.status == 1) {
$('#' + uuid).remove();
delete(streams[uuid]);
$('#stream-counter').html(Object.keys(streams).length);
Swal.fire(
'Deleted!',
'Your stream has been deleted.',
'success'
)
}
break;
case 'reload':
break;
case 'info':
break;
case 'streams':
if (response.status == 1) {
streams = response.payload;
$('#stream-counter').html(Object.keys(streams).length);
if (Object.keys(streams).length > 0) {
$.each(streams, function(uuid, param) {
if ($('#' + uuid).length == 0) {
$('.streams').append(streamHtmlTemplate(uuid, param.name));
}
})
}
}
break;
default:
}
}
function getImageBase64(videoEl){
const canvas = document.createElement("canvas");
canvas.width = videoEl.videoWidth;
canvas.height = videoEl.videoHeight;
canvas.getContext('2d').drawImage(videoEl, 0, 0, canvas.width, canvas.height);
const dataURL = canvas.toDataURL();
canvas.remove();
return dataURL;
}
function downloadBase64Image(base64Data){
const a = document.createElement("a");
a.href = base64Data;
a.download = "screenshot.png";
a.click();
a.remove();
}
function makePic(video_element, uuid, chan) {
if (typeof(video_element) === "undefined") {
video_element = $("#videoPlayer")[0];
}
ratio = video_element.videoWidth / video_element.videoHeight;
w = 400;
h = parseInt(w / ratio, 10);
$('#canvas')[0].width = w;
$('#canvas')[0].height = h;
$('#canvas')[0].getContext('2d').fillRect(0, 0, w, h);
$('#canvas')[0].getContext('2d').drawImage(video_element, 0, 0, w, h);
var imageData = $('#canvas')[0].toDataURL();
var images = localStorage.getItem('imagesNew');
if (images != null) {
images = JSON.parse(images);
} else {
images = {};
}
var uid = $('#uuid').val();
if (!!uuid) {
uid = uuid;
}
var channel = $('#channel').val() || chan || 0;
if (typeof(images[uid]) === "undefined") {
images[uid] = {};
}
images[uid][channel] = imageData;
localStorage.setItem('imagesNew', JSON.stringify(images));
$('#' + uid).find('.stream-img[channel="' + channel + '"]').attr('src', imageData);
}
function localImages() {
var images = localStorage.getItem('imagesNew');
if (images != null) {
images = JSON.parse(images);
$.each(images, function(k, v) {
$.each(v, function(channel, img) {
$('#' + k).find('.stream-img[channel="' + channel + '"]').attr('src', img);
})
});
}
}
function clearLocalImg() {
localStorage.setItem('imagesNew', '{}');
}
function streamHtmlTemplate(uuid, name) {
return '<div class="item" id="' + uuid + '">' +
'<div class="stream">' +
'<div class="thumbs" onclick="rtspPlayer.livePlayer(0, \'' + uuid + '\')">' +
'<img src="../static/img/noimage.svg" alt="" class="stream-img">' +
'</div>' +
'<div class="text">' +
'<h5>' + name + '</h5>' +
'<p>property</p>' +
'<div class="input-group-prepend dropleft text-muted">' +
'<a class="btn" data-toggle="dropdown" >' +
'<i class="fas fa-ellipsis-v"></i>' +
'</a>' +
'<div class="dropdown-menu">' +
'<a class="dropdown-item" onclick="rtspPlayer.livePlayer(\'hls\', \'' + uuid + '\')" href="#">Play HLS</a>' +
'<a class="dropdown-item" onclick="rtspPlayer.livePlayer(\'mse\', \'' + uuid + '\')" href="#">Play MSE</a>' +
'<a class="dropdown-item" onclick="rtspPlayer.livePlayer(\'webrtc\', \'' + uuid + '\')" href="#">Play WebRTC</a>' +
'<div class="dropdown-divider"></div>' +
'<a class="dropdown-item" onclick="showEditStream(\'' + uuid + '\')" href="#">Edit</a>' +
'<a class="dropdown-item" onclick="deleteStream(\'' + uuid + '\')" href="#">Delete</a>' +
'</div>' +
'</div>' +
'</div>' +
'</div>' +
'</div>';
}
function randomUuid() {
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
);
}
function validURL(url) {
//TODO: fix it
return true;
}
function Utf8ArrayToStr(array) {
var out, i, len, c;
var char2, char3;
out = "";
len = array.length;
i = 0;
while (i < len) {
c = array[i++];
switch (c >> 4) {
case 7:
out += String.fromCharCode(c);
break;
case 13:
char2 = array[i++];
out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
break;
case 14:
char2 = array[i++];
char3 = array[i++];
out += String.fromCharCode(((c & 0x0F) << 12) |
((char2 & 0x3F) << 6) |
((char3 & 0x3F) << 0));
break;
}
}
return out;
}
function browserDetector() {
var Browser;
var ua = self.navigator.userAgent.toLowerCase();
var match =
/(edge)\/([\w.]+)/.exec(ua) ||
/(opr)[\/]([\w.]+)/.exec(ua) ||
/(chrome)[ \/]([\w.]+)/.exec(ua) ||
/(iemobile)[\/]([\w.]+)/.exec(ua) ||
/(version)(applewebkit)[ \/]([\w.]+).*(safari)[ \/]([\w.]+)/.exec(ua) ||
/(webkit)[ \/]([\w.]+).*(version)[ \/]([\w.]+).*(safari)[ \/]([\w.]+)/.exec(
ua
) ||
/(webkit)[ \/]([\w.]+)/.exec(ua) ||
/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
/(msie) ([\w.]+)/.exec(ua) ||
(ua.indexOf("trident") >= 0 && /(rv)(?::| )([\w.]+)/.exec(ua)) ||
(ua.indexOf("compatible") < 0 && /(firefox)[ \/]([\w.]+)/.exec(ua)) || [];
var platform_match =
/(ipad)/.exec(ua) ||
/(ipod)/.exec(ua) ||
/(windows phone)/.exec(ua) ||
/(iphone)/.exec(ua) ||
/(kindle)/.exec(ua) ||
/(android)/.exec(ua) ||
/(windows)/.exec(ua) ||
/(mac)/.exec(ua) ||
/(linux)/.exec(ua) ||
/(cros)/.exec(ua) || [];
var matched = {
browser: match[5] || match[3] || match[1] || "",
version: match[2] || match[4] || "0",
majorVersion: match[4] || match[2] || "0",
platform: platform_match[0] || ""
};
var browser = {};
if (matched.browser) {
browser[matched.browser] = true;
var versionArray = matched.majorVersion.split(".");
browser.version = {
major: parseInt(matched.majorVersion, 10),
string: matched.version
};
if (versionArray.length > 1) {
browser.version.minor = parseInt(versionArray[1], 10);
}
if (versionArray.length > 2) {
browser.version.build = parseInt(versionArray[2], 10);
}
}
if (matched.platform) {
browser[matched.platform] = true;
}
if (browser.chrome || browser.opr || browser.safari) {
browser.webkit = true;
} // MSIE. IE11 has 'rv' identifer
if (browser.rv || browser.iemobile) {
if (browser.rv) {
delete browser.rv;
}
var msie = "msie";
matched.browser = msie;
browser[msie] = true;
} // Microsoft Edge
if (browser.edge) {
delete browser.edge;
var msedge = "msedge";
matched.browser = msedge;
browser[msedge] = true;
} // Opera 15+
if (browser.opr) {
var opera = "opera";
matched.browser = opera;
browser[opera] = true;
} // Stock android browsers are marked as Safari
if (browser.safari && browser.android) {
var android = "android";
matched.browser = android;
browser[android] = true;
}
browser.name = matched.browser;
browser.platform = matched.platform;
return browser;
}
function addChannel() {
$('#streams-form-wrapper').append(chanellTemplate());
}
function chanellTemplate() {
let random = Math.ceil(Math.random() * 1000);
let html = `
<div class="col-12">
<div class="card card-secondary">
<div class="card-header">
<h3 class="card-title">Sub channel<small> parameters</small></h3>
<div class="card-tools">
<button type="button" class="btn btn-tool" onclick="removeChannelDiv(this)"><i class="fas fa-times"></i></button>
</div>
</div>
<div class="card-body">
<form class="stream-form">
<div class="form-group">
<label for="exampleInputPassword1">Substream url</label>
<input type="text" name="stream-url" class="form-control" placeholder="Enter stream url" >
<small class="form-text text-muted">Enter rtsp address as instructed by your camera. Look like <code>rtsp://&lt;ip&gt;:&lt;port&gt;/path </code> </small>
</div>
<div class="form-group">
<label for="inputStatus">Substream type</label>
<select class="form-control custom-select" name="stream-ondemand" >
<option selected disabled><small>Select One</small></option>
<option value="1">On demand only</option>
<option value="0">Persistent connection</option>
</select>
<small class="form-text text-muted">On persistent connection, the server get data from the camera continuously. On demand, the server get data from the camera only when you click play button </small>
</div>
<div class="form-group">
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" name="debug" id="substream-debug-switch-` + random + `" >
<label class="custom-control-label" for="substream-debug-switch-` + random + `">Enable debug</label>
</div>
<small class="form-text text-muted">Select this options if you want get more data about the stream </small>
</div>
</form>
</div>
</div>
</div>`;
return html;
}
function removeChannelDiv(element) {
$(element).closest('.col-12').remove();
}
function logger() {
if (!colordebug) {
return;
}
let colors = {
"0": "color:green",
"1": "color:#66CDAA",
"2": "color:blue",
"3": "color:#FF1493",
"4": "color:#40E0D0",
"5": "color:red",
"6": "color:red",
"7": "color:red",
"8": "color:red",
"9": "color:red",
"10": "color:red",
"11": "color:red",
"12": "color:red",
"13": "color:red",
"14": "color:red",
"15": "color:red",
}
console.log('%c%s', colors[arguments[0]], new Date().toLocaleString() + " " + [].slice.call(arguments).join('|'))
}