$(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: '
' + '
' + '' + '' + '' + '
' + '
' + ' ' + ' ' + '
' + '
' + '' + '' + '
' + '
', 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 '
' + '
' + '
' + '' + '
' + '
' + '
' + name + '
' + '

property

' + '
' + '' + '' + '' + '' + '
' + '
' + '
' + '
'; } 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 = `

Sub channel parameters

Enter rtsp address as instructed by your camera. Look like rtsp://<ip>:<port>/path
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
Select this options if you want get more data about the stream
`; 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('|')) }