Adding initial files
This commit is contained in:
commit
30790d588a
BIN
assets/WaitingOnVideo.xcf
Normal file
BIN
assets/WaitingOnVideo.xcf
Normal file
Binary file not shown.
BIN
assets/WaitingOnVideoAfterClick.png
Normal file
BIN
assets/WaitingOnVideoAfterClick.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 78 KiB |
BIN
assets/WaitingOnVideoAfterClick.xcf
Normal file
BIN
assets/WaitingOnVideoAfterClick.xcf
Normal file
Binary file not shown.
BIN
assets/clickToWatch.png
Normal file
BIN
assets/clickToWatch.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 76 KiB |
BIN
assets/clickToWatch.xcf
Normal file
BIN
assets/clickToWatch.xcf
Normal file
Binary file not shown.
BIN
assets/leave.fbx
Normal file
BIN
assets/leave.fbx
Normal file
Binary file not shown.
BIN
assets/pauseButton.fbx
Normal file
BIN
assets/pauseButton.fbx
Normal file
Binary file not shown.
BIN
assets/playButton.fbx
Normal file
BIN
assets/playButton.fbx
Normal file
Binary file not shown.
BIN
assets/play_btn.png
Normal file
BIN
assets/play_btn.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 61 KiB |
BIN
assets/videoInProgress.png
Normal file
BIN
assets/videoInProgress.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 85 KiB |
BIN
assets/videoInProgress.xcf
Normal file
BIN
assets/videoInProgress.xcf
Normal file
Binary file not shown.
BIN
assets/videoInterfaceButton.fbx
Normal file
BIN
assets/videoInterfaceButton.fbx
Normal file
Binary file not shown.
248
assets/videoSyncInterface.html
Normal file
248
assets/videoSyncInterface.html
Normal file
@ -0,0 +1,248 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Video Sync Interface</title>
|
||||
<style>
|
||||
.slidecontainer {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.slider {
|
||||
-webkit-appearance: none;
|
||||
width: 100%;
|
||||
height: 15px;
|
||||
border-radius: 5px;
|
||||
background: #d3d3d3;
|
||||
outline: none;
|
||||
opacity: 0.7;
|
||||
-webkit-transition: .2s;
|
||||
transition: opacity .2s;
|
||||
}
|
||||
|
||||
.slider:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.slider::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
border-radius: 50%;
|
||||
background: #1f1f1f;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.slider::-moz-range-thumb {
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
border-radius: 50%;
|
||||
background: #4245f8;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
input[type=text],
|
||||
|
||||
select {
|
||||
width: 450px;
|
||||
padding: 12px 20px;
|
||||
margin: 8px 0;
|
||||
display: inline-block;
|
||||
border: 1px solid #dddddd;
|
||||
border-radius: 4px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.myButton {
|
||||
box-shadow: inset 0px 1px 0px 0px #ffffff;
|
||||
background: linear-gradient(to bottom, #ededed 5%, #dfdfdf 100%);
|
||||
background-color: #ededed;
|
||||
border-radius: 6px;
|
||||
border: 1px solid #dcdcdc;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
color: #777777;
|
||||
font-family: Arial;
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
padding: 6px 24px;
|
||||
text-decoration: none;
|
||||
text-shadow: 0px 1px 0px #ffffff;
|
||||
}
|
||||
|
||||
.myButton:hover {
|
||||
background: linear-gradient(to bottom, #dfdfdf 5%, #ededed 100%);
|
||||
background-color: #dfdfdf;
|
||||
}
|
||||
|
||||
.myButton:active {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
|
||||
.myButtonActivated {
|
||||
box-shadow: inset 0px 1px 0px 0px #ffffff;
|
||||
background: linear-gradient(to bottom, #666666 5%, #4e4e4e 100%);
|
||||
background-color: #ededed;
|
||||
border-radius: 6px;
|
||||
border: 1px solid #dcdcdc;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
color: #e2e2e2;
|
||||
font-family: Arial;
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
padding: 6px 24px;
|
||||
text-decoration: none;
|
||||
text-shadow: 0px 1px 0px #ffffff;
|
||||
}
|
||||
|
||||
.myButtonActivated:hover {
|
||||
background: linear-gradient(to bottom, #8b8b8b 5%, #2e2e2e 100%);
|
||||
background-color: #dfdfdf;
|
||||
}
|
||||
|
||||
.myButtonActivated:active {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body onload="RequestVideoLengthAndTimeStamp()">
|
||||
<h2>Enter new video URL</h2>
|
||||
<input type="text" id="videoURL" onfocus="this.value=''" placeholder="Enter video URL here"><br><br>
|
||||
<button class="myButton" onclick="newVideoURL()">Play video</button><br><br>
|
||||
<div class="slidecontainer">
|
||||
<h2>Video slider</h2>
|
||||
<input type="range" min="0" max="2" value="1" step="0.01" class="slider" id="videoRange">
|
||||
</div>
|
||||
<h2 id="checkMark"></h2>
|
||||
<p id="description"></p>
|
||||
</body>
|
||||
<script>
|
||||
var timeoutIs = false;
|
||||
var slider = document.getElementById("videoRange");
|
||||
var myTimeStamp = Date.now();
|
||||
var videoLength = 2;
|
||||
var myButtonActivated = 0;
|
||||
var descriptionIsLoopingStartAtBeginning = "While this is chosen after the video has ended when a new person joins. The video will start at the beginning.";
|
||||
var descriptionLoop = "While this is chosen the Video will continue to loop in the background whether somebody is watching it or not. When somebody knew joins. The video will begin playing at its current time. Whether anybody is watching it or not.";
|
||||
slider.oninput = function () {
|
||||
if (!timeoutIs) {
|
||||
setTimeout(() => {
|
||||
timeoutIs = false;
|
||||
var readyEvent = {
|
||||
"action": "play",
|
||||
"timeStamp": parseInt(this.value)
|
||||
};
|
||||
EventBridge.emitWebEvent(JSON.stringify(readyEvent));
|
||||
}, 1000);
|
||||
timeoutIs = true;
|
||||
}
|
||||
}
|
||||
function newVideoURL() {
|
||||
videoURL = document.getElementById("videoURL").value;
|
||||
var readyEvent = {
|
||||
"action": "nowVideoFromTablet",
|
||||
"timeStamp": 0,
|
||||
"videoUrl": videoURL,
|
||||
"myTimeStamp": myTimeStamp
|
||||
};
|
||||
EventBridge.emitWebEvent(JSON.stringify(readyEvent));
|
||||
document.getElementById("checkMark").innerHTML = "";
|
||||
}
|
||||
|
||||
function RequestVideoLengthAndTimeStamp() {
|
||||
var readyEvent = {
|
||||
"action": "RequestVideoLengthAndTimeStamp",
|
||||
"myTimeStamp": myTimeStamp
|
||||
};
|
||||
EventBridge.emitWebEvent(JSON.stringify(readyEvent));
|
||||
}
|
||||
|
||||
function loopVideoFunction() {
|
||||
if (myButtonActivated == 0) {
|
||||
var readyEvent = {
|
||||
"action": "loop",
|
||||
"videoLength": videoLength,
|
||||
"myTimeStamp": myTimeStamp
|
||||
};
|
||||
EventBridge.emitWebEvent(JSON.stringify(readyEvent));
|
||||
document.getElementById("loopVideoButton").innerHTML = "Loop Video Start At Beginning";
|
||||
document.getElementById("checkMark").innerHTML = "<h3><span>✓</span> Loop</h3>";
|
||||
document.getElementById("description").innerHTML = "<h3>" + descriptionLoop + "</h3>";
|
||||
myButtonActivated = 1;
|
||||
} else if (myButtonActivated == 1) {
|
||||
var readyEvent = {
|
||||
"action": "loopVideoStartAtBeginning",
|
||||
"videoLength": videoLength,
|
||||
"myTimeStamp": myTimeStamp
|
||||
};
|
||||
EventBridge.emitWebEvent(JSON.stringify(readyEvent));
|
||||
document.getElementById("loopVideoButton").innerHTML = "Stop Looping Video";
|
||||
document.getElementById("checkMark").innerHTML = "<h3><span>✓</span> Loop Video Start At Beginning</h3>";
|
||||
document.getElementById("description").innerHTML = "<h3>" + descriptionIsLoopingStartAtBeginning + "</h3>";
|
||||
myButtonActivated = 2;
|
||||
} else if (myButtonActivated == 2) {
|
||||
var readyEvent = {
|
||||
"action": "stopLoop",
|
||||
"myTimeStamp": myTimeStamp
|
||||
};
|
||||
EventBridge.emitWebEvent(JSON.stringify(readyEvent));
|
||||
document.getElementById("loopVideoButton").innerHTML = "Loop Video";
|
||||
document.getElementById("checkMark").innerHTML = "";
|
||||
document.getElementById("description").innerHTML = "";
|
||||
myButtonActivated = 0;
|
||||
}
|
||||
}
|
||||
|
||||
EventBridge.scriptEventReceived.connect(function (message) {
|
||||
var messageData = JSON.parse(message);
|
||||
if (messageData.action == "RequestVideoLengthAndTimeStampResponse") {
|
||||
if (messageData.myTimeStamp == myTimeStamp) {
|
||||
document.getElementById("videoRange").max = messageData.length;
|
||||
document.getElementById("videoRange").value = messageData.timeStamp;
|
||||
videoLength = messageData.length;
|
||||
}
|
||||
} else if (messageData.action == "requestVideoPlayingStatusServerReply") {
|
||||
if (messageData.isLooping && !messageData.isLoopingStartAtBeginning) {
|
||||
document.getElementById("loopVideoButton").innerHTML = "Loop Video Start At Beginning";
|
||||
document.getElementById("checkMark").innerHTML = "<h3><span>✓</span> Loop</h3>";
|
||||
document.getElementById("description").innerHTML = "<h3>" + descriptionLoop + "</h3>";
|
||||
document.getElementById("videoURL").value = messageData.videoUrl;
|
||||
myButtonActivated = 1;
|
||||
} else if (!messageData.isLooping && messageData.isLoopingStartAtBeginning) {
|
||||
document.getElementById("loopVideoButton").innerHTML = "Stop Looping Video";
|
||||
document.getElementById("checkMark").innerHTML = "<h3><span>✓</span> Loop Video Start At Beginning</h3>";
|
||||
document.getElementById("description").innerHTML = "<h3>" + descriptionIsLoopingStartAtBeginning + "</h3>";
|
||||
document.getElementById("videoURL").value = messageData.videoUrl;
|
||||
myButtonActivated = 2;
|
||||
} else if (!messageData.isLooping && !messageData.isLoopingStartAtBeginning) {
|
||||
document.getElementById("loopVideoButton").innerHTML = "Loop Video";
|
||||
document.getElementById("checkMark").innerHTML = "";
|
||||
document.getElementById("description").innerHTML = "";
|
||||
document.getElementById("videoURL").value = messageData.videoUrl;
|
||||
myButtonActivated = 0;
|
||||
}
|
||||
} else if (messageData.action == "loop" && messageData.myTimeStamp != myTimeStamp) {
|
||||
document.getElementById("loopVideoButton").innerHTML = "Loop Video Start At Beginning";
|
||||
document.getElementById("checkMark").innerHTML = "<h3><span>✓</span> Loop</h3>";
|
||||
document.getElementById("description").innerHTML = "<h3>" + descriptionLoop + "</h3>";
|
||||
myButtonActivated = 1;
|
||||
} else if (messageData.action == "loopVideoStartAtBeginning" && messageData.myTimeStamp != myTimeStamp) {
|
||||
document.getElementById("loopVideoButton").innerHTML = "Stop Looping Video";
|
||||
document.getElementById("checkMark").innerHTML = "<h3><span>✓</span> Loop Video Start At Beginning</h3>";
|
||||
document.getElementById("description").innerHTML = "<h3>" + descriptionIsLoopingStartAtBeginning + "</h3>";
|
||||
myButtonActivated = 2;
|
||||
} else if (messageData.action == "stopLoop" && messageData.myTimeStamp != myTimeStamp) {
|
||||
document.getElementById("loopVideoButton").innerHTML = "Loop Video";
|
||||
document.getElementById("checkMark").innerHTML = "";
|
||||
document.getElementById("description").innerHTML = "";
|
||||
myButtonActivated = 0;
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
</html>
|
BIN
assets/volumeButtonMinus.fbx
Normal file
BIN
assets/volumeButtonMinus.fbx
Normal file
Binary file not shown.
BIN
assets/volumeButtonPlus.fbx
Normal file
BIN
assets/volumeButtonPlus.fbx
Normal file
Binary file not shown.
73
assets/volumeSlider.html
Normal file
73
assets/volumeSlider.html
Normal file
@ -0,0 +1,73 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Video Sync Interface</title>
|
||||
<style>
|
||||
|
||||
body {
|
||||
background-color: #333333;
|
||||
}
|
||||
|
||||
.slider {
|
||||
-webkit-appearance: none;
|
||||
width: 100%;
|
||||
height: 15px;
|
||||
border-radius: 5px;
|
||||
background: #a7a7a7;
|
||||
outline: none;
|
||||
opacity: 0.7;
|
||||
-webkit-transition: .2s;
|
||||
transition: opacity .2s;
|
||||
}
|
||||
|
||||
.slider:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.slider::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
border-radius: 50%;
|
||||
background: #f5f5f5;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="slidecontainer">
|
||||
<h1 style="color:#f5f5f5;">Volume</h1>
|
||||
<input type="range" min="0" max="1" value="1" step="0.01" class="slider" id="volumeSlider">
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
var slider = document.getElementById("volumeSlider");
|
||||
var myTimeStamp = Date.now();
|
||||
var timeoutIs = false;
|
||||
slider.oninput = function () {
|
||||
if (!timeoutIs) {
|
||||
setTimeout(() => {
|
||||
timeoutIs = false;
|
||||
var readyEvent = {
|
||||
action: "volumeSlider",
|
||||
volume: this.value
|
||||
};
|
||||
EventBridge.emitWebEvent(JSON.stringify(readyEvent));
|
||||
}, 300);
|
||||
timeoutIs = true;
|
||||
}
|
||||
}
|
||||
|
||||
EventBridge.scriptEventReceived.connect(function (message) {
|
||||
var messageData = JSON.parse(message);
|
||||
if (messageData.action == "volumeChanged") {
|
||||
document.getElementById("volumeSlider").value = parseFloat(messageData.volume);
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
</html>
|
BIN
assets/waitingOnVideo.png
Normal file
BIN
assets/waitingOnVideo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 84 KiB |
181
videoSync.html
Normal file
181
videoSync.html
Normal file
@ -0,0 +1,181 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Video Sync</title>
|
||||
<style>
|
||||
#video {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
#video-container-play-button {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-repeat: no-repeat;
|
||||
background-attachment: fixed;
|
||||
background-position: center center;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
background-image: url('assets/play_btn.png');
|
||||
}
|
||||
|
||||
*::-webkit-media-controls-panel {
|
||||
display: none !important;
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
div.volumeIs {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
}
|
||||
|
||||
strong {
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
display: inline-block;
|
||||
border-radius: 16px;
|
||||
padding: 0 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#333333">
|
||||
<div id="video-container" onclick="requestSync()">
|
||||
<video id="video" poster="assets/clickToWatch.png" controls autoplay>
|
||||
<source id="mp4_src" src=" " type="video/webm">
|
||||
</video>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var firstTime = true;
|
||||
var myTimeStamp = Date.now();
|
||||
var HasBeenClicked = false;
|
||||
var videoLoaded = false;
|
||||
|
||||
function requestSync() {
|
||||
if (firstTime) {
|
||||
HasBeenClicked = true;
|
||||
var readyEvent = {
|
||||
action: 'requestSync',
|
||||
myTimeStamp: myTimeStamp
|
||||
};
|
||||
EventBridge.emitWebEvent(JSON.stringify(readyEvent));
|
||||
}
|
||||
}
|
||||
EventBridge.scriptEventReceived.connect(function (message) {
|
||||
var messageData = JSON.parse(message);
|
||||
if (messageData.action == 'play' && !firstTime) {
|
||||
document.getElementById('video').play();
|
||||
document.getElementById('video').currentTime = messageData.timeStamp;
|
||||
} else if (messageData.action == 'pause' && !firstTime) {
|
||||
document.getElementById('video').pause();
|
||||
} else if (messageData.action == 'now' && messageData.myTimeStamp != myTimeStamp) {
|
||||
if (!firstTime || HasBeenClicked) {
|
||||
document.getElementById('video').src = messageData.videoUrl;
|
||||
firstTime = false;
|
||||
}
|
||||
} else if (messageData.action == 'sync' && messageData.myTimeStamp == myTimeStamp) {
|
||||
if (firstTime) {
|
||||
document.getElementById('video').src = messageData.videoUrl;
|
||||
document.getElementById('video').currentTime = messageData.timeStamp;
|
||||
firstTime = false;
|
||||
if (!messageData.videoPlaying) {
|
||||
var vid = document.getElementById("video");
|
||||
vid.onloadeddata = function () {
|
||||
document.getElementById('video').pause();
|
||||
};
|
||||
}
|
||||
}
|
||||
} else if (messageData.action == 'ping' && !firstTime) {
|
||||
var video = document.getElementById('video');
|
||||
var myVideoCurrentTimeStamp = video.currentTime;
|
||||
var ping = messageData.timeStamp;
|
||||
if (ping + 2 > myVideoCurrentTimeStamp && ping - 2 < myVideoCurrentTimeStamp) {
|
||||
} else {
|
||||
document.getElementById('video').currentTime = messageData.timeStamp;
|
||||
}
|
||||
} else if (messageData.action == "nowVideoFromTablet") {
|
||||
videoLoaded = false;
|
||||
document.getElementById('video').src = messageData.videoUrl;
|
||||
firstTime = false;
|
||||
var v = document.getElementById('video');
|
||||
v.onloadeddata = function () {
|
||||
videoLoaded = true;
|
||||
};
|
||||
var videoLoadedSendMessageInterval = setInterval(() => {
|
||||
if (videoLoaded) {
|
||||
var v = document.getElementById('video');
|
||||
var readyEvent = {
|
||||
action: "now",
|
||||
videoUrl: messageData.videoUrl,
|
||||
length: v.duration,
|
||||
timeStamp: v.currentTime,
|
||||
myTimeStamp: myTimeStamp
|
||||
};
|
||||
EventBridge.emitWebEvent(JSON.stringify(readyEvent));
|
||||
clearInterval(videoLoadedSendMessageInterval);
|
||||
videoLoaded = false;
|
||||
}
|
||||
}, 100);
|
||||
} else if (messageData.action == "buttonAction") {
|
||||
if (messageData.buttonAction == "leave") {
|
||||
document.getElementById('video').src = "http://";
|
||||
firstTime = true;
|
||||
HasBeenClicked = false;
|
||||
} else if (messageData.buttonAction == "volumeButtonMinus") {
|
||||
var video = document.getElementById('video');
|
||||
var volume = video.volume;
|
||||
var chosenVolume;
|
||||
if (volume - 0.1 < 0.1) {
|
||||
chosenVolume = 0;
|
||||
} else {
|
||||
chosenVolume = volume - 0.1;
|
||||
}
|
||||
video.volume = chosenVolume.toFixed(1);
|
||||
} else if (messageData.buttonAction == "volumeButtonPlus") {
|
||||
var video = document.getElementById('video');
|
||||
var volume = video.volume;
|
||||
var chosenVolume;
|
||||
if (video.volume.toFixed(1) == 1) {
|
||||
chosenVolume = 1;
|
||||
} else {
|
||||
chosenVolume = volume + 0.1;
|
||||
}
|
||||
video.volume = chosenVolume.toFixed(1);
|
||||
} else if (messageData.buttonAction == "pause" && !firstTime) {
|
||||
sendButtonAction(messageData.buttonAction);
|
||||
} else if (messageData.buttonAction == "play" && !firstTime) {
|
||||
sendButtonAction(messageData.buttonAction);
|
||||
}
|
||||
} else if (messageData.action == "RequestVideoLengthAndTimeStamp") {
|
||||
var v = document.getElementById('video');
|
||||
var readyEvent = {
|
||||
action: "RequestVideoLengthAndTimeStampResponse",
|
||||
length: v.duration,
|
||||
timeStamp: v.currentTime,
|
||||
myTimeStamp: messageData.myTimeStamp
|
||||
};
|
||||
EventBridge.emitWebEvent(JSON.stringify(readyEvent));
|
||||
} else if (messageData.action == "volumeSlider") {
|
||||
video = document.getElementById('video');
|
||||
video.volume = parseFloat(messageData.volume);
|
||||
}
|
||||
});
|
||||
|
||||
function sendButtonAction(buttonAction) {
|
||||
var readyEvent = {
|
||||
"action": buttonAction,
|
||||
"timeStamp": document.getElementById('video').currentTime,
|
||||
"nowVideo": "false"
|
||||
};
|
||||
EventBridge.emitWebEvent(JSON.stringify(readyEvent));
|
||||
}
|
||||
|
||||
vid = document.getElementById('myVideo');
|
||||
vid.currentTime = 5;
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
343
videoSync.js
Normal file
343
videoSync.js
Normal file
@ -0,0 +1,343 @@
|
||||
(function () {
|
||||
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||
var videoSyncInterface = Script.resolvePath("assets/videoSyncInterface.html");
|
||||
var videoSyncServerScriptUrl = Script.resolvePath("videoSyncServerScript.js");
|
||||
var volumeSliderSourceUrl = Script.resolvePath("assets/volumeSlider.html");
|
||||
var uuid;
|
||||
var script = this;
|
||||
var entity;
|
||||
var _entityID;
|
||||
var sourceUrl = Script.resolvePath("videoSync.html" + "?" + Date.now());
|
||||
var leaveButtonFbxUrl = Script.resolvePath("assets/leave.fbx");
|
||||
var playButtonFbxUrl = Script.resolvePath("assets/playButton.fbx");
|
||||
var pauseButtonURL = Script.resolvePath("assets/pauseButton.fbx");
|
||||
var volumeButtonPlusUrl = Script.resolvePath("assets/volumeButtonPlus.fbx");
|
||||
var videoInterfaceButton = Script.resolvePath("assets/videoInterfaceButton.fbx");
|
||||
var volumeButtonPlus;
|
||||
var volumeButtonMinus;
|
||||
var playButtonUuid;
|
||||
var pauseButtonUuid;
|
||||
var leaveButtonUuid;
|
||||
var videoInterfaceButtonUuid;
|
||||
var volumeSliderUuid;
|
||||
var buttonsAreActive = false;
|
||||
var hasInteractedWithWebPage = false;
|
||||
var webPanelTimeStamp;
|
||||
var interfaceButtonActive = false;
|
||||
|
||||
function openVideoInter() {
|
||||
if (buttonsAreActive || interfaceButtonActive) {
|
||||
tablet.gotoWebScreen(videoSyncInterface);
|
||||
}
|
||||
};
|
||||
|
||||
tablet.webEventReceived.connect(onTabletWebEvent);
|
||||
|
||||
function onTabletWebEvent(event) {
|
||||
var webEventData = JSON.parse(event);
|
||||
console.log(JSON.stringify(webEventData));
|
||||
if (webEventData.action == "nowVideoFromTablet") {
|
||||
sendMessage(event);
|
||||
} else if (webEventData.action == "RequestVideoLengthAndTimeStamp") {
|
||||
sendMessage(event);
|
||||
} else if (webEventData.action == "play") {
|
||||
Messages.sendMessage("videoPlayOnEntity", event);
|
||||
}
|
||||
}
|
||||
|
||||
script.preload = function (entityID) {
|
||||
entity = Entities.getEntityProperties(entityID, ["position", "dimensions", "rotation", "serverScripts"]);
|
||||
Entities.editEntity(entityID, {
|
||||
sourceUrl: sourceUrl,
|
||||
dpi: 8,
|
||||
maxFPS: 60,
|
||||
grab: {
|
||||
"grabbable": false,
|
||||
},
|
||||
});
|
||||
if (entity.serverScripts == "") {
|
||||
Entities.editEntity(entityID, {
|
||||
serverScripts: videoSyncServerScriptUrl
|
||||
});
|
||||
}
|
||||
_entityID = entityID;
|
||||
Entities.webEventReceived.connect(onWebEvent);
|
||||
addButtons();
|
||||
}
|
||||
|
||||
function onWebEvent(uuid, event) {
|
||||
if (uuid == _entityID || volumeSliderUuid == uuid) {
|
||||
var messageData = JSON.parse(event);
|
||||
console.log("Web Event " + JSON.stringify(messageData));
|
||||
if (messageData.action == "requestSync") {
|
||||
webPanelTimeStamp = messageData.myTimeStamp;
|
||||
} else if (messageData.action == "RequestVideoLengthAndTimeStampResponse") {
|
||||
tablet.emitScriptEvent(event);
|
||||
return;
|
||||
} else if (messageData.action == "volumeSlider") {
|
||||
sendMessage(event);
|
||||
return;
|
||||
}
|
||||
Messages.sendMessage("videoPlayOnEntity", event);
|
||||
}
|
||||
}
|
||||
|
||||
function onMessageReceived(channel, message, sender, localOnly) {
|
||||
if (channel != "videoPlayOnEntity") {
|
||||
return;
|
||||
}
|
||||
var messageData = JSON.parse(message);
|
||||
console.log("Message Received " + JSON.stringify(messageData));
|
||||
if (messageData.action == "sync" && webPanelTimeStamp == messageData.myTimeStamp) {
|
||||
if (messageData.videoUrl != "") {
|
||||
buttonsAreActive = true;
|
||||
hideAndRevealButtons(buttonsAreActive);
|
||||
} else if (messageData.videoUrl == "") {
|
||||
hasInteractedWithWebPage = true;
|
||||
interfaceButtonActive = true;
|
||||
addInterfaceButton();
|
||||
}
|
||||
} else if (messageData.action == "now" && hasInteractedWithWebPage) {
|
||||
buttonsAreActive = true;
|
||||
hideAndRevealButtons(buttonsAreActive);
|
||||
}
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
function sendMessage(message) {
|
||||
Entities.emitScriptEvent(_entityID, message);
|
||||
}
|
||||
|
||||
function addButtons() {
|
||||
leaveButtonUuid = Entities.addEntity({
|
||||
type: "Model",
|
||||
modelURL: leaveButtonFbxUrl,
|
||||
parentID: _entityID,
|
||||
triggerable: true,
|
||||
position: Vec3.sum(entity.position, Vec3.multiplyQbyV(entity.rotation, { x: entity.dimensions.x / 2 - entity.dimensions.x - -0.2, y: entity.dimensions.y / 2 - entity.dimensions.y - 0.2, z: 0 })),
|
||||
dimensions: {
|
||||
"x": 0.22840283811092377,
|
||||
"y": 0.22654350101947784,
|
||||
"z": 0.019338179379701614
|
||||
},
|
||||
grab: {
|
||||
"grabbable": false,
|
||||
},
|
||||
visible: false
|
||||
}, "local");
|
||||
Script.addEventHandler(leaveButtonUuid, "mousePressOnEntity", evaluateWhichButtonPressed);
|
||||
|
||||
pauseButtonUuid = Entities.addEntity({
|
||||
type: "Model",
|
||||
modelURL: pauseButtonURL,
|
||||
parentID: _entityID,
|
||||
triggerable: true,
|
||||
position: Vec3.sum(entity.position, Vec3.multiplyQbyV(entity.rotation, { x: entity.dimensions.x / 2 - entity.dimensions.x - -0.8, y: entity.dimensions.y / 2 - entity.dimensions.y - 0.2, z: 0 })),
|
||||
dimensions: {
|
||||
"x": 0.22840283811092377,
|
||||
"y": 0.22654350101947784,
|
||||
"z": 0.019338179379701614
|
||||
},
|
||||
grab: {
|
||||
"grabbable": false,
|
||||
},
|
||||
visible: false
|
||||
}, "local");
|
||||
Script.addEventHandler(pauseButtonUuid, "mousePressOnEntity", evaluateWhichButtonPressed);
|
||||
|
||||
playButtonUuid = Entities.addEntity({
|
||||
type: "Model",
|
||||
modelURL: playButtonFbxUrl,
|
||||
parentID: _entityID,
|
||||
triggerable: true,
|
||||
position: Vec3.sum(entity.position, Vec3.multiplyQbyV(entity.rotation, { x: entity.dimensions.x / 2 - entity.dimensions.x - -0.5, y: entity.dimensions.y / 2 - entity.dimensions.y - 0.2, z: 0 })),
|
||||
dimensions: {
|
||||
"x": 0.22840283811092377,
|
||||
"y": 0.22654350101947784,
|
||||
"z": 0.019338179379701614
|
||||
},
|
||||
grab: {
|
||||
"grabbable": false,
|
||||
},
|
||||
visible: false
|
||||
}, "local");
|
||||
Script.addEventHandler(playButtonUuid, "mousePressOnEntity", evaluateWhichButtonPressed);
|
||||
|
||||
volumeButtonMinus = Entities.addEntity({
|
||||
type: "Model",
|
||||
modelURL: leaveButtonFbxUrl,
|
||||
parentID: _entityID,
|
||||
triggerable: true,
|
||||
position: Vec3.sum(entity.position, Vec3.multiplyQbyV(entity.rotation, { x: entity.dimensions.x / 2 - 0.2, y: entity.dimensions.y / 2 - entity.dimensions.y - 0.2, z: 0 })),
|
||||
dimensions: {
|
||||
"x": 0.2284,
|
||||
"y": 0.0779,
|
||||
"z": 0.0193
|
||||
},
|
||||
grab: {
|
||||
"grabbable": false,
|
||||
},
|
||||
}, "local");
|
||||
Script.addEventHandler(volumeButtonMinus, "mousePressOnEntity", evaluateWhichButtonPressed);
|
||||
|
||||
volumeButtonPlus = Entities.addEntity({
|
||||
type: "Model",
|
||||
modelURL: volumeButtonPlusUrl,
|
||||
parentID: _entityID,
|
||||
triggerable: true,
|
||||
position: Vec3.sum(entity.position, Vec3.multiplyQbyV(entity.rotation, { x: entity.dimensions.x / 2 - 0.5, y: entity.dimensions.y / 2 - entity.dimensions.y - 0.2, z: 0 })),
|
||||
dimensions: {
|
||||
"x": 0.22840283811092377,
|
||||
"y": 0.22654350101947784,
|
||||
"z": 0.019338179379701614
|
||||
},
|
||||
grab: {
|
||||
"grabbable": false,
|
||||
},
|
||||
}, "local");
|
||||
Script.addEventHandler(volumeButtonPlus, "mousePressOnEntity", evaluateWhichButtonPressed);
|
||||
|
||||
videoInterfaceButtonUuid = Entities.addEntity({
|
||||
type: "Model",
|
||||
modelURL: videoInterfaceButton,
|
||||
parentID: _entityID,
|
||||
triggerable: true,
|
||||
position: Vec3.sum(entity.position, Vec3.multiplyQbyV(entity.rotation, { x: entity.dimensions.x / 2 - entity.dimensions.x + 0.5, y: entity.dimensions.y / 2 + 0.4, z: 0 })),
|
||||
grab: {
|
||||
"grabbable": false,
|
||||
},
|
||||
visible: false
|
||||
}, "local");
|
||||
Script.addEventHandler(videoInterfaceButtonUuid, "mousePressOnEntity", evaluateWhichButtonPressed);
|
||||
|
||||
volumeSliderUuid = Entities.addEntity({
|
||||
type: "Web",
|
||||
dpi: 8,
|
||||
sourceUrl: volumeSliderSourceUrl,
|
||||
parentID: uuid,
|
||||
//visible: false,
|
||||
dimensions: {
|
||||
"x": 1.3687,
|
||||
"y": 0.3429,
|
||||
"z": 0.0010
|
||||
},
|
||||
registrationPoint: {
|
||||
"x": 0.5,
|
||||
"y": 0.5,
|
||||
"z": 0
|
||||
},
|
||||
position: Vec3.sum(entity.position, Vec3.multiplyQbyV(entity.rotation, { x: entity.dimensions.x / 2 - 1.4, y: entity.dimensions.y / 2 - entity.dimensions.y - 0.2, z: 0 })),
|
||||
rotation: entity.rotation
|
||||
}, "local");
|
||||
}
|
||||
|
||||
function evaluateWhichButtonPressed(mousePressEntityID, event) {
|
||||
switch (mousePressEntityID) {
|
||||
case pauseButtonUuid:
|
||||
console.log("PauseButtonUuid Yes");
|
||||
actOnButtonPressed("pause");
|
||||
break;
|
||||
case leaveButtonUuid:
|
||||
console.log("LeaveButtonUuid Yes");
|
||||
actOnButtonPressed("leave");
|
||||
buttonsAreActive = false;
|
||||
interfaceButtonActive = false;
|
||||
hideAndRevealButtons(buttonsAreActive);
|
||||
break;
|
||||
case playButtonUuid:
|
||||
console.log("playButtonUuid Yes");
|
||||
actOnButtonPressed("play");
|
||||
break;
|
||||
case volumeButtonMinus:
|
||||
console.log("volumeButtonMinus Yes");
|
||||
actOnButtonPressed("volumeButtonMinus");
|
||||
break;
|
||||
case volumeButtonPlus:
|
||||
console.log("volumeButtonPlus Yes");
|
||||
actOnButtonPressed("volumeButtonPlus");
|
||||
break;
|
||||
case videoInterfaceButtonUuid:
|
||||
console.log("videoInterfaceButton Yes");
|
||||
openVideoInter();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function addInterfaceButton() {
|
||||
Entities.editEntity(videoInterfaceButtonUuid, {
|
||||
visible: true,
|
||||
position: Vec3.sum(entity.position, Vec3.multiplyQbyV(entity.rotation, { x: entity.dimensions.x / 2 - entity.dimensions.x + 0.5, y: entity.dimensions.y / 2 + 0.4, z: 0 }))
|
||||
});
|
||||
}
|
||||
|
||||
function hideAndRevealButtons(hideOrReveal) {
|
||||
entity = Entities.getEntityProperties(_entityID, ["position", "dimensions", "rotation"]);
|
||||
Entities.editEntity(leaveButtonUuid, {
|
||||
visible: hideOrReveal,
|
||||
position: Vec3.sum(entity.position, Vec3.multiplyQbyV(entity.rotation, { x: entity.dimensions.x / 2 - entity.dimensions.x - -0.2, y: entity.dimensions.y / 2 - entity.dimensions.y - 0.2, z: 0 }))
|
||||
});
|
||||
|
||||
Entities.editEntity(pauseButtonUuid, {
|
||||
visible: hideOrReveal,
|
||||
position: Vec3.sum(entity.position, Vec3.multiplyQbyV(entity.rotation, { x: entity.dimensions.x / 2 - entity.dimensions.x - -0.8, y: entity.dimensions.y / 2 - entity.dimensions.y - 0.2, z: 0 }))
|
||||
});
|
||||
|
||||
Entities.editEntity(playButtonUuid, {
|
||||
visible: hideOrReveal,
|
||||
position: Vec3.sum(entity.position, Vec3.multiplyQbyV(entity.rotation, { x: entity.dimensions.x / 2 - entity.dimensions.x - -0.5, y: entity.dimensions.y / 2 - entity.dimensions.y - 0.2, z: 0 }))
|
||||
});
|
||||
|
||||
Entities.editEntity(volumeButtonMinus, {
|
||||
position: Vec3.sum(entity.position, Vec3.multiplyQbyV(entity.rotation, { x: entity.dimensions.x / 2 - 0.2, y: entity.dimensions.y / 2 - entity.dimensions.y - 0.2, z: 0 }))
|
||||
});
|
||||
|
||||
Entities.editEntity(volumeButtonPlus, {
|
||||
position: Vec3.sum(entity.position, Vec3.multiplyQbyV(entity.rotation, { x: entity.dimensions.x / 2 - 0.5, y: entity.dimensions.y / 2 - entity.dimensions.y - 0.2, z: 0 }))
|
||||
});
|
||||
|
||||
Entities.editEntity(videoInterfaceButtonUuid, {
|
||||
visible: hideOrReveal,
|
||||
position: Vec3.sum(entity.position, Vec3.multiplyQbyV(entity.rotation, { x: entity.dimensions.x / 2 - entity.dimensions.x + 0.5, y: entity.dimensions.y / 2 + 0.4, z: 0 }))
|
||||
});
|
||||
|
||||
Entities.editEntity(volumeSliderUuid, {
|
||||
position: Vec3.sum(entity.position, Vec3.multiplyQbyV(entity.rotation, { x: entity.dimensions.x / 2 - 1.4, y: entity.dimensions.y / 2 - entity.dimensions.y - 0.2, z: 0 })),
|
||||
rotation: entity.rotation
|
||||
});
|
||||
}
|
||||
|
||||
function actOnButtonPressed(buttonAction) {
|
||||
var readyEvent = {
|
||||
"action": "buttonAction",
|
||||
"buttonAction": buttonAction
|
||||
};
|
||||
sendMessage(JSON.stringify(readyEvent));
|
||||
}
|
||||
|
||||
function removeButtons() {
|
||||
Entities.deleteEntity(leaveButtonUuid);
|
||||
Entities.deleteEntity(pauseButtonUuid);
|
||||
Entities.deleteEntity(playButtonUuid);
|
||||
Entities.deleteEntity(volumeButtonMinus);
|
||||
Entities.deleteEntity(volumeButtonPlus);
|
||||
Entities.deleteEntity(videoInterfaceButtonUuid);
|
||||
Entities.deleteEntity(volumeSliderUuid);
|
||||
Script.removeEventHandler(videoInterfaceButtonUuid, "mousePressOnEntity", evaluateWhichButtonPressed);
|
||||
Script.removeEventHandler(volumeButtonPlus, "mousePressOnEntity", evaluateWhichButtonPressed);
|
||||
Script.removeEventHandler(volumeButtonMinus, "mousePressOnEntity", evaluateWhichButtonPressed);
|
||||
Script.removeEventHandler(leaveButtonUuid, "mousePressOnEntity", evaluateWhichButtonPressed);
|
||||
Script.removeEventHandler(pauseButtonUuid, "mousePressOnEntity", evaluateWhichButtonPressed);
|
||||
Script.removeEventHandler(playButtonUuid, "mousePressOnEntity", evaluateWhichButtonPressed);
|
||||
}
|
||||
|
||||
Messages.subscribe("videoPlayOnEntity");
|
||||
Messages.messageReceived.connect(onMessageReceived);
|
||||
script.unload = function (entityID) {
|
||||
Messages.unsubscribe("videoPlayOnEntity");
|
||||
Entities.deleteEntity(uuid);
|
||||
Messages.messageReceived.disconnect(onMessageReceived);
|
||||
Entities.webEventReceived.disconnect(onWebEvent);
|
||||
tablet.webEventReceived.disconnect(onTabletWebEvent);
|
||||
removeButtons();
|
||||
}
|
||||
});
|
84
videoSyncServerScript.js
Normal file
84
videoSyncServerScript.js
Normal file
@ -0,0 +1,84 @@
|
||||
(function () {
|
||||
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;
|
||||
|
||||
function onMessageReceived(channel, message, sender, localOnly) {
|
||||
if (channel != "videoPlayOnEntity") {
|
||||
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();
|
||||
} else if (messageData.action == "play") {
|
||||
timeStamp = messageData.timeStamp;
|
||||
if (intervalIsRunning) {
|
||||
Script.clearInterval(timeStampInterval);
|
||||
}
|
||||
intervalIsRunning = true;
|
||||
videoPlaying = true;
|
||||
ping();
|
||||
} else if (messageData.action == "pause") {
|
||||
Script.clearInterval(timeStampInterval);
|
||||
intervalIsRunning = false;
|
||||
} 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("videoPlayOnEntity", message);
|
||||
}, 600);
|
||||
}
|
||||
}
|
||||
|
||||
function ping() {
|
||||
timeStampInterval = Script.setInterval(function () {
|
||||
timeStamp = timeStamp + 1;
|
||||
pingTimer = pingTimer + 1;
|
||||
if (pingTimer == 60) {
|
||||
pingTimer = 0;
|
||||
messageData.timeStamp = timeStamp;
|
||||
messageData.action = "ping";
|
||||
var message = JSON.stringify(messageData);
|
||||
Messages.sendMessage("videoPlayOnEntity", message);
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
Messages.subscribe("videoPlayOnEntity");
|
||||
Messages.messageReceived.connect(onMessageReceived);
|
||||
|
||||
this.unload = function () {
|
||||
Messages.unsubscribe("videoPlayOnEntity");
|
||||
Messages.messageReceived.disconnect(onMessageReceived);
|
||||
if (intervalIsRunning) {
|
||||
Script.clearInterval(timeStampInterval);
|
||||
}
|
||||
}
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user