first commit
This commit is contained in:
166
public/client.html
Normal file
166
public/client.html
Normal file
@@ -0,0 +1,166 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Room ID Form</title>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css"
|
||||
integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#form-container {
|
||||
text-align: center;
|
||||
border: 1px solid #ccc;
|
||||
padding: 20px;
|
||||
border-radius: 5px;
|
||||
background-color: #f7f7f7;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="form-container">
|
||||
<form id="roomForm">
|
||||
<h2>Room ID Form</h2>
|
||||
<label for="roomId">Room ID:</label>
|
||||
<input type="text" id="roomId" required />
|
||||
<br /><br />
|
||||
<button type="submit" id="submitBtn">Submit</button>
|
||||
</form>
|
||||
<div id="mainPage" style="display: none">
|
||||
<div class="container text-center">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<img height="80" src="http://localhost:3000/img" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<video
|
||||
id="video_field"
|
||||
height="300"
|
||||
src="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
|
||||
controls
|
||||
></video>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h4>Host? <span id="host_field"></span></h4>
|
||||
<h4 id="room_field">Room ID:</h4>
|
||||
<h4 id="name_field">Your name:</h4>
|
||||
<h4>Other connected clients:</h4>
|
||||
<p id="clients_field"></p>
|
||||
</div>
|
||||
<div class="col-5">
|
||||
<p
|
||||
id="global_field"
|
||||
style="height: 200px; overflow-x: hidden; overflow-y: scroll"
|
||||
></p>
|
||||
<div style="display: flex; justify-content: center">
|
||||
<input
|
||||
style="width: 200px; margin-right: 10px"
|
||||
type="text"
|
||||
id="global_input"
|
||||
class="form-control"
|
||||
/>
|
||||
<button
|
||||
onclick="ClientInstance.sendGlobal()"
|
||||
class="btn btn-primary small-button"
|
||||
>
|
||||
Send Global
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<button
|
||||
onclick="ClientInstance.makeHost()"
|
||||
class="btn btn-primary small-button"
|
||||
>
|
||||
Make Host
|
||||
</button>
|
||||
<div
|
||||
style="display: flex; justify-content: center; padding: 10px"
|
||||
>
|
||||
<input
|
||||
placeholder="Change name:"
|
||||
style="width: 200px; margin-right: 10px"
|
||||
type="text"
|
||||
id="name_input"
|
||||
class="form-control"
|
||||
/>
|
||||
<button
|
||||
onclick="ClientInstance.changeName()"
|
||||
class="btn btn-primary small-button"
|
||||
>
|
||||
Change Name
|
||||
</button>
|
||||
</div>
|
||||
<div style="display: flex; justify-content: center">
|
||||
<input
|
||||
placeholder="Put link:"
|
||||
style="width: 200px; margin-right: 10px"
|
||||
type="text"
|
||||
id="link_input"
|
||||
class="form-control"
|
||||
/>
|
||||
<button
|
||||
style="margin-right: 10px"
|
||||
onclick="ClientInstance.setLink()"
|
||||
class="btn btn-primary small-button"
|
||||
>
|
||||
Set Link
|
||||
</button>
|
||||
<button
|
||||
onclick="ClientInstance.syncVideo()"
|
||||
class="btn btn-primary small-button"
|
||||
>
|
||||
Sync
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script
|
||||
src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.min.js"
|
||||
integrity="sha384-cuYeSxntonz0PPNlHhBs68uyIAVpIIOZZ5JqeqvYYIcEL727kskC66kF92t6Xl2V"
|
||||
crossorigin="anonymous"
|
||||
></script>
|
||||
<script
|
||||
src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"
|
||||
integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4"
|
||||
crossorigin="anonymous"
|
||||
></script>
|
||||
<script src="https://unpkg.com/axios@1.1.2/dist/axios.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/client.js"></script>
|
||||
<script>
|
||||
let ClientInstance;
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const roomForm = document.getElementById('roomForm');
|
||||
const mainPage = document.getElementById('mainPage');
|
||||
let hasSubmitted = false;
|
||||
roomForm.addEventListener('submit', function (event) {
|
||||
event.preventDefault();
|
||||
const ID = document.getElementById('roomId').value;
|
||||
mainPage.style.display = 'block';
|
||||
roomForm.style.display = 'none';
|
||||
hasSubmitted = true;
|
||||
ClientInstance = new Client(ID);
|
||||
ClientInstance.connect();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
200
public/client.js
Normal file
200
public/client.js
Normal file
@@ -0,0 +1,200 @@
|
||||
class Client {
|
||||
#ClientSocket;
|
||||
#ClientData;
|
||||
|
||||
constructor(room_id) {
|
||||
this.#ClientData = { name: 'Guest', id: 0, room: room_id };
|
||||
this.#ClientSocket = new WebSocket('ws://93.116.13.156:3000/ws');
|
||||
|
||||
this.host_field = document.getElementById('host_field');
|
||||
this.name_field = document.getElementById('name_field');
|
||||
this.clients_field = document.getElementById('clients_field');
|
||||
this.name_input = document.getElementById('name_input');
|
||||
this.global_field = document.getElementById('global_field');
|
||||
this.global_input = document.getElementById('global_input');
|
||||
this.room_field = document.getElementById('room_field');
|
||||
this.room_field.textContent += room_id;
|
||||
this.video_field = document.getElementById('video_field');
|
||||
this.link_input = document.getElementById('link_input');
|
||||
}
|
||||
|
||||
connect() {
|
||||
let isManuallySeeked = true;
|
||||
let isManuallyPlayed = true;
|
||||
let isManuallyPaused = true;
|
||||
|
||||
this.video_field.addEventListener('play', () => {
|
||||
if (isManuallyPlayed) {
|
||||
const js = {
|
||||
command: 'play',
|
||||
room_id: this.#ClientData.room,
|
||||
};
|
||||
this.sendCommand(js);
|
||||
} else isManuallyPlayed = true;
|
||||
});
|
||||
|
||||
video_field.addEventListener('pause', () => {
|
||||
if (isManuallyPaused) {
|
||||
const js = {
|
||||
command: 'pause',
|
||||
room_id: this.#ClientData.room,
|
||||
};
|
||||
this.sendCommand(js);
|
||||
} else isManuallyPaused = true;
|
||||
});
|
||||
|
||||
video_field.addEventListener('seeked', () => {
|
||||
if (isManuallySeeked) this.syncForVid();
|
||||
else isManuallySeeked = true;
|
||||
});
|
||||
|
||||
this.#ClientSocket.addEventListener('open', () => {
|
||||
console.log('Connected');
|
||||
});
|
||||
|
||||
this.#ClientSocket.addEventListener('message', (event) => {
|
||||
try {
|
||||
const msg = JSON.parse(event.data);
|
||||
|
||||
if (msg.command == 'set_id') {
|
||||
this.#ClientData.id = msg.id;
|
||||
this.refreshData();
|
||||
const json = {
|
||||
command: 'set_room',
|
||||
room_id: this.#ClientData.room,
|
||||
id: this.#ClientData.id,
|
||||
};
|
||||
this.sendCommand(json);
|
||||
}
|
||||
|
||||
if (msg.command == 'set_link') {
|
||||
this.video_field.src = msg.link;
|
||||
this.video_field.play();
|
||||
}
|
||||
|
||||
if (msg.command == 'sync') {
|
||||
this.isManuallySeeked = false;
|
||||
this.video_field.currentTime = msg.time;
|
||||
// refresh_data(CLIENT.id, CLIENT.room);
|
||||
}
|
||||
|
||||
if (msg.command == 'refresh') {
|
||||
this.refreshData();
|
||||
}
|
||||
|
||||
if (msg.command == 'play') {
|
||||
this.isManuallyPlayed = false;
|
||||
this.video_field.play();
|
||||
}
|
||||
|
||||
if (msg.command == 'pause') {
|
||||
this.isManuallyPaused = false;
|
||||
this.video_field.pause();
|
||||
}
|
||||
|
||||
if (msg.command == 'message') {
|
||||
this.message_field.innerHTML += msg.message + '<br>';
|
||||
}
|
||||
|
||||
if (msg.command == 'global') {
|
||||
this.global_field.innerHTML += msg.message + '<br>';
|
||||
}
|
||||
|
||||
if (msg.command == 'sync_with_me') {
|
||||
this.syncVideo();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error parsing JSON:', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getSocket() {
|
||||
return this.#ClientSocket;
|
||||
}
|
||||
|
||||
getClientData() {
|
||||
return this.#ClientData;
|
||||
}
|
||||
|
||||
sendCommand(json) {
|
||||
this.#ClientSocket.send(JSON.stringify(json));
|
||||
}
|
||||
|
||||
syncForVid() {
|
||||
const js = {
|
||||
command: 'sync_with_host',
|
||||
room_id: this.#ClientData.room,
|
||||
id: this.#ClientData.id,
|
||||
};
|
||||
this.sendCommand(js);
|
||||
}
|
||||
|
||||
changeName() {
|
||||
const js = {
|
||||
command: 'change_name',
|
||||
id: this.#ClientData.id,
|
||||
room_id: this.#ClientData.room,
|
||||
name: name_input.value,
|
||||
};
|
||||
this.sendCommand(js);
|
||||
}
|
||||
|
||||
sendGlobal() {
|
||||
const js = {
|
||||
command: 'global',
|
||||
message: global_input.value,
|
||||
room_id: this.#ClientData.room,
|
||||
name: this.#ClientData.name,
|
||||
};
|
||||
this.sendCommand(js);
|
||||
}
|
||||
|
||||
makeHost() {
|
||||
const js = {
|
||||
command: 'make_host',
|
||||
id: this.#ClientData.id,
|
||||
room_id: this.#ClientData.room,
|
||||
};
|
||||
this.sendCommand(js);
|
||||
}
|
||||
|
||||
setLink() {
|
||||
const js = {
|
||||
command: 'set_link',
|
||||
link: link_input.value,
|
||||
room_id: this.#ClientData.room,
|
||||
};
|
||||
this.sendCommand(js);
|
||||
}
|
||||
|
||||
syncVideo() {
|
||||
const js = {
|
||||
command: 'sync',
|
||||
time: video_field.currentTime,
|
||||
room_id: this.#ClientData.room,
|
||||
};
|
||||
this.sendCommand(js);
|
||||
}
|
||||
|
||||
refreshData() {
|
||||
axios
|
||||
.post('/api/getRefreshData', {
|
||||
id: this.#ClientData.id,
|
||||
room_id: this.#ClientData.room,
|
||||
})
|
||||
.then((response) => {
|
||||
const data = response.data;
|
||||
this.host_field.textContent = data.host;
|
||||
this.#ClientData.name = data.name;
|
||||
this.name_field.textContent = `Your name: ${data.name}`;
|
||||
this.clients_field.innerHTML = '';
|
||||
let clients = JSON.parse(data.client_data);
|
||||
for (const client of clients)
|
||||
this.clients_field.innerHTML += `<h5>${client.name}</h5>`;
|
||||
if (data.link != undefined) this.video_field.src = data.link;
|
||||
this.video_field.play();
|
||||
this.syncForVid();
|
||||
});
|
||||
}
|
||||
}
|
||||
BIN
public/img.png
Normal file
BIN
public/img.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 68 KiB |
Reference in New Issue
Block a user