1
0
overte-synced-video/videoSyncServerScript.js
Darlingnotin d467a54c6c
Update videoSyncServerScript.js
Adding automatically scaling entity to handle aspect ratio of video playing.
2024-02-06 14:24:09 -05:00

290 lines
11 KiB
JavaScript

// Copyright (c) 2020 Danielle Arlington.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 3.
// https://www.gnu.org/licenses/gpl-3.0.en.html
(function () {
var videoSyncServerScriptUrl = Script.resolvePath("videoSyncServerScript.js");
var sourceUrl = Script.resolvePath("videoSync.html");
var timeStamp;
var messageData;
var pingTimer = 0;
var intervalIsRunning = false;
var videoUrl = "";
var timeStampInterval;
var thisTimeout;
var videoLength;
var videoPlaying = false;
var newVideoSent = false;
var newVideoSender;
var videoPlayerChannel;
var wsUrl;
var ws;
var useGatewayServer = false;
var gatewayServerConnected = false;
var connectionAttempts = 0;
var lastUpdated = 0;
var currentUserData;
var checkCurrentUserDataTimeout;
var checkCurrentUserDataTimeoutIsRunning = false;
var gatewayUserData = {
"useGatewayServer": false,
"wsUrl": "",
"serverConnected": false,
"lastUpdated": 0
};
function openWebSocket() {
var entityUserData = Entities.getEntityProperties(videoPlayerChannel, ["userData"]);
var UserData = JSON.parse(entityUserData.userData);
ws = new WebSocket(wsUrl);
ws.onopen = function () {
gatewayServerConnected = true;
connectionAttempts = 0;
UserData.serverConnected = true;
lastUpdated = Date.now();
UserData.lastUpdated = lastUpdated;
currentUserData = UserData;
updateUserData();
var webSocketConnected = {
"action": "webSocketConnected",
"wsUrl": currentUserData.wsUrl
};
Messages.sendMessage(videoPlayerChannel, JSON.stringify(webSocketConnected));
}
ws.onmessage = function (evt) {
var wsMessageData = JSON.parse(evt.data);
if (wsMessageData.action == "requestSync") {
var readyEvent = {
action: "sync",
timeStamp: timeStamp,
videoUrl: videoUrl,
nowVideo: "false",
videoPlaying: intervalIsRunning,
myTimeStamp: wsMessageData.myTimeStamp
};
ws.send(JSON.stringify(readyEvent));
}
}
ws.onclose = function () {
gatewayServerConnected = false;
UserData.serverConnected = false;
lastUpdated = Date.now();
UserData.lastUpdated = lastUpdated;
currentUserData = UserData;
updateUserData();
if (useGatewayServer) {
Script.setTimeout(function () {
connectionAttempts++;
if (connectionAttempts >= 2) {
useGatewayServer = false;
lastUpdated = Date.now();
gatewayUserData = {
"useGatewayServer": false,
"wsUrl": "",
"serverConnected": false,
"lastUpdated": lastUpdated
};
currentUserData = gatewayUserData;
currentUserData.lastUpdated = lastUpdated;
updateUserData();
} else {
openWebSocket();
}
}, 3000);
}
}
}
function updateUserData() {
Entities.editEntity(videoPlayerChannel, {
userData: JSON.stringify(currentUserData)
});
checkCurrentUserData();
}
function checkCurrentUserData() {
if (checkCurrentUserDataTimeoutIsRunning) {
clearTimeout(checkCurrentUserDataTimeout);
}
checkCurrentUserDataTimeout = Script.setTimeout(function () {
var entityUserData = Entities.getEntityProperties(videoPlayerChannel, ["userData"]);
var UserData = JSON.parse(entityUserData.userData);
if (UserData.lastUpdated != lastUpdated) {
console.log(currentUserData.lastUpdated + " " + lastUpdated);
updateUserData();
}
}, 6000);
}
this.preload = function (entityID) {
var entityUserData = Entities.getEntityProperties(entityID, ["userData"]);
var UserData = JSON.parse(entityUserData.userData);
wsUrl = UserData.wsUrl;
videoPlayerChannel = entityID;
Messages.subscribe(videoPlayerChannel);
if (UserData.useGatewayServer) {
useGatewayServer = true;
openWebSocket();
}
};
function onMessageReceived(channel, message, sender, localOnly) {
if (channel != videoPlayerChannel) {
return;
}
messageData = JSON.parse(message);
if (messageData.action == "now") {
videoPlaying = true;
newVideoSent = true;
newVideoSender = messageData.myTimeStamp;
timeStamp = messageData.timeStamp;
videoUrl = messageData.videoUrl;
videoLength = messageData.length;
if (intervalIsRunning) {
Script.clearInterval(timeStampInterval);
}
intervalIsRunning = true;
ping();
var wsNow = {
"action": "now",
"videoUrl": messageData.videoUrl,
"timeStamp": messageData.timeStamp
};
if (useGatewayServer && gatewayServerConnected) {
ws.send(JSON.stringify(wsNow));
}
console.log(JSON.stringify(messageData));
var entity = Entities.getEntityProperties(videoPlayerChannel);
entity.dimensions.y = (entity.dimensions.x / messageData.aspectRatio) + .1
Entities.editEntity(videoPlayerChannel, {
dimensions: entity.dimensions
});
} else if (messageData.action == "play") {
timeStamp = messageData.timeStamp;
if (intervalIsRunning) {
Script.clearInterval(timeStampInterval);
}
intervalIsRunning = true;
videoPlaying = true;
ping();
var wsPlay = {
"action": "play",
"timeStamp": messageData.timeStamp
};
if (useGatewayServer && gatewayServerConnected) {
ws.send(JSON.stringify(wsPlay));
}
} else if (messageData.action == "pause") {
Script.clearInterval(timeStampInterval);
intervalIsRunning = false;
var wsPause = {
"action": "pause",
"timeStamp": messageData.timeStamp
};
if (useGatewayServer && gatewayServerConnected) {
ws.send(JSON.stringify(wsPause));
}
} else if (messageData.action == "sync") {
timeStamp = messageData.timeStamp;
} else if (messageData.action == "requestSync") {
Script.setTimeout(function () {
var readyEvent = {
action: "sync",
timeStamp: timeStamp,
videoUrl: videoUrl,
nowVideo: "false",
videoPlaying: intervalIsRunning,
myTimeStamp: messageData.myTimeStamp
};
var message = JSON.stringify(readyEvent);
Messages.sendMessage(videoPlayerChannel, message);
}, 600);
} else if (messageData.action == "videoSyncGateway") {
if (!gatewayServerConnected) {
gatewayUserData.wsUrl = "ws://" + messageData.gatewayIp + ":7080";
gatewayUserData.useGatewayServer = true;
currentUserData = gatewayUserData;
updateUserData();
useGatewayServer = true;
wsUrl = "ws://" + messageData.gatewayIp + ":7080";
connectionAttempts = 0;
openWebSocket();
}
} else if (messageData.action == "reset") {
var entity = Entities.getEntityProperties(videoPlayerChannel, ["position", "dimensions", "rotation", "locked", "script"]);
var newVideoSync = Entities.addEntity({
type: "Web",
position: entity.position,
rotation: entity.rotation,
dimensions: entity.dimensions,
script: entity.script,
serverScripts: videoSyncServerScriptUrl,
sourceUrl: sourceUrl,
userData: JSON.stringify({
"useGatewayServer": false,
"wsUrl": "",
"serverConnected": false,
"lastUpdated": 0
}),
grab: {
"grabbable": false,
}
});
if (entity.locked) {
Entities.editEntity(videoPlayerChannel, {
locked: false
});
Script.setTimeout(function () {
Entities.editEntity(newVideoSync, {
locked: true
});
Entities.deleteEntity(videoPlayerChannel);
}, 3000);
} else {
Entities.deleteEntity(videoPlayerChannel);
}
}
}
function ping() {
timeStampInterval = Script.setInterval(function () {
timeStamp = timeStamp + 1;
pingTimer = pingTimer + 1;
if (timeStamp > videoLength) {
Script.clearInterval(timeStampInterval);
videoUrl = "";
videoPlaying = false;
intervalIsRunning = false;
var readyEvent = {
action: "videoEnd"
};
var message = JSON.stringify(readyEvent);
Messages.sendMessage(videoPlayerChannel, message);
}
if (pingTimer == 60) {
pingTimer = 0;
messageData.timeStamp = timeStamp;
messageData.action = "ping";
var message = JSON.stringify(messageData);
Messages.sendMessage(videoPlayerChannel, message);
if (useGatewayServer && gatewayServerConnected) {
ws.send(message);
}
}
}, 1000);
}
Messages.messageReceived.connect(onMessageReceived);
this.unload = function () {
Messages.unsubscribe(videoPlayerChannel);
Messages.messageReceived.disconnect(onMessageReceived);
if (intervalIsRunning) {
Script.clearInterval(timeStampInterval);
}
}
});