const { pipelines, components, utils, Buffer } = window.mediaStreamLibrary;
Number.prototype.toUnsigned = function() {
return ((this >>> 1) * 2 + (this & 1));
};
const ulawencodeTable = [
0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7];
window.vxgwsplayer = function(id, options_){
window.vxgwsplayer.version="1.1.2"; //version is updated by 'npm run build'
window.vxgwsplayer.players = window.vxgwsplayer.players || {};
if(!document.getElementById(id)){
console.error(" Player with " + id + " did not found");
return undefined;
}
if(!window.vxgwsplayer.players[id]){
/*
if(typeof chrome == "undefined"){
vxgwsplayer.showAvailableInChrome(id);
return undefined;
}
if(navigator.userAgent.match(/Android/i)
|| navigator.userAgent.match(/webOS/i)
|| navigator.userAgent.match(/iPhone/i)
|| navigator.userAgent.match(/iPad/i)
|| navigator.userAgent.match(/iPod/i)
|| navigator.userAgent.match(/BlackBerry/i)
|| navigator.userAgent.match(/Windows Phone/i)
){
vxgwsplayer.showAvailableInChrome(id);
return undefined;
};
*/
/*
if(!vxgwsplayer.browserSupportsPluginPnacl()){
console.log("Not installed vxg_media_player");
vxgwsplayer.showNotInstalled(id);
var fs = window.RequestFileSystem || window.webkitRequestFileSystem;
if (fs) {
fs(window.TEMPORARY,100,function(){},function(){ vxgwsplayer.showNotInstalledInIncognitoMode(id); });
}
return undefined;
}
*/
// magic run app
/*
var fs = window.RequestFileSystem || window.webkitRequestFileSystem;
if (!fs) {
//console.log("RequestFileSystem failed");
window.location.href = "https://www.videoexpertsgroup.com/player_start/";
} else {
fs(window.TEMPORARY, 1, function(){
//console.log("not in incognito mode");
if(!vxgwsplayer.isFrame()){
//console.log("Start Chrome App");
window.location.href = "https://www.videoexpertsgroup.com/player_start/";
}
},
function(){
console.log("Not installed vxg_media_player");
});
}
*/
// check web socket server
/*
if(window.location.protocol != "https:" && !vxgwsplayer.isFrame()){
vxgwsplayer.checkWebSocket().done(function(result){
//console.log('websocket: success');
}).fail(function(err){
// check incognito mode
fs(window.TEMPORARY,1,function(){ vxgwsplayer.showWebSocketFailed(id); },function(){ vxgwsplayer.showNotStartedInIncognitoMode(id); });
});
}
*/
if(window.location.protocol != "https:" && vxgwsplayer.isFrame()){
vxgwsplayer.checkWebSocket().done(function(result){
//console.log('websocket: success');
}).fail(function(err){
vxgwsplayer.showNotStartedInIFrame(id);
});
}
//window.location.href = "https://videoexpertsgroup.com/player_start/";
window.vxgwsplayer.players[id] = new function(id, opts){
const self = this;
self.id = id;
self.player = document.getElementById(id);
/* init options */
window.vxgwsplayer.initOptions(self, opts);
self.playerWidth=self.options.width || 640;
self.playerHeight=self.options.height || 480;
self.playerWidth = parseInt(self.player.getAttribute('width'),10) || self.playerWidth;
self.playerHeight = parseInt(self.player.getAttribute('height'),10) || self.playerHeight;
self.player.style.width = self.playerWidth + 'px';
self.player.style.height = self.playerHeight + 'px';
self.wd = null;
self.wdtries = 0;
self.wdwork = null;
var html = ''
+ '
'
+ ''
+ ''
+ ''
+ ''
+ ''
+ '
'
+ '
'
+ '
'
+ '
'
+ '
'
+ '
'
+ '
'
+'
'
+'
'
+'
'
+ '
'
+ ''
// + ''
+ ''
+ ''
/*
+ window.vxgwsplayer.generateEmbededElement(self);
*/
self.player.innerHTML = html;
var el_controls = self.player.getElementsByClassName('vxgwsplayer-controls')[0];
var el_controls_zoom = self.player.getElementsByClassName('vxgwsplayer-controls-zoom')[0];
var el_controls_zoom_position = self.player.getElementsByClassName('vxgwsplayer-controls-zoom-position')[0];
var el_play = self.player.getElementsByClassName('vxgwsplayer-play')[0];
var el_pause = self.player.getElementsByClassName('vxgwsplayer-pause')[0];
var el_stop = self.player.getElementsByClassName('vxgwsplayer-stop')[0];
var el_fullscreen = self.player.getElementsByClassName('vxgwsplayer-fullscreen')[0];
var el_takescreenshot = self.player.getElementsByClassName('vxgwsplayer-takescreenshot')[0];
var el_screenshot_loading = self.player.getElementsByClassName('vxgwsplayer-screenshot-loading')[0];
var el_scale = self.player.getElementsByClassName('vxgwsplayer-scale')[0];
var el_zoomUp = self.player.getElementsByClassName('vxgwsplayer-zoom-up')[0];
var el_zoomDown = self.player.getElementsByClassName('vxgwsplayer-zoom-down')[0];
var el_zoomProgress = self.player.getElementsByClassName('vxgwsplayer-zoom-progress')[0];
var el_zoomPositionCursor = self.player.getElementsByClassName('vxgwsplayer-zoom-position-cursor')[0];
var el_loader = self.player.getElementsByClassName('vxgwsplayer-loader')[0];
var el_error = self.player.getElementsByClassName('vxgwsplayer-error')[0];
var el_error_text = self.player.getElementsByClassName('vxgwsplayer-error-text')[0];
var el_video = self.player.getElementsByClassName('vxgwsplayer-native-video')[0];
var el_snap_stub = self.player.getElementsByClassName('vxgwsplayer-stub-snapshot')[0];
var el_record = self.player.getElementsByClassName('vxgwsplayer-stub-record')[0];
var el_btnstart = document.getElementById(id + '_btnstart');
self.video = el_video;
self.video.onplay = function() {
var b = self.video.buffered;
if (b.length > 0)
self.video.currentTime = b.end(b.length - 1) - self.m.latency/1000;
console.log('onplay: start=' + self.video.currentTime + ', buffer=(' + b.start(b.length - 1) + ', ' + b.end(b.length - 1) + ')');
/*
var b = self.video.buffered;
if (b.length == 0) {
console.log('no buffer');
} else {
if ((b.end(0)*1000 - self.m.latency > 0) && (self.video.paused )) {
self.video.paused = false;
self.video.currentTime = b.end(0) - self.m.latency/1000;
self.pipeline.play();
}
console.log('buffer:' + b.start(0) + '~' + b.end(0));
}
*/
}
self.video.onpause = function() {
console.log('onpause');
}
/*
self.module = document.getElementById(id + '_nacl_module');
self.module.command = function(){
var cmd = [];
for(var i = 0; i < arguments.length; i++){
cmd.push(arguments[i]);
}
if(id != self.id || self.id + '_nacl_module' != self.module.id){
console.error("Mixed player id");
}
if(self.m.debug){
console.log('Player: ' + self.id + ' cmd=[' + cmd.join('] '));
}
self.module.postMessage(cmd);
// self.module.postMessage(arguments);
}
// Request the offsetTop property to force a relayout. As of Apr 10, 2014
// this is needed if the module is being loaded on a Chrome App's
// background page (see crbug.com/350445).
self.module.offsetTop;
*/
self.m.versionapp = "unknown";
self.m.debug = self.options.debug || self.player.hasAttribute('debug') || false;
var watchdog_tr = self.player.getAttribute('watchdog');
// self.m.watchdog = ( (watchdog_tr !== undefined) && (watchdog_tr !==null) && (watchdog_tr !== "") ) ? parseInt(watchdog_tr,10) : 3;
// if fps=1, 3sec is not enough to fill buffer to satisfy latency.
self.m.watchdog = ( (watchdog_tr !== undefined) && (watchdog_tr !==null) && (watchdog_tr !== "") ) ? parseInt(watchdog_tr,10) : 5;
self.m.autostart = self.player.hasAttribute('autostart');
self.m.is_opened = false;
self.m.latency = 0;
self.m.controls = true;
self.m.avsync = self.options.avsync || false;
self.m.vxgReadyState = 0;
self.m.autohide = self.options.autohide || 2000;
self.m.lastErrorCode = -1;
self.m.lastErrorDecoder = 0;
self.m.autoreconnect = self.options.autoreconnect || 0;
self.m.connection_timeout = self.options.connection_timeout || 0;
self.m.connection_udp = self.options.connection_udp || 0;
self.m.isCustomDigitalZoom = self.options.custom_digital_zoom || false;
self.currentZoom = 10;
self.m.snapshotFile = "";
self.m.snapshotPTS = "-1";
self.m.PTSVideo = "-1";
self.m.PTSAudio = "-1";
self.m.playAfterBufferFill = false;
self.m.lastRecvTime = Date.now();
vxgwsplayer.initVolumeControls(self, false);
if(self.m.debug){
console.log("Player " + self.id + " - init new player");
}
self.set_controls_opacity = function(val){
el_controls.style.opacity = val;
el_controls_zoom.style.opacity = val;
el_controls_zoom_position.style.opacity = val;
}
self.set_controls_display = function(val){
el_controls.style.display = val;
if(self.m.isCustomDigitalZoom == true){
el_controls_zoom.style.display = "none";
el_controls_zoom_position.style.display = "none";
}else{
el_controls_zoom.style.display = val;
el_controls_zoom_position.style.display = self.currentZoom == 10 ? "none" : "";
}
}
if(self.m.isCustomDigitalZoom == false){
el_controls_zoom_position.style.display = self.currentZoom == 10 ? "none" : "";
}
if(self.player.hasAttribute('custom-digital-zoom')){
self.m.isCustomDigitalZoom = true;
el_controls_zoom.style.display = "none";
el_controls_zoom_position.style.display = "none";
}
if(!self.player.hasAttribute('controls')){
self.m.controls = false;
self.set_controls_display("none");
}
if(self.options.controls && self.options.controls == true){
self.m.controls = true;
self.set_controls_display("");
}
self.m.avsync = self.player.hasAttribute('avsync');
self.m.aspectRatio = (self.player.hasAttribute('aspect-ratio-mode'))?(parseInt(self.player.getAttribute('aspect-ratio-mode'),10)):0;
if(self.player.hasAttribute('autohide')){
self.m.autohide = parseInt(self.player.getAttribute('autohide'),10)*1000;
}else if(self.options.autohide){
self.m.autohide = self.options.autohide*1000;
}
self.timeout = undefined;
self.loadSettings = function(){
if(self.m.debug){
console.log('Player ' + self.id + ' - loadSettings');
}
/*
if(self.player.hasAttribute('useragent-prefix')){
self.module.command('setuseragent', self.player.getAttribute('useragent-prefix') + ' ' + navigator.userAgent)
}else if(self.options.useragent_prefix){
self.module.command('setuseragent', self.options.useragent_prefix + ' ' + navigator.userAgent)
}
*/
/*
self.module = document.getElementById(self.id + '_nacl_module');
self.module.command = function(){
var cmd = [];
for(var i = 0; i < arguments.length; i++){
cmd.push(arguments[i]);
}
if(id != self.id || self.id + '_nacl_module' != self.module.id){
console.error("Mixed player id");
}
if(self.m.debug){
console.log('Player: ' + self.id + ' cmd=[' + cmd.join('] '));
}
self.module.postMessage(cmd);
// self.module.postMessage(arguments);
}
self.module.offsetTop;
self.module.command('setversion', window.vxgwsplayer.version);
*/
//self.m.autoreconnect = 0;
if(self.player.hasAttribute('auto-reconnect') || self.options.autoreconnect){
self.m.autoreconnect = 1;
/*
self.module.command('setautoreconnect', '1');
*/
}
if(self.player.hasAttribute('connection-timeout')){
self.m.connection_timeout = parseInt(self.player.getAttribute('connection-timeout'), 10);
}
if(self.options.connection_timeout != 0){
/*
self.module.command('setconnection_timeout', self.m.connection_timeout.toString());
*/
}
if(self.player.hasAttribute('connection-udp') || self.m.connection_udp){
self.m.connection_udp = 1;
/*
self.module.command('setconnection_udp', '1');
*/
}
self.m.avsync = self.player.hasAttribute('avsync');
self.m.aspectRatio = 0;
if(self.player.hasAttribute('aspect-ratio-mode')){
self.m.aspectRatio = parseInt(self.player.getAttribute('aspect-ratio-mode'), 10);
}else if(self.options.aspect_ratio_mode){
self.m.aspectRatio = self.options.aspect_ratio_mode;
}
self.aspectRatioMode(self.m.aspectRatio);
/*
self.module.command('setavsync', self.m.avsync ? '1' : '0');
*/
if(self.player.hasAttribute('latency')){
self.m.latency = parseInt(self.player.getAttribute('latency'), 10);
/*
self.module.command('setlatency', self.m.latency.toString());
*/
}else if(self.options.latency){
self.m.latency = self.options.latency;
/*
self.module.command('setlatency', self.m.latency.toString());
*/
}
if (self.m.latency < 0) {
self.m.latency = 0;
}
window.vxgwsplayer.initVolumeControls(self, true);
if(self.player.hasAttribute('autohide')){
self.m.autohide = parseInt(self.player.getAttribute('autohide'),10)*1000;
}else if(self.options.autohide){
self.m.autohide = self.options.autohide*1000;
}
}
self.moduleDidLoad = function(){
if(self.m.debug){
console.log('Player ' + self.id + ' - moduleDidLoad');
}
self.loadSettings();
if(window.location.protocol == "https:"){
//use Native protocol
self.connectToApp();
}else{
//use Websocket protocol
/*
self.module.command('startwebsclient', vxgwsplayer.webserverport)
*/
}
}
self.playerDidLoad = function(){
self.loadSettings();
if(self.m.debug){
console.log('Player ' + self.id + " - playerDidLoad");
}
if(self.onReadyStateCallback){
self.m.is_opened = false;
self.onReadyStateCallback();
}else{
self.setSource(); //binary, wsurl and rtspurl should be inited
}
}
self.connectToApp = function(){
if(self.m.debug){
console.log('Player ' + self.id + ' connectToApp');
}
//self.m.port = chrome.runtime.connect("hncknjnnbahamgpjoafdebabmoamcnni");
//self.m.port = chrome.runtime.connect("invalid");
if(self.m.debug){
console.log('Player ' + self.id + ' connected port='+self.m.port);
}
self.m.portName = ""+ new Date().getTime().toString();
/*
self.m.port.onDisconnect.addListener(function(){
if(self.m.debug)
console.log('disconnected portName='+self.m.portName);
self.module.command( 'stopnativeclient', '@'+self.m.portName);
self.m.port = undefined;
});
*/
if(self.m.debug)
console.log('connected portName='+self.m.portName);
/*
self.m.port.onMessage.addListener(function(msg) {
if( msg != undefined && msg.id == undefined && msg[0] != undefined && msg[0].charAt(0) == '@'){
if(self.module.postMessage == undefined){
self.m.port.disconnect();
}else{
self.module.postMessage(msg);
}
}else
if( msg != undefined && msg.cmd == 'getversionapp'){
if(0 == msg.data.indexOf("VERSION_APP")){
self.m.versionapp = msg.data.split(' ')[1];
if(self.m.debug){
console.log('Player ' + self.id + ' =VERSION_APP '+self.m.versionapp);
}
self.module.command( 'setappversion', self.m.versionapp);
self.module.command( 'startnativeclient', '@'+self.m.portName);
self.playerDidLoad();
}else{
console.log('Player ' + self.id + ' Invalid VERSION_APP msg.data='+msg.data);
}
}else{
console.log('Player ' + self.id + 'getversionapp unknown msg=', msg);
}
});
self.m.port.postMessage({id: ""+self.m.portName, cmd: "getversionapp", data: ""} );
*/
}
self.showerror = function(text){
el_loader.style.display = "none";
el_error.style.display = "inline-block";
el_error_text.style.display = "inline-block";
el_error_text.innerHTML = text;
}
self.hideerror = function(text){
el_error.style.display = "none";
el_error_text.style.display = "none";
}
self.readyState = function(){
return self.m.vxgReadyState;
}
self.onReadyStateChange = function(cb){
self.onReadyStateCallback = cb;
}
self.ready = self.onReadyStateChange;
self.onStateChange = function(cb){
self.onStateChangeCallback = cb;
}
self.onBandwidthError = function(cb){
self.m.handlerBandwidthError = cb;
}
self.onError = function(cb){
self.m.handlerError = cb;
}
/*
self.handleMessage = function(msgEvent){
if(self.m.debug){
console.log('Player ' + self.id + ' handleMessage: ' + msgEvent.data);
}
if(msgEvent == undefined || msgEvent.data == undefined){
return;
}
if(msgEvent.data[0] != undefined && msgEvent.data[0].charAt(0) == '@'){
//proto native send to app
if(self.m.port != undefined){
self.m.port.postMessage(msgEvent.data);
}
}else if(0 == msgEvent.data.indexOf("PLAYER_INITED")){
self.moduleDidLoad();
}else if(0 == msgEvent.data.indexOf("PLAYER_INIT_ERR")){
str = "PLAYER_INIT_ERR ";
err = parseInt(msgEvent.data.split(' ')[1], 10);
err_type = (err >> 16)&0xffff;
console.log('err_type='+err_type);
switch(err_type){
case 4:
str += "Init audio output error ";
break;
case 2:
str += "Init video decoder error ";
break;
default:
str += "Init D3D error ";
break;
}
str += ""+err.toString();
vxgwsplayer.showInitFailed(id, str);
}else
// Player source error=60935 WSS status=6
// Player listener2: Skip picture: 170, frame_duration: 41, latencyms: 0<=frames_buf:0, b: 0, p: 0
if(0 == msgEvent.data.indexOf("VERSION_APP")){
self.m.versionapp = msgEvent.data.split(' ')[1];
if(self.m.debug)
console.log('=VERSION_APP '+self.m.versionapp);
self.playerDidLoad();
}else if(0 == msgEvent.data.indexOf("PTS_VIDEO")){
self.m.PTSVideo = msgEvent.data.split(' ')[1];
//console.log('=PTS_VIDEO '+self.m.PTSVideo);
}else if(0 == msgEvent.data.indexOf("PTS_AUDIO")){
self.m.PTSAudio = msgEvent.data.split(' ')[1];
//console.log('=PTS_AUDIO '+self.m.PTSAudio);
}else if(0 == msgEvent.data.indexOf("TAKE_SNAPSHOT")){
snap_status = msgEvent.data.split(' ')[1];
snap_pts = msgEvent.data.split(' ')[2];
console.log('TAKE_SNAPSHOT snap_status='+snap_status+' snap_pts='+snap_pts);
if(0 != snap_status.indexOf("ERROR")){
self.m.snapshotFile = snap_status;
if(snap_pts != undefined)
self.m.snapshotPTS = snap_pts;
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
window.requestFileSystem(window.TEMPORARY, 1, function(fs) {
fs.root.getFile(self.m.snapshotFile, {create: false}, function(fileEntry) { // /test is filename
var pom = document.createElement('a');
pom.setAttribute('href', fileEntry.toURL());
if(self.m.snapshotPTS == -1){
pom.setAttribute('download', "snapshot.jpg");
}else{
pom.setAttribute('download', "snapshot_"+self.m.snapshotPTS+".jpg");
}
pom.style.display = 'none';
document.body.appendChild(pom);
pom.click();
document.body.removeChild(pom);
}, function(e) {
console.error("[vxgwsplayer] TAKE_SNAPSHOT fs.root.getFile FAILED")
});
}, function(e) {
console.error("[vxgwsplayer] TAKE_SNAPSHOT requestFileSystem window.TEMPORARY FAILED")
});
}
}else if(msgEvent.data == "MEDIA_ERR_URL"){
self.showerror('Problem with URL');
self.m.lastErrorCode = 0;
if(self.m.handlerError)
self.m.handlerError(self);
}else if(0 == msgEvent.data.indexOf("MEDIA_ERR_NETWORK")){
self.showerror('Problem with network');
self.m.lastErrorCode = 1;
if(self.m.handlerError)
self.m.handlerError(self);
}else if(0 == msgEvent.data.indexOf("MEDIA_ERR_SOURCE")){
self.showerror('Problem with source');
self.m.lastErrorCode = 2;
if(self.m.handlerError)
self.m.handlerError(self);
}else if(0 == msgEvent.data.indexOf("MEDIA_ERR_CARRIER")){
self.showerror('Problem with carrier');
self.m.lastErrorCode = 3;
if(self.m.handlerError)
self.m.handlerError(self);
}else if(0 == msgEvent.data.indexOf("MEDIA_ERR_AUDIO")){
self.showerror('Problem with audio');
self.m.lastErrorCode = 4;
if(self.m.handlerError)
self.m.handlerError(self);
}else if(0 == msgEvent.data.indexOf("MEDIA_ERR_VIDEO")){
self.showerror('Problem with video');
self.m.lastErrorCode = 5;
if(self.m.handlerError)
self.m.handlerError(self);
}else if(0 == msgEvent.data.indexOf("MEDIA_ERR_AUTHENTICATION")){
self.showerror('Problem with authentification');
self.m.lastErrorCode = 6;
if(self.m.handlerError)
self.m.handlerError(self);
}else if(0 == msgEvent.data.indexOf("MEDIA_ERR_BANDWIDTH")){
//self.stop();
self.m.lastErrorCode = 7;
if(self.m.handlerError)
self.m.handlerError(self);
if(self.m.handlerBandwidthError){
self.m.handlerBandwidthError(self);
}else{
//self.showerror('Problem with bandwidth');
}
}else if(0 == msgEvent.data.indexOf("MEDIA_ERR_EOF")){
self.showerror('End of File');
self.m.lastErrorCode = 8;
if(self.m.handlerError)
self.m.handlerError(self);
}else if(0 == msgEvent.data.indexOf("MEDIA_ERR_DECODER")){
var arr = msgEvent.data.split(' ');
self.m.lastErrorDecoder = (arr.length > 1) ? parseInt(arr[1],10) : 0;
if(self.m.debug)
console.log('=MEDIA_ERR_DECODER '+self.m.lastErrorDecoder + ' ' + (self.m.lastErrorDecoder == 0)?'Decoder resumed':'');
if(self.m.lastErrorDecoder == 0){
self.m.lastErrorCode = -1;
//self.hideerror();
}else{
self.m.lastErrorCode = 9;
//self.showerror('Decoder error '+self.m.lastErrorDecoder);
}
if(self.m.handlerError)
self.m.handlerError(self);
}else if(0 == msgEvent.data.indexOf("PLAYER_CONNECTING")){
self.m.vxgReadyState = 1;
//el_play.style.display = "none";
// el_stop.style.display = "none";
// self.hideerror();
el_loader.style.display = "inline-block";
el_takescreenshot.style.display = "none";
if(self.onStateChangeCallback)
self.onStateChangeCallback(self.m.vxgReadyState);
}else if(0 == msgEvent.data.indexOf("PLAYER_PLAYING")){
//console.log('PLAYER_PLAYING');
self.m.vxgReadyState = 2;
el_play.style.display = "none";
el_stop.style.display = "inline-block";
el_pause.style.display = "inline-block";
el_takescreenshot.style.display = "inline-block";
self.hideerror();
el_loader.style.display = "none";
if(self.onStateChangeCallback)
self.onStateChangeCallback(self.m.vxgReadyState);
}else if(0 == msgEvent.data.indexOf("PLAYER_STOPPING")){
self.m.vxgReadyState = 3;
// el_error.style.display = "none";
// el_loader.style.display = "inline-block";
el_play.style.display = "none";
el_stop.style.display = "none";
el_pause.style.display = "none";
el_takescreenshot.style.display = "none";
}else if(0 == msgEvent.data.indexOf("PLAYER_STOPPED")){
self.m.vxgReadyState = 0;
el_play.style.display = "inline-block";
el_stop.style.display = "none";
el_pause.style.display = "none";
el_takescreenshot.style.display = "none";
if(self.onStateChangeCallback)
self.onStateChangeCallback(self.m.vxgReadyState);
}else if(0 == msgEvent.data.indexOf("PLAYER_PAUSED")){
//console.log('PLAYER_PAUSED');
self.m.vxgReadyState = 4;
el_play.style.display = "inline-block";
el_stop.style.display = "inline-block";
el_pause.style.display = "none";
// el_takescreenshot.style.display = "none";
if(self.onStateChangeCallback)
self.onStateChangeCallback(self.m.vxgReadyState);
}
}
*/
self.handleError = function(){
el_loader.style.display = "none";
el_error.style.display = "block";
console.error("ERROR");
self.showerror('Unknown error');
}
self.handleCrash = function(){
el_loader.style.display = "none";
el_error.style.display = "block";
self.showerror('Crashed');
}
self.restartTimeout = function(){
if(self.m.autohide <= 0){
self.set_controls_opacity("0");
return;
}
self.set_controls_opacity("0.7");
clearTimeout(self.timeout);
self.timeout = setTimeout(function(){
self.set_controls_opacity("0");
},self.m.autohide);
};
self.player.addEventListener('mousemove', function(){
self.restartTimeout();
}, true);
self.restartTimeout();
/*
//self.module.addEventListener('load', self.moduleDidLoad, true);
self.module.addEventListener('message', self.handleMessage, true);
self.module.addEventListener('error', self.handleError, true);
self.module.addEventListener('crash', self.handleCrash, true);
*/
if (typeof window.attachListeners !== 'undefined') {
window.attachListeners();
}
self.error = function(){
return self.m.lastErrorCode;
}
self.errorDecoder = function(){
return self.m.lastErrorDecoder;
}
self.controls = function(val){
if(val == undefined){
return self.m.controls;
}else{
if(val == true){
self.set_controls_display("");
self.m.controls = true;
}else if(val == false){
self.set_controls_display("none");
self.m.controls = false;
}
}
}
self.debug = function(val){
if(val == undefined){
return self.m.debug;
}else{
self.m.debug = val;
}
}
// Truen
var stinit = 0;
var svt = 0;
var sdt = 0;
self.play = function(){
self.hideerror();
self.m.vxgReadyState = 1;
if (self.pipeline === undefined || self.pipeline == null) {
var isCreated = self.createPipeline();
if (isCreated != true) {
el_loader.style.display = "none";
return;
}
}
self.pipeline.ready.then(function(){
firstPackage = null;
self.pipeline.rtsp.play();
//self.pipeline.play();
//record-on-start 300s
//self.startRecord(300*1000);
el_stop.style.display = "inline-block";
el_pause.style.display = "inline-block";
el_takescreenshot.style.display = "inline-block";
el_loader.style.display = "none";
if(self.onStateChangeCallback){
self.onStateChangeCallback(self.m.vxgReadyState);
}
});
if(self.m.debug)
console.log( 'self.play self.m.url='+self.m.url + ' self.m.is_opened='+self.m.is_opened);
if(!self.m.is_opened){
self.m.is_opened = true;
/*
self.module.command('open', self.m.url);
*/
}
el_play.style.display = "none";
if(self.m.vxgReadyState != 4) {//not paused=>play, show progress
el_loader.style.display = "inline-block";
}
/*
self.module.command('play', '0');
*/
self.applyVolume();
stinit = 0;
svt = 0;
sdt = 0;
self.wdwork = setTimeout(function(){
self.updateStreamInfo();
}, 1000);
};
self.restart = function (reason) {
console.log(reason);
self.wdtries = 0;
self.wd = null;
clearTimeout(self.wdwork);
self.wdwork = null;
self.stop();
self.play();
}
self.updateStreamInfo = function() {
if (self.pipeline) {
var curtime = self.pipeline.currentTime;
if(self.m.debug){
console.log("curtime:" + curtime + "; wd:" + self.wd);
}
if (stinit == 0) {
svt = curtime;
sdt = Date.now();
stinit = 1;
}
var stdiff = ((Date.now() - sdt) / 1000) - (curtime - svt);
if (stdiff >= 0.5) {
//console.warn('update currenttime! id : ' + self.id + ', dif : ' + stdiff);
//el_video.currentTime = Date.now();
}
if (self.m.watchdog <= 0 ) {
console.log('Watchdog disabled by user');
return;
}
if (self.video.paused && !self.m.playAfterBufferFill) {
console.log('Video paused. Skip watchdog');
var now = Date.now();
//console.log("Now: " + now + ", lastRecvTime: " + self.m.lastRecvTime);
if ((now - self.m.lastRecvTime) > 5 * 1000) {
self.m.lastRecvTime = now;
self.restart('restart by recvTime');
return;
}
self.wdtries = 0;
self.wd = curtime;
self.wdwork = setTimeout(function(){
self.updateStreamInfo();
}, 1000);
return;
}
if ((self.wd == null) || /*(self.video.paused) || */((curtime - self.wd >= 0.0) && (self.wdtries < self.m.watchdog) ) ){
if ((curtime - self.wd > 0.2)/* || (self.video.paused)*/ ){
self.wdtries = 0;
} else {
self.wdtries += 1;
}
self.wd = curtime;
self.wdwork = setTimeout(function(){
self.updateStreamInfo();
}, 1000);
} else {
self.restart('restart by wd');
}
}
}
self.stop = function(){
/*
self.module.command('stop', '0');
*/
pps = '';
sps = '';
if (self.wdwork) {
clearTimeout(self.wdwork);
self.wdwork = null;
}
self.wdtries = 0;
self.wd = null;
if (dataCatcherWdId) {
clearTimeout(dataCatcherWdId);
dataCatcherWdId = null;
}
dataCatcherWdCnt = 0;
if (self.pipeline !== undefined && self.pipeline != null) {
self.pipeline.pause();
self.pipeline.close();
self.pipeline = null;
}
if (self.audBuffer) {
self.audBuffer.clear();
//self.audBuffer = null;
}
self.m.vxgReadyState = 0;
el_play.style.display = "inline-block";
el_stop.style.display = "none";
el_pause.style.display = "none";
el_takescreenshot.style.display = "none";
if(self.onStateChangeCallback){
self.onStateChangeCallback(self.m.vxgReadyState);
}
el_loader.style.display = "none";
};
self.pause = function(){
//console.log("pause");
/*
self.module.command('pause', '0');
*/
self.pipeline.pause();
if (self.audBuffer) {
self.audBuffer.clear();
}
self.m.vxgReadyState = 4;
el_play.style.display = "inline-block";
el_stop.style.display = "inline-block";
el_pause.style.display = "none";
// el_takescreenshot.style.display = "none";
if(self.onStateChangeCallback) {
self.onStateChangeCallback(self.m.vxgReadyState);
}
el_loader.style.display = "none";
};
self.autohide = function(val){
if(val){
self.m.autohide = val*1000;
}else{
return self.m.autohide/1000;
}
}
self.autoreconnect = function(val){
if(val == undefined){
return self.m.autoreconnect;
}else{
self.m.autoreconnect = parseInt(val,10);
/*
self.module.command('setautoreconnect', self.m.autoreconnect.toString());
*/
}
};
self.latency = function(val){
if(val && val >= 0){
self.m.latency = parseInt(val,10);
/*
self.module.command('setlatency', val.toString());
*/
}else{
return self.m.latency;
}
};
self.connection_timeout = function(val){
if(val){
self.m.connection_timeout = parseInt(val,10);
/*
self.module.command('setconnection_timeout', val.toString());
*/
}else{
return self.m.connection_timeout;
}
};
self.connection_udp = function(val){
if(val){
self.m.connection_udp = parseInt(val,10);
/*
self.module.command('setconnection_udp', val.toString());
*/
}else{
return self.m.connection_udp;
}
};
/*
self.aspectRatio = function(val){
if(val == undefined){
return self.m.aspectRatio?true:false;
}else{
self.m.aspectRatio = (val)?self.m.aspectRatioMode:0;
self.module.command('setaspectratio', self.m.aspectRatio.toString());
}
}
*/
self.aspectRatioMode = function(val){
if(val == undefined){
return self.m.aspectRatioMode;
}else{
self.m.aspectRatioMode = (val > 0)?val:self.m.aspectRatioMode;
self.m.aspectRatio = val;
if (val == 0) {
self.video.classList.remove('fill');
self.video.classList.remove('cover');
self.video.classList.add('contain');
} else if (val == 1) {
self.video.classList.remove('fill');
self.video.classList.add('cover');
self.video.classList.remove('contain');
} else if (val == 2) {
self.video.classList.add('fill');
self.video.classList.remove('cover');
self.video.classList.remove('contain');
}
}
}
self.aspectRatioMode(self.m.aspectRatio);
self.avsync = function(val){
if(val == undefined){
return self.m.avsync;
}else{
self.m.avsync = val;
/*
self.module.command('setavsync', self.m.avsync ? '1':'0');
*/
}
}
self.isPlaying = function(){
return (self.m.vxgReadyState == 2);
}
self.versionPLG = function(){
return window.vxgwsplayer.version;
}
self.versionAPP = function(){
return self.m.versionapp;
}
self.size = function(width, height){
if(width && height){
if(Number.isInteger(width) && Number.isInteger(height)){
var w = parseInt(width,10);
var h = parseInt(height,10);
self.playerWidth = self.playerWidth != w ? w : self.playerWidth;
self.playerHeight = self.playerHeight != h ? h : self.playerHeight;
self.player.style.width = width + 'px';
self.player.style.height = height + 'px';
}else{
self.player.style.width = width;
self.player.style.height = height;
}
}else{
return { width: self.playerWidth, height: self.playerHeight };
}
};
self.changedFullscreen = function(){
console.log('changedFullscreen');
if (document.webkitIsFullScreen){
self.size('100%', '100%');
console.log('changedFullscreen -> fullscreen');
}else{
self.size(self.playerWidth + 'px', self.playerHeight + 'px');
console.log('changedFullscreen -> NOT fullscreen');
}
};
if (document.addEventListener){
document.addEventListener('webkitfullscreenchange', self.changedFullscreen, false);
document.addEventListener('mozfullscreenchange', self.changedFullscreen, false);
document.addEventListener('fullscreenchange', self.changedFullscreen, false);
document.addEventListener('MSFullscreenChange', self.changedFullscreen, false);
}
self.fullscreen = function(){
console.log("fullscreen: clicked");
if(document.webkitIsFullScreen == true){
document.webkitCancelFullScreen();
}else{
if(self.player.requestFullscreen) {
self.player.requestFullscreen();
} else if(self.player.webkitRequestFullscreen) {
self.player.webkitRequestFullscreen();
} else if(self.player.mozRequestFullscreen) {
self.player.mozRequestFullScreen();
}
}
};
self.takescreenshot = function(){
var stub = el_snap_stub;
var videotag = el_video;
if (videotag != null ) {
var width = videotag.videoWidth ;
var height = videotag.videoHeight;
if ((width > 0) && (height > 0)) {
stub.setAttribute('width', width);
stub.setAttribute('height', height);
context = stub.getContext('2d');
if (context != null) {
context.fillRect(0, 0, width, height);
context.drawImage(videotag, 0, 0, width, height);
var downloadLink = document.createElement('a');
// jpg
downloadLink.setAttribute('download', 'snapshot.jpg');
stub.toBlob(function(blob) {
var url = URL.createObjectURL(blob);
downloadLink.setAttribute('href', url);
downloadLink.click();
}, 'image/jpeg', 1.0);
/* png
downloadLink.setAttribute('download', 'snapshot.png');
stub.toBlob(function(blob) {
var url = URL.createObjectURL(blob);
downloadLink.setAttribute('href', url);
downloadLink.click();
});
*/
}
}
}
el_screenshot_loading.style.display = "block";
setTimeout(function(){
el_screenshot_loading.style.display = "";
},3000);
};
self.getScreenshotPTS = function(){
return self.m.snapshotPTS;
};
self.getPTSVideo = function(){
return self.m.PTSVideo;
};
self.getPTSAudio = function(){
return self.m.PTSAudio;
};
var audioCtx = null;
var audioGain = null;
var audioFlt = null;
var audIsRun = false;
var audBuffer = null;
self.initAudioCtx = function() {
if (self.audioCtx != null || self.audioCtx !== undefined) {
return;
}
try {
window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.oAudioContext || window.msAudioContext;
self.audioCtx = new AudioContext();
self.audioCtx.onstatechange = function() {
if (self.audioCtx !== null && self.audioCtx !== undefined) {
if (self.audioCtx.state === "running") {
console.log(" audio context running");
self.audIsRun = true;
} else if (audioContext.state === "closed") {
console.log(" audio context close");
self.audioCtx = null;
self.audIsRun = false;
}
}
}
if (self.audioCtx !== undefined && self.audioCtx !== null) {
self.audioGain = self.audioCtx.createGain();
self.audBuffer = new audioBufferPCM(self.audioCtx, self.audioGain, 8000, 8/*48*/);
self.audioGain.connect(self.audioCtx.destination)
}
return true;
} catch (err) {
console.warn("Web Audio API is not supported in this web browser! : ", err);
}
}
self.audioPlayBuffer = function( data ) {
if (!self.audIsRun) {
return;
}
//test sinus for noise camera
//for (var i = 0; i < data.length; ++i) {
// data[i] = (Math.sin( i ) + 1.0) * 256;
//}
var data_js = new Float32Array(data.length);
for (var i = 0; i < data.length; i++) {
data_js[i] = data[i] / Math.pow(2, 15)
}
if(self.isMute()) {
self.audioGain.gain.value = 0;
} else {
self.audioGain.gain.value = self.m.volume;
}
if (self.audBuffer != null && self.audBuffer !== undefined) {
self.audBuffer.addBuffer( data_js);
}
delete data_js;
data_js = null;
}
self.recordedData264 = null;
self.recordedData711 = null;
var recData264Len = 0;
var recData711Len = 0;
var isRecording = false;
var isRecStarted = false;
var isRecStopping = false;
var firstPackage = null;
var record_wd = null;
var record_try = 0;
var prevRecLen = 0;
self.rech264maxsize = self.options.clipH264maxsize || Number(self.player.getAttribute('clipH264maxsize')) || 768*1024*1024; //~10min for 10Mbit
self.recg711maxsize = self.options.clipG711maxsize || Number(self.player.getAttribute('clipG711maxsize')) || 64*1024*1024;
self.defaultClipName = self.options.clipname || self.player.getAttribute('clipname') || 'clip';
var pps = '';
var sps = '';
// Truen
var dataCatcherWdId = undefined;
var dataCatcherWdCnt = 0;
self.m.debug = self.options.debug || self.player.hasAttribute('debug') || false;
function arraysAreEqual(a, b) {
var ret_val =
Array.isArray(a) &&
Array.isArray(b) &&
a.length === b.length &&
a.every((val, index) => val === b[index]);
return ret_val;
}
self.debug = function(){
//pps = '1'; //test possible pps-changing
}
self.createPipeline = function(){
el_loader.style.display = "inline-block";
firstPackage = null;
if ((self.m.wsurl !== undefined && self.m.wsurl.length > 0)
&& (self.m.rtspurl !== undefined && self.m.rtspurl.length > 0)){
self.m.is_opened = true;
let Pipeline = pipelines.Html5VideoPipeline;
let mediaElement = el_video;
pps = '';
sps = '';
var authopts = {}
if (self.m.user && self.m.password) {
authopts = {
username: self.m.user,
password: self.m.password
}
}
self.pipeline = new Pipeline({
ws: {
uri: self.m.wsurl,
},
rtsp: {
uri: self.m.rtspurl,
},
auth: authopts,
mediaElement,
});
self.pipeline.onSourceOpen = function(mse, tracks) {
//mse.duration = 10.0;
//mse.sourceBuffers[0].timestampOffset = -3.0;
}
var dataCatcherRTP = new components.dataCatcherDepay(0);//ULAW
dataCatcherRTP.onDataCallback = function( msg) {
if(self.m.debug){
console.log('Playback' + ((isRecording)?('+Recording'):('')) +': data(ulaw) catcher: len ' + msg.data.length + ' type:' + msg.type + ' rawdata len ' + msg.rawdata.length );
}
if (isRecStarted == true) {
if (recData711Len + msg.data.length < self.recg711maxsize) {
var data = msg.data;
self.recordedData711.set( data, recData711Len);
recData711Len += data.length;
delete msg.data;
delete data; data = null;
}
}
msg = null;
}
self.pipeline.insertAfter(self.pipeline.firstComponent.next, dataCatcherRTP);
var lastupdatetime = Date.now();
var forceupdatecheckcount = 0;
var forceupdatecountthreshold = 10;
var forceupdatetimethreshold = 100; //ms
self.pipeline.onDataCallback = function(sourceBuffer, msg) { // mp4 with H264 or H264+AAC
self.m.lastRecvTime = Date.now();
var b = sourceBuffer.buffered;
if (b.length == 0) {
//console.log('no buffer');
} else if (false) {
if ((b.end(0)*1000 - self.m.latency > 0) && (self.video.paused ) && (self.m.vxgReadyState != 4)) {
self.video.paused = false;
self.pipeline.play();
}
else {
if ((Date.now() - lastupdatetime >= 100) || forceupdatecheckcount > 0) {
if ((self.video.currentTime + (self.m.latency + forceupdatetimethreshold)/1000) < b.end(0)) {
forceupdatecheckcount++;
if (forceupdatecheckcount > forceupdatecountthreshold) {
console.log('update time');
self.video.currentTime = b.end(0) - self.m.latency/1000;
forceupdatecheckcount = 0;
}
}
else {
if (forceupdatecheckcount > 0) {
forceupdatecheckcount = 0;
}
}
lastupdatetime = Date.now();
}
}
//console.log('buffer:' + b.start(0) + '~' + b.end(0));
}
else {
if (self.m.playAfterBufferFill) {
/*
for (var i = 0; i < b.length; i++) {
console.log('buffer[' + i + ']: ' + b.start(i) + ', ' + b.end(i));
}
*/
if (b.end(b.length - 1) * 1000 - self.m.latency >= 0) {
self.m.playAfterBufferFill = false;
console.log("Buffer filled. Start pipeline.");
self.pipeline.play();
}
}
}
if(self.m.debug){
console.log( 'Playback' + ((isRecording)?('+Recording'):('')) +': w.data length:' + msg.data.length );
}
if (firstPackage == null) {
firstPackage = msg.data;
}
if (isRecording == true) {
if (msg.idrPicture == true) {
isRecStarted = true;
}
if (isRecStarted) {
if( recData264Len + msg.data.length < self.rech264maxsize) {
var data = msg.data;
self.recordedData264.set( data, recData264Len);
recData264Len += data.length;
delete msg.data;
delete data; data = null;
}
else { // Truen
console.warn('len(' + recData264Len + ') + new(' + msg.data.length + ') >= max(' + self.rech264maxsize + ')');
clearTimeout(record_wd);
self.stopRecord();
record_try = 0;
}
}
}
msg = null;
}
// Truen
function dataCatcherWd() {
dataCatcherWdCnt++;
if (dataCatcherWdCnt > 4) {
setTimeout(function() {
self.restart('restart by dataCatcherWd');
},10);
}
else {
dataCatcherWdId = setTimeout(function() {
dataCatcherWd();
}, 1000);
}
}
/* raw pcm (after g711 decode) data callback*/
var dataCatcherPCM = new components.g711toPCM(); //96-h264, 97-aac, 98-metadata, 0-g711?
dataCatcherPCM.onDataCallback = function( msg) {
self.initAudioCtx();
self.audioPlayBuffer(msg.data);
delete msg.data;
msg = null;
// Truen
if (dataCatcherWdId != undefined) {
clearTimeout(dataCatcherWdId);
}
dataCatcherWdCnt = 0;
dataCatcherWdId = setTimeout(function() {
dataCatcherWd();
},1000);
}
self.pipeline.insertAfter(self.pipeline.firstComponent.next.next, dataCatcherPCM);
/* catch h264 sps/pps data callback*/
var dataCatcherH264 = new components.dataCatcherDepay(96);
dataCatcherH264.onDataCallback = function( msg) {
/* Truen
if (msg.data[0] == 0x67) {
//console.log('data[H264] : SPS');
if (sps == '') {
sps = Array.from(msg.data);
} else if ( !arraysAreEqual (sps, Array.from(msg.data)) ) {
setTimeout(function(){
self.restart('restart by sps-changed');
},10);
}
} else */if (msg.data[0] == 0x68) {
//console.log('data[H264] : PPS');
if (pps == '') {
pps = Array.from(msg.data);
} else if ( !arraysAreEqual ( pps, Array.from(msg.data)) ) {
setTimeout(function(){
self.restart('restart by pps-changed');
},10);
}
}
// Truen
if (dataCatcherWdId != undefined) {
clearTimeout(dataCatcherWdId);
}
dataCatcherWdCnt = 0;
dataCatcherWdId = setTimeout(function() {
dataCatcherWd();
},1000);
}
self.pipeline.insertAfter(self.pipeline.firstComponent.next, dataCatcherH264);
/*
// aac - data callback
var dataCatcherAAC = new components.dataCatcherDepay(97); //96-h264, 97-aac, 98-metadata, 0-g711?
dataCatcherAAC.onDataCallback = function( msg) {
console.log('data(aac) catcher: ' + msg.data.length + ' type:' + msg.type );
}
self.pipeline.insertAfter(self.pipeline.firstComponent.next, dataCatcherAAC);
*/
self.pipeline.onSdp = function(sdp) {
console.log('onSdp');
var str = sdp.rawdata.toString();
console.log(str);
console.log(sdp);
}
self.pipeline.onPlay = function(range) {
console.log('onPlay: latency: ' + self.m.latency);
self.m.playAfterBufferFill = true;
//self.pipeline.play();
}
return true;
}
return false;
}
self.setSource = function (cameraIP, user, pwd, wsport=80, rtspport=554 ) {
if (cameraIP !== undefined) {
self.m.wsurl = 'ws://'+cameraIP+':'+wsport+'/rtsp_over_websocket';
self.m.rtspurl = 'rtsp://'+cameraIP+':'+rtspport+'/video1_audio1';
self.m.user = user;
self.m.password = pwd;
}
var isCreated = self.createPipeline();
if (isCreated) {
self.wdtries = 0;
self.play();
} else {
self.m.is_opened = false;
self.stop();
return undefined;
}
/*
if(url != undefined){
self.m.url = url;
console.log('Player ' + self.id+' src='+self.m.url+' autostart='+self.m.autostart+' is_opened='+self.m.is_opened);
if(self.m.url.length > 0 && self.m.autostart){
self.m.is_opened = true;
self.module.command('open', url);
}else{
self.m.is_opened = false;
//el_play.style.display = "inline-block";
//el_stop.style.display = "none";
//el_loader.style.display = 'none';
self.stop();
}
} else {
return self.m.url;
}
*/
}
self.dispose = function(){
self.player.innerHTML = "";
delete window.vxgwsplayer.players[self.id];
}
self.custom_digital_zoom = function(newval){
if(newval != undefined){
if(self.m.isCustomDigitalZoom == false && newval == true){
self.m.isCustomDigitalZoom = true;
self.setCustomDigitalZoom(100,0,0); // reset
self.set_controls_display("");
}else if(self.m.isCustomDigitalZoom == true && newval == false){
self.m.isCustomDigitalZoom = false;
self.set_controls_display("");
self.setNewZoom(10);
}
}else{
return self.m.isCustomDigitalZoom;
}
}
self.setCustomDigitalZoom = function(ratio, x, y){
if (ratio !== parseInt(ratio, 10) || x !== parseInt(x, 10) || y !== parseInt(y, 10)){
throw "[vxgwsplayer] setDigitalZoom / Some values is not integer";
}
if(ratio < 100 || ratio > 1000/*500*/){ // Truen
throw "[vxgwsplayer] setDigitalZoom / Parameter Ratio must be 100..500";
}
if(self.m.isCustomDigitalZoom != true){
throw "[vxgwsplayer] setDigitalZoom / Please enable custom digital zoom";
}
self.video.style.transform = "scale(" + (ratio/100) + ")";
el_controls_zoom_position.style.display = "none";
var s = self.size();
var newx = x - s.width/2;
var newy = y - s.height/2;
var neww = s.width*(100/ratio);
var newh = s.height*(100/ratio);
var left = Math.floor(-100*(newx + neww/2)/neww);
var top = Math.floor(-100*(newy + newh/2)/newh);
self.video.style.left = left + '%';
self.video.style.top = top + '%';
}
self.setNewZoom = function(v){
if(v >= 30){ v = 30; }
if(v <= 10){ v = 10; }
if(self.currentZoom != v){
self.currentZoom = v;
self.video.style.transform = "scale(" + (ratio/100) + ")";
el_zoomPositionCursor.style.transform = "scale(" + (10/self.currentZoom) + ")";
el_zoomProgress.className = el_zoomProgress.className.replace(/zoom\d+x/g,'zoom' + Math.ceil(self.currentZoom) + 'x');
el_controls_zoom_position.style.display = self.currentZoom == 10 ? "none" : "";
self.video.style.left = left + '%';
self.video.style.top = top + '%';
el_zoomPositionCursor.style.left = '';
el_zoomPositionCursor.style.top = '';
}
}
self.zoomUp = function(){
self.setNewZoom(self.currentZoom + 5)
}
self.zoomDown = function(){
self.setNewZoom(self.currentZoom - 5);
}
self.zoomProgressDownBool = false;
self.zoomProgressDown = function(e){
self.zoomProgressDownBool = true;
}
self.zoomProgressMove = function(e){
if(self.zoomProgressDownBool == true){
var y = e.pageY - vxgwsplayer.getAbsolutePosition(e.currentTarget).y;
var height = el_zoomProgress.offsetHeight;
var steps = height/5;
y = 10*(Math.floor((height-y)/steps)/2 + 1);
self.setNewZoom(y);
}
}
self.zoomProgressLeave = function(e){
self.zoomProgressDownBool = false;
}
self.zoomProgressUp = function(e){
if(self.zoomProgressDownBool == true){
var y = e.pageY - vxgwsplayer.getAbsolutePosition(e.currentTarget).y;
var height = el_zoomProgress.offsetHeight;
var steps = height/5;
y = 10*(Math.floor((height-y)/steps)/2 + 1);
self.setNewZoom(y);
}
self.zoomProgressDownBool = false;
}
self.zoomCursorDownBool = false;
self.zoomCursorX = 0;
self.zoomCursorY = 0;
self.zoomCursorWidth = 160;
self.zoomCursorHeight = 120;
self.zoomControlsWidth = 0;
self.zoomControlsHeight = 0;
self.zoomCursorDown = function(e){
self.zoomCursorX = e.pageX;
self.zoomCursorY = e.pageY;
self.zoomCursorWidth = el_zoomPositionCursor.offsetWidth;
self.zoomCursorHeight = el_zoomPositionCursor.offsetHeight;
self.zoomControlsWidth = el_controls_zoom_position.offsetWidth;
self.zoomControlsHeight = el_controls_zoom_position.offsetHeight;
self.zoomCursorDownBool = true;
}
self.zoomCursorUp = function(e){
console.log("zoomCursorUp");
self.zoomCursorDownBool = false;
}
self.zoomCursorMove = function(e){
if(self.zoomCursorDownBool == true){
var diffX = self.zoomCursorX - e.pageX;
var diffY = self.zoomCursorY - e.pageY;
self.zoomCursorX = e.pageX;
self.zoomCursorY = e.pageY;
var newx = el_zoomPositionCursor.offsetLeft - diffX;
var newy = el_zoomPositionCursor.offsetTop - diffY;
var d2x = (self.zoomControlsWidth - self.zoomCursorWidth*(10/self.currentZoom));
var d2y = (self.zoomControlsHeight - self.zoomCursorHeight*(10/self.currentZoom));
var minX = -1*d2x/2;
var maxX = d2x/2;
var minY = -1*d2y/2;
var maxY = d2y/2;
if(newx < minX) newx = minX;
if(newy < minY) newy = minY;
if(newx >= maxX) newx = maxX;
if(newy >= maxY) newy = maxY;
el_zoomPositionCursor.style.left = newx + "px";
el_zoomPositionCursor.style.top = newy + "px";
var zoom = self.currentZoom/10 - 1;
var left = Math.floor(-100*((newx/d2x)*zoom));
var top = Math.floor(-100*((newy/d2y)*zoom));
self.video.style.left = left + '%';
self.video.style.top = top + '%';
}
}
self.setNewZoom = function(v){
if(v >= 30){ v = 30; }
if(v <= 10){ v = 10; }
if(self.currentZoom != v){
self.currentZoom = v;
self.video.style.transform = "scale(" + (self.currentZoom/10) + ")";
el_zoomPositionCursor.style.transform = "scale(" + (10/self.currentZoom) + ")";
el_zoomProgress.className = el_zoomProgress.className.replace(/zoom\d+x/g,'zoom' + Math.ceil(self.currentZoom) + 'x');
el_controls_zoom_position.style.display = self.currentZoom == 10 ? "none" : "";
self.video.style.left = '';
self.video.style.top = '';
el_zoomPositionCursor.style.left = '';
el_zoomPositionCursor.style.top = '';
}
}
self.zoomUp = function(){
self.setNewZoom(self.currentZoom + 5)
}
self.zoomDown = function(){
self.setNewZoom(self.currentZoom - 5);
}
self.zoomProgressDownBool = false;
self.zoomProgressDown = function(e){
self.zoomProgressDownBool = true;
}
self.zoomProgressMove = function(e){
if(self.zoomProgressDownBool == true){
var y = e.pageY - vxgwsplayer.getAbsolutePosition(e.currentTarget).y;
var height = el_zoomProgress.offsetHeight;
var steps = height/5;
y = 10*(Math.floor((height-y)/steps)/2 + 1);
self.setNewZoom(y);
}
}
self.zoomProgressLeave = function(e){
self.zoomProgressDownBool = false;
}
self.zoomProgressUp = function(e){
if(self.zoomProgressDownBool == true){
var y = e.pageY - vxgwsplayer.getAbsolutePosition(e.currentTarget).y;
var height = el_zoomProgress.offsetHeight;
var steps = height/5;
y = 10*(Math.floor((height-y)/steps)/2 + 1);
self.setNewZoom(y);
}
self.zoomProgressDownBool = false;
}
self.zoomCursorDownBool = false;
self.zoomCursorX = 0;
self.zoomCursorY = 0;
self.zoomCursorWidth = 160;
self.zoomCursorHeight = 120;
self.zoomControlsWidth = 0;
self.zoomControlsHeight = 0;
self.zoomCursorDown = function(e){
self.zoomCursorX = e.pageX;
self.zoomCursorY = e.pageY;
self.zoomCursorWidth = el_zoomPositionCursor.offsetWidth;
self.zoomCursorHeight = el_zoomPositionCursor.offsetHeight;
self.zoomControlsWidth = el_controls_zoom_position.offsetWidth;
self.zoomControlsHeight = el_controls_zoom_position.offsetHeight;
self.zoomCursorDownBool = true;
}
self.zoomCursorUp = function(e){
console.log("zoomCursorUp");
self.zoomCursorDownBool = false;
}
self.zoomCursorMove = function(e){
if(self.zoomCursorDownBool == true){
var diffX = self.zoomCursorX - e.pageX;
var diffY = self.zoomCursorY - e.pageY;
self.zoomCursorX = e.pageX;
self.zoomCursorY = e.pageY;
var newx = el_zoomPositionCursor.offsetLeft - diffX;
var newy = el_zoomPositionCursor.offsetTop - diffY;
var d2x = (self.zoomControlsWidth - self.zoomCursorWidth*(10/self.currentZoom));
var d2y = (self.zoomControlsHeight - self.zoomCursorHeight*(10/self.currentZoom));
var minX = -1*d2x/2;
var maxX = d2x/2;
var minY = -1*d2y/2;
var maxY = d2y/2;
if(newx < minX) newx = minX;
if(newy < minY) newy = minY;
if(newx >= maxX) newx = maxX;
if(newy >= maxY) newy = maxY;
el_zoomPositionCursor.style.left = newx + "px";
el_zoomPositionCursor.style.top = newy + "px";
var zoom = self.currentZoom/10 - 1;
var left = Math.floor(-100*((newx/d2x)*zoom));
var top = Math.floor(-100*((newy/d2y)*zoom));
self.video.style.left = left + '%';
self.video.style.top = top + '%';
}
}
var isAudioCapture = false;
var audioCapture = null;
self.startBackwardAudio = function () {
if (self.isAudioCapture) {
return;
}
if (!self.pipeline.rtsp.audioback_chnl) {
console.warn('backward channel not found in SDP');
return;
}
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
console.log('getUserMedia supported.');
navigator.mediaDevices.getUserMedia ({ audio: true })
.then(function(stream) {
var buflen = 2048;
var numchannels = 1;
var rtp_pkt;
var rtsp_hdr;
self.audioCapture = new AudioContext({ sampleRate: 8000 });
var input = self.audioCapture.createMediaStreamSource(stream);
var node = (input.context.createScriptProcessor ||
input.context.createJavaScriptNode).call(input.context,
buflen, numchannels, numchannels
);
self.isAudioCapture = true;
input.connect(node);
node.connect(input.context.destination);
node.onaudioprocess = function(e) {
if (self.isAudioCapture) {
var data = e.inputBuffer.getChannelData(0);
/*
console.log("got audio buffer: " + e.inputBuffer.length
+ " for " + e.inputBuffer.duration
+ " samplerate " + e.inputBuffer.sampleRate
+ " data: [" + data[0] + "][" + data[1] + "][" + data[2] + "][" + data[3] + "]"
);
*/
if (!rtsp_hdr) {
//console.log(self.pipeline);
//console.log(self.pipeline.rtsp);
//console.log(self.pipeline.rtsp.audioback_chnl);
// Stream data (such as RTP packets) is encapsulated by an ASCII dollar sign
// (0x24 hexadecimal), followed by one byte of channel identifier, followed by two bytes of the length of
// the encapsulated binary data.The stream data follows immediately afterwards.Each $ block contains
// only one upper layer protocol data unit, such as an RTP packet.
var len = e.inputBuffer.length + 12;
rtsp_hdr = new Uint8Array(4);
rtsp_hdr[0] = 0x24;
rtsp_hdr[1] = self.pipeline.rtsp.audioback_chnl;
rtsp_hdr[2] = (len >>> 8);
rtsp_hdr[3] = (len & 0xFF);
rtsp_hdr._isBuffer = true;
rtsp_hdr.data = rtsp_hdr;
/* RFC3550 http://www.ietf.org/rfc/rfc3550.txt
V = 2, // version. always 2 (2 bits)
P = 0, // padding. (1 bit)
X = 0, // header extension (1 bit)
CC = 0, // CSRC count (4 bits)
M = 0, // marker (1 bit)
PT = 0, // payload type. (7 bits)
SN = // sequence number. SHOULD be random (16 bits)
TS = 1, // timestamp (32 bits)
SSRC = 1; // synchronization source (32 bits)
//CSRC = 0, // contributing sources (32 bits)
//DP = 0, // header extension, 'Defined By Profile' (16 bits)
//EL = 0; // header extension length (16 bits)
*/
rtp_pkt = new Uint8Array(len);
rtp_pkt[0] = 0x80;
rtp_pkt[1] = 0;//ulaw
var SN = Math.floor(1000 * Math.random());
rtp_pkt[2] = (SN >>> 8)
rtp_pkt[3] = (SN & 0xFF);
rtp_pkt[4] = 0;
rtp_pkt[5] = 0;
rtp_pkt[6] = 0;
rtp_pkt[7] = 1;
rtp_pkt[8] = 0;
rtp_pkt[9] = 0;
rtp_pkt[10] = 0;
rtp_pkt[11] = 1;
rtp_pkt._isBuffer = true;
rtp_pkt.data = rtp_pkt;
}
var seq = (rtp_pkt[2] << 8 | rtp_pkt[3]) + 1;
seq = seq.toUnsigned();
if (seq <= 65535) {
rtp_pkt[2] = (seq >>> 8);
rtp_pkt[3] = (seq & 0xFF);
}
var time = (rtp_pkt[4] << 24 | rtp_pkt[5] << 16 | rtp_pkt[6] << 8 | rtp_pkt[7]) + rtp_pkt.length;
time = time.toUnsigned();
if (time <= 4294967295) {
rtp_pkt[4] = (time >>> 24);
rtp_pkt[5] = (time >>> 16 & 0xFF);
rtp_pkt[6] = (time >>> 8 & 0xFF);
rtp_pkt[7] = (time & 0xFF);
}
self.pipeline._src.outgoing.write(rtsp_hdr);
self.pipeline._src.outgoing.write(rtp_pkt);
const BIAS = 0x84;
const CLIP = 32635;
for (var i = 0; i < e.inputBuffer.length; ++i) {
var pcm_16_sample = Math.min(1, data[i]) * 0x7FFF;
var sign = (pcm_16_sample >> 8) & 0x80;
if (sign != 0) pcm_16_sample = -pcm_16_sample;
pcm_16_sample = pcm_16_sample + BIAS;
if (pcm_16_sample > CLIP) pcm_16_sample = CLIP;
var exponent = ulawencodeTable[(pcm_16_sample >> 7) & 0xFF];
var mantissa = (pcm_16_sample >> (exponent + 3)) & 0x0F;
rtp_pkt[i+12] = ~(sign | (exponent << 4) | mantissa);
}
self.pipeline._src.outgoing.write(rtsp_hdr);
self.pipeline._src.outgoing.write(rtp_pkt);
}
}
}).catch(function(err) {
console.log('The following getUserMedia error occured: ' + err);
});
} else {
console.log('getUserMedia not supported on your browser!');
}
}
self.stopBackwardAudio = function() {
self.isAudioCapture = false;
self.audioCapture = null;
}
function wait(delayInMS) {
return new Promise(resolve => setTimeout(resolve, delayInMS));
}
function mergeTypedArrays(a, b) {
if(!a && !b) throw 'Please specify valid arguments for parameters a and b.';
if(!b || b.length === 0) return a;
if(!a || a.length === 0) return b;
if(Object.prototype.toString.call(a) !== Object.prototype.toString.call(b))
throw 'The types of the two arguments passed for parameters a and b do not match.';
var c = new a.constructor(a.length + b.length);
c.set(a);
c.set(b, a.length);
return c;
}
self.onRecord = null;
self.ffmpeg_worker = null;
self.startRecord = function( ms_length = 5000){
isRecStarted = false;
if (isRecording || isRecStopping) return;
self.ffmpeg_worker = new Worker('/vxgwsplayer/ffmpeg/ffmpeg-worker-mp4.js');
clearTimeout(record_wd);
prevRecLen = 0;
self.recordedData264 = new Uint8Array(self.rech264maxsize);
self.recordedData711 = new Uint8Array(self.recg711maxsize);
recData264Len = 0;
recData711Len = 0;
if (firstPackage != null) {
self.recordedData264.set(firstPackage, recData264Len);
recData264Len += firstPackage.length;
}
isRecording = true;
isRecStopping = false;
if (self.onRecord !== null) {
var args = {};
args.isRecording = isRecording;
args.isRecStopping = isRecStopping;
self.onRecord(args);
}
if (ms_length > 0) {
setTimeout(function(){
self.stopRecord();
}, ms_length);
}
function recordWd () {
clearTimeout(record_wd);
if (!isRecording) return;
if (!isRecStarted || recData264Len > prevRecLen) {
prevRecLen = recData264Len;
console.log('record watchdog: OK - record in process');
record_wd = setTimeout(function(){recordWd();}, 5000);
} else {
if (record_try > 3) {
console.warn('Early record save before expected time due record stream error or allocated memmory is over');
self.stopRecord();
record_try = 0;
} else {
console.log('record watchdog: may be error (recdata:'+recData264Len+'<= prevrecorded:'+prevRecLen+'<= maxsize:'+self.rech264maxsize+'): - check in process ');
record_try += 1;
record_wd = setTimeout(function(){recordWd();}, 5000);
}
}
}
record_wd = setTimeout(function(){recordWd();}, 5000);
}
self.stopRecord = async function stopRecord() {
if (isRecording == false || isRecStopping == true) {
return;
}
isRecording = false;
isRecStarted = false;
isRecStopping = true;
if (self.onRecord !== null) {
var args = {};
args.isRecording = isRecording;
args.isRecStopping = isRecStopping;
self.onRecord(args);
}
//const OUT_FILE_NAME = self.defaultClipName + '.avi';
const OUT_FILE_NAME = self.defaultClipName + '.mkv';
//const OUT_FILE_NAME = self.defaultClipName + '.mov';
var data = self.recordedData264.subarray(0, recData264Len);
var outfile;
self.ffmpeg_worker.onmessage = function(arg) {
var msg = arg.data;
switch (msg.type) {
case "stdout":
console.log("ffmpeg: stdout: " + msg.data);
break;
case "stderr":
console.log("ffmpeg: stderr: " + msg.data);
break;
case "exit":
console.log("Process exited with code " + msg.data);
break;
case 'done': {
//const blob = new Blob([msg.data.MEMFS[0].data], {type: "video/avi"});
const blob = new Blob([msg.data.MEMFS[0].data], {type: "video/mkv"});
//const blob = new Blob([msg.data.MEMFS[0].data], {type: "video/mov"});
let a = document.createElement("a");
//document.body.appendChild(a);
a.style.display = 'none';
let url = URL.createObjectURL(blob);
a.href = url;
a.download = OUT_FILE_NAME;
a.click();
window.URL.revokeObjectURL(url);
delete self.recordedData264; self.recordedData264 = null;
delete self.recordedData711; self.recordedData711 = null;
recData264Len = 0;
recData711Len = 0;
isRecStopping = false;
if (self.onRecord !== null) {
var args = {};
args.isRecording = isRecording;
args.isRecStopping = isRecStopping;
self.onRecord(args);
}
setTimeout(function () {
if (self.ffmpeg_worker != null) {
self.ffmpeg_worker.terminate();
self.ffmpeg_worker = null;
}
}, 0);
} break;
}
};
if(self.recordedData711.length>0){
var data711 = self.recordedData711.subarray(0, recData711Len);
self.ffmpeg_worker.postMessage({
type: 'run',
TOTAL_MEMORY: 581510912, // 268435456,
// arguments: ['-formats']
//avi
//arguments: ['-r','30', '-i', 'input.mp4', '-f', 'mulaw', '-ar', '8000', '-ac', '1', '-i', 'input.ulaw', '-vcodec', 'copy', '-acodec', 'copy', OUT_FILE_NAME],
//mkv
arguments: ['-i', 'input.mp4', '-f', 'mulaw', '-ar', '8000', '-ac', '1', '-i', 'input.ulaw', '-vcodec', 'copy', '-acodec', 'copy', OUT_FILE_NAME],
//mov
//arguments: ['-i', 'input.mp4', '-f', 'mulaw', '-ar', '8000', '-ac', '1', '-i', 'input.ulaw', '-vcodec', 'copy', '-acodec', 'copy', OUT_FILE_NAME],
MEMFS: [{name: 'input.mp4', data: data}, {name: 'input.ulaw', data: data711 }],
});
}else{
self.ffmpeg_worker.postMessage({
type: 'run',
TOTAL_MEMORY: 581510912, // 268435456,
//avi
//arguments: ['-r','30', '-i', 'input.mp4', '-vcodec', 'copy', '-acodec', 'copy', OUT_FILE_NAME],
//mkv
arguments: ['-i', 'input.mp4', '-vcodec', 'copy', '-acodec', 'copy', OUT_FILE_NAME],
//mov
//arguments: ['-i', 'input.mp4', '-vcodec', 'copy', '-acodec', 'copy', OUT_FILE_NAME],
MEMFS: [{name: 'input.mp4', data: data}],
});
}
/*
if(self.recordedData711.length>0){
var data711 = self.recordedData711.subarray(0, recData711Len);
var file2 = { name:IN_FILE_NAME_ULAW, data:data711}
const args = ['-i', IN_FILE_NAME_264, '-f', 'mulaw', '-ar', '8000', '-ac', '1', '-i', IN_FILE_NAME_ULAW, '-vcodec', 'copy', '-acodec', 'copy', OUT_FILE_NAME];
var ret = await runFFmpeg(IN_FILE_NAME_264, data, args, OUT_FILE_NAME, [ file2 ] );
data = null;
data711 = null;
ret.Core.PThread.ih();
delete ret.Core;
outfile = ret.file;
}
else{
const args = ['-i', IN_FILE_NAME_264, '-vcodec', 'copy', '-acodec', 'copy', OUT_FILE_NAME];
const ret = await runFFmpeg(IN_FILE_NAME_264, data, args, OUT_FILE_NAME );
data = null;
ret.Core.PThread.ih();
delete ret.Core;
outfile = ret.file;
}
let a = document.createElement("a");
document.body.appendChild(a);
a.style.display = 'none';
a.href = URL.createObjectURL(new Blob([outfile.buffer], { type: 'video/mp4' }));
a.download = OUT_FILE_NAME;
a.click();
delete self.recordedData264; self.recordedData264 = null;
delete self.recordedData711; self.recordedData711 = null;
recData264Len = 0;
recData711Len = 0;
isRecStopping = false;
if (self.onRecord !== null) {
var args = {};
args.isRecording = isRecording;
args.isRecStopping = isRecStopping;
self.onRecord(args);
}
*/
}
self.recordStatus = function() {
if (isRecording == true) {
var ret = {};
ret.recording = true;
ret.recStopping = false;
ret.recData264Len = recData264Len;
ret.recData711Len = recData711Len;
return ret;
} else if (isRecording == false && isRecStopping) {
var ret = {};
ret.recording = false;
ret.recStopping = true;
ret.recData264Len = recData264Len;
ret.recData711Len = recData711Len;
return ret;
} else {
var ret = {};
ret.recording = false;
ret.recStopping = false;
ret.recData264Len = recData264Len;
ret.recData711Len = recData711Len;
return ret;
}
}
el_play.onclick = self.play;
el_pause.onclick = self.pause;
el_stop.onclick = self.stop;
el_fullscreen.onclick = self.fullscreen;
el_takescreenshot.onclick = self.takescreenshot;
el_zoomUp.onclick = self.zoomUp;
el_zoomDown.onclick = self.zoomDown;
el_zoomPositionCursor.addEventListener('mousedown',self.zoomCursorDown,false);
el_zoomPositionCursor.addEventListener('mousemove',self.zoomCursorMove,false);
el_zoomPositionCursor.addEventListener('mouseleave',self.zoomCursorUp,false);
el_zoomPositionCursor.addEventListener('mouseup',self.zoomCursorUp,false);
el_zoomProgress.addEventListener('mousedown',self.zoomProgressDown,false);
el_zoomProgress.addEventListener('mousemove',self.zoomProgressMove,false);
el_zoomProgress.addEventListener('mouseleave',self.zoomProgressLeave,false);
el_zoomProgress.addEventListener('mouseup',self.zoomProgressUp,false);
}(id, options_);
window.vxgwsplayer.players[id].playerDidLoad();
}else{
// console.warn(id + " - already exists player");
}
return window.vxgwsplayer.players[id];
};
window.vxgwsplayer.webserverport = '8778';
window.vxgwsplayer.isFrame = function() {
try {
return window.self !== window.top;
} catch (e) {
return true;
}
}
/*
window.vxgwsplayer.browserSupportsPluginPnacl = function() {
return navigator.mimeTypes['application/x-pnacl'] !== undefined &&
navigator.mimeTypes['application/vxg_media_player'] !== undefined;
}
*/
window.vxgwsplayer.showGlobalErrorMessage = function(id, html){
var player = document.getElementById(id);
var width=640;
var height=480;
width = parseInt(player.width,10) || width;
height = parseInt(player.height,10) || height;
player.style.width = width + 'px';
player.style.height = height + 'px';
player.innerHTML = html;
return undefined;
}
window.vxgwsplayer.showNotInstalled = function(id){
vxgwsplayer.showGlobalErrorMessage(id, ''
+ '');
}
window.vxgwsplayer.showAvailableInChrome = function(id){
vxgwsplayer.showGlobalErrorMessage(id, ''
+ '');
}
window.vxgwsplayer.showWebSocketFailed = function(id){
vxgwsplayer.showGlobalErrorMessage(id, ''
+ ''
+ '
'
+ ' Could not connect to plugin (WebSocket Error). Please try restart your browser.'
+ '
'
+ '
');
}
window.vxgwsplayer.showNotInstalledInIncognitoMode = function(id){
vxgwsplayer.showGlobalErrorMessage(id, ''
+ ''
+ '
You have opened this page in incognito mode. Please open it in a regular tab, install the plugin and then come back.'
+ '
Also you can install
VXG Media Player from webstore in regular tab.'
+ '
'
+ '
');
}
window.vxgwsplayer.showNotStartedInIncognitoMode = function(id){
vxgwsplayer.showGlobalErrorMessage(id, ''
+ ''
+ '
You have opened this page in incognito mode. Please open it in a regular tab and then come back.'
+ '
'
+ '
');
}
window.vxgwsplayer.startPlayerInNewTab = function(){
console.log('start player');
var params = "menubar=yes,location=yes,resizable=yes,scrollbars=yes,status=yes"
var win = window.open('https://www.videoexpertsgroup.com/player_start/', "_blank", params)
setTimeout(function(){
win.close();
location.reload();
/*for(var id in window.vxgwsplayer.players){
console.log("Restart player: " + id);
}*/
},1000);
}
window.vxgwsplayer.showNotStartedInIFrame = function(id){
vxgwsplayer.showGlobalErrorMessage(id, ''
+ ''
+ '
You have opened this page in frame.
'
+ ' Please click on
this link for start Chrome App (VXG Media Player).'
+ '
'
+ '
');
}
window.vxgwsplayer.showInitFailed = function(id, str){
vxgwsplayer.showGlobalErrorMessage(id, ''
+ ''
+ '
'
+ ' Chrome plugin init error. Try to update Video/Audio drivers. '
+ str
+ '
'
+ '
');
}
window.vxgwsplayer.Promise = function(){
var completed = false;
this.done = function(callback){
this.done_callback = callback;
if(this.completed){
this.done_callback(this.err);
}
return this;
}
this.fail = function(callback){
this.fail_callback = callback;
if(this.completed){
this.fail_callback(this.err);
}
return this;
}
this.resolve = function(result) {
if(!this.completed){
this.result = result;
this.done_callback(result);
}
this.completed = true;
}
this.reject = function(err) {
if(!this.completed){
this.err = err;
this.fail_callback(err);
}
this.completed = true;
}
};
/*
window.vxgwsplayer.checkWebSocket = function(){
var p = new vxgwsplayer.Promise();
setTimeout(function(){
var testWebSocket = new WebSocket('ws://127.0.0.1:' + vxgwsplayer.webserverport + '/');
testWebSocket.onerror=function(event){
p.reject();
}
testWebSocket.onmessage = function(evt){
console.log(evt);
}
testWebSocket.onopen=function(){
testWebSocket.close();
p.resolve();
}
},60000);
return p;
}
*/
// helper funxtion
window.vxgwsplayer.getAbsolutePosition = function(element){
var r = { x: element.offsetLeft, y: element.offsetTop };
if (element.offsetParent) {
var tmp = vxgwsplayer.getAbsolutePosition(element.offsetParent);
r.x += tmp.x;
r.y += tmp.y;
}
return r;
};
// init options
window.vxgwsplayer.initOptions = function(self, options){
self.options = options || {};
self.m = {};
self.m.wsurl = self.player.getAttribute('wsurl') || self.options.wsurl || "";
self.m.rtspurl = self.player.getAttribute('rtspurl') || self.options.rtspurl || "";
self.m.user = self.player.getAttribute('user') || self.options.user || "";
self.m.password = self.player.getAttribute('password') || self.options.password || "";
/*
var nmf_path = "media_player.nmf";
var nmf_src = "pnacl/Release/media_player.nmf";
self.m.nmf_path = self.player.getAttribute('nmf-path') || self.options.nmf_path || nmf_path;
self.m.nmf_src = self.player.getAttribute('nmf-src') || self.options.nmf_src || nmf_src;
*/
self.m.autostart_parameter = self.player.hasAttribute('autostart') ? '1' : '0';
self.m.audio_parameter = (self.player.hasAttribute('audio') && parseInt(self.player.getAttribute('audio', 10)) == 0) ? '0' : '1';
self.m.mute_parameter = (self.player.hasAttribute('mute') && parseInt(self.player.getAttribute('mute', 10)) == 1) ? '1' : '0';
}
// generate embeded element for nacl player
/*
window.vxgwsplayer.generateEmbededElement = function(self){
return ''
+ '';
}
*/
class audioBufferPCM {
constructor(audioCtx, audioGain, sampleRate, bufferSize = 10) {
this.ctx = audioCtx;
this.gain = audioGain;
this.sampleRate = sampleRate;
this.bufferSize = bufferSize;
this.chunks = [];
this.isPlaying = false;
this.startTime = 0;
this.lastChunkOffset = 0;
}
clear() {
this.chunks.splice(0, this.chunks.length);
}
createChunk(chunk) {
var audioBuffer = this.ctx.createBuffer(1, chunk.length, this.sampleRate);
audioBuffer.getChannelData(0).set(chunk);
var source = this.ctx.createBufferSource();
source.buffer = audioBuffer;
source.connect(this.gain);
source.onended = (e) => {
this.chunks.splice(this.chunks.indexOf(source), 1);
if (this.chunks.length == 0) {
this.isPlaying = false;
this.startTime = 0;
this.lastChunkOffset = 0;
}
};
return source;
}
addBuffer(data) {
if (this.isPlaying && (this.chunks.length > this.bufferSize)) {
console.warn("audio chunk discarded");
return;
} else if (this.isPlaying && (this.chunks.length <= this.bufferSize)) { // schedule & add right now
var chunk = this.createChunk(data);
chunk.start(this.startTime + this.lastChunkOffset);
this.lastChunkOffset += chunk.buffer.duration;
this.chunks.push(chunk);
chunk = null;
} else if ((this.chunks.length < (this.bufferSize / 2)) && !this.isPlaying) { // add & don't schedule
var chunk = this.createChunk(data);
this.chunks.push(chunk);
chunk = null;
} else { // add & schedule entire buffer
this.isPlaying = true;
var chunk = this.createChunk(data);
this.chunks.push(chunk);
chunk = null;
this.startTime = this.ctx.currentTime;
this.lastChunkOffset = 0;
for (let i = 0; i < this.chunks.length; i++) {
var chunk = this.chunks[i];
chunk.start(this.startTime + this.lastChunkOffset);
this.lastChunkOffset += chunk.buffer.duration;
}
}
}
}
// init volumes
window.vxgwsplayer.initVolumeControls = function(self, onloadsettings){
self.m.volume = self.options.volume || 0.7;
var el_volumeMute = self.player.getElementsByClassName('vxgwsplayer-volume-mute')[0];
var el_volumeDown = self.player.getElementsByClassName('vxgwsplayer-volume-down')[0];
var el_volumeProgress = self.player.getElementsByClassName('vxgwsplayer-volume-progress')[0];
var el_volumeUp = self.player.getElementsByClassName('vxgwsplayer-volume-up')[0];
if(self.player.hasAttribute('volume')){
self.m.volume = parseFloat(self.player.getAttribute('volume'));
self.m.volume = Math.ceil(self.m.volume*10)/10;
if(onloadsettings){
/*
self.module.command('setvolume', self.m.volume.toFixed(1));
*/
}
}else if(self.options.volume){
console.warn("TODO volume");
}
self.m.mute = self.video.hasAttribute('muted') || self.options.mute || self.m.volume == 0 || self.m.mute_parameter == '1';
if(self.m.mute){
el_volumeDown.style.display='none';
el_volumeProgress.style.display='none';
el_volumeUp.style.display='none';
}
el_volumeProgress.className = el_volumeProgress.className.replace(/vol\d+/g,'vol' + Math.ceil(self.m.volume*10));
self.isMute = function(){
return self.m.mute;
}
self.applyVolume = function(){
if(self.isMute()){
el_volumeDown.style.display='none';
el_volumeProgress.style.display='none';
el_volumeUp.style.display='none';
el_volumeProgress.className = el_volumeProgress.className.replace(/vol\d+/g,'vol0')
}else{
el_volumeDown.style.display='inline-block';
el_volumeProgress.style.display='inline-block';
el_volumeUp.style.display='inline-block';
el_volumeProgress.className = el_volumeProgress.className.replace(/vol\d+/g,'vol' + Math.floor(self.m.volume*10));
}
/*
self.module.command('setvolume', self.m.mute? '0': '' + self.m.volume.toFixed(1));
*/
if (self.isMute()){
self.video.setAttribute('muted', true);
self.video.muted = true;
if (self.audioGain != null && self.audioGain !== undefined && self.audioCtx != null && self.audioCtx !== undefined) {
self.audioGain.gain.setValueAtTime(0, self.audioCtx.currentTime);
}
} else {
self.video.removeAttribute('muted');
self.video.muted = false;
self.video.setAttribute('volume', self.m.volume.toFixed(1));
self.video.volume = self.m.volume.toFixed(1);
if (self.audioGain != null && self.audioGain !== undefined && self.audioCtx != null && self.audioCtx !== undefined) {
self.audioGain.gain.setValueAtTime( self.m.volume, self.audioCtx.currentTime);
}
}
// self.video.volume = self.m.mute? '0': '' + self.m.volume.toFixed(1)
if (self.audioCtx !== undefined || self.audioCtx != null) {
self.audioCtx.resume();
}
}
self.mute = function(){
self.restartTimeout();
self.m.mute = !self.m.mute;
self.applyVolume();
}
self.volume = function(val){
if(val != undefined){
val = val > 1 ? 1 : val;
val = val < 0 ? 0 : val;
self.m.volume = Math.ceil(val*10)/10;
self.applyVolume();
}else{
return self.m.volume;
}
}
self.volup = function(){
self.restartTimeout();
if(Math.round(self.m.volume*10) < 10){
self.m.volume = self.m.volume + 0.1;
self.applyVolume();
}
};
self.voldown = function(){
self.restartTimeout();
if(Math.round(self.m.volume*10) > 0){
self.m.volume = self.m.volume - 0.1;
self.applyVolume();
}
};
el_volumeMute.onclick = self.mute;
el_volumeDown.onclick = self.voldown;
el_volumeUp.onclick = self.volup;
}
document.addEventListener('DOMContentLoaded', function() {
console.log("vxgwsplayer isFrame: " + window.vxgwsplayer.isFrame());
// console.log("vxgwsplayer browserSupportsPluginPnacl: " + window.vxgwsplayer.browserSupportsPluginPnacl());
// search all vxgwsplayers
var els = document.getElementsByClassName("vxgwsplayer");
for (var i = 0; i < els.length; i++) {
if(els[i].id){
vxgwsplayer(els[i].id);
}else{
console.error("Player has not id", els[i]);
}
}
// TODO check ws
// TODO start Chrome App
});