diff --git a/zoom/src/public/js/app.js b/zoom/src/public/js/app.js index 6c9ead36..0054c05c 100644 --- a/zoom/src/public/js/app.js +++ b/zoom/src/public/js/app.js @@ -1,85 +1,94 @@ const socket = io(); -const welcome = document.getElementById("welcome"); -const form = welcome.querySelector("form"); -const room = document.getElementById("room"); +const myFace = document.getElementById("myFace"); +const muteBtn = document.getElementById("mute"); +const cameraBtn = document.getElementById("camera"); +const camerasSelect = document.getElementById("cameras"); -room.hidden = true; +let myStream; +let mute = false; +let camera = false; -let roomName; -function addMessage(messages) { - const ul = room.querySelector("ul"); - const li = document.createElement("li"); - li.innerText = messages; - ul.appendChild(li); -} -function handleMessageSubmit(event) { - event.preventDefault(); - const input = room.querySelector("#msg input"); - const value = input.value; - socket.emit("message", input.value, roomName, () => { - addMessage(`You : ${value}`); - }); - input.value = ""; -} +async function getCameras() { + try { + const devices = await navigator.mediaDevices.enumerateDevices(); + const cameras = devices.filter(device => device.kind === 'videoinput'); + const currentCamera = myStream.getVideoTracks()[0]; -function handleNicknameSubmit(event) { - event.preventDefault(); - const input = room.querySelector("#name input"); - socket.emit("nickname", input.value); -} - -function showRoom() { - welcome.hidden = true; - room.hidden = false; - const h3 = room.querySelector("h3"); - h3.innerText = `Room : ${roomName}`; - const msgForm = room.querySelector("#msg"); - const nameForm = room.querySelector("#name"); - msgForm.addEventListener("submit", handleMessageSubmit); - nameForm.addEventListener("submit", handleNicknameSubmit); -} -function handleRoomSubmit(event) { - event.preventDefault(); - const input = form.querySelector("input"); - - socket.emit( - "enter_room", - input.value, - showRoom - ); - roomName = input.value; - input.value = ""; -} - -form.addEventListener("submit", handleRoomSubmit); - -socket.on("welcome", (user, count) => { - const h3 = room.querySelector("h3"); - h3.innerText = `Room : ${roomName} (${count})`; - addMessage(`${user} joined!`); -}) - -socket.on("bye", (left, count) => { - const h3 = room.querySelector("h3"); - h3.innerText = `Room : ${roomName} (${count})`; - addMessage(`${left} left...`); -}) - -socket.on("message", addMessage); - -socket.on("room_change", (rooms) => { - const roomList = welcome.querySelector("ul"); - roomList.innerHTML = ""; - - if (rooms.length === 0) { - return; + cameras.forEach(camera => { + const option = document.createElement("option"); + option.value = camera.deviceId; + option.innerText = camera.label; + if (currentCamera.label === camera.label) { + option.selected = true; + } + camerasSelect.appendChild(option); + }); + } catch (e) { + console.log(e); } - rooms.forEach(room => { - const li = document.createElement("li"); - li.innerText = room; - roomList.appendChild(li); - }); -}); \ No newline at end of file +} + +async function getMedia(deviceId) { + const initialConstraints = { + audio: true, + video: { facingMode: "user"}, + } + const cameraConstraints = { + audio: true, + video: { deviceId: { exact : deviceId }}, + } + + try { + myStream = await navigator.mediaDevices.getUserMedia( + deviceId ? cameraConstraints : initialConstraints + ); + + myFace.srcObject = myStream; + + if (!deviceId) { + await getCameras(); + } + } catch (e) { + console.log(e); + } +} + +getMedia(); + +function handleMuteClick() { + myStream + .getAudioTracks() + .forEach((track) => (track.enabled = !track.enabled)); + + if (mute) { + muteBtn.innerText = "Mute"; + mute = false; + } else { + muteBtn.innerText = "UnMute"; + mute = true; + } +} + +function handleCameraClick() { + myStream + .getVideoTracks() + .forEach((track) => (track.enabled = !track.enabled)); + + if (camera) { + cameraBtn.innerText = "Turn Camera Off"; + camera = false; + } else { + cameraBtn.innerText = "Turn Camera On"; + camera = true; + } +} + +async function handleCameraChange() { + await getMedia(camerasSelect.value); +} +muteBtn.addEventListener("click", handleMuteClick); +cameraBtn.addEventListener("click", handleCameraClick); +camerasSelect.addEventListener("input", handleCameraChange); \ No newline at end of file diff --git a/zoom/src/public/js/app_socketIO.js b/zoom/src/public/js/app_socketIO.js new file mode 100644 index 00000000..6c9ead36 --- /dev/null +++ b/zoom/src/public/js/app_socketIO.js @@ -0,0 +1,85 @@ +const socket = io(); + +const welcome = document.getElementById("welcome"); +const form = welcome.querySelector("form"); +const room = document.getElementById("room"); + +room.hidden = true; + +let roomName; + +function addMessage(messages) { + const ul = room.querySelector("ul"); + const li = document.createElement("li"); + li.innerText = messages; + ul.appendChild(li); +} + +function handleMessageSubmit(event) { + event.preventDefault(); + const input = room.querySelector("#msg input"); + const value = input.value; + socket.emit("message", input.value, roomName, () => { + addMessage(`You : ${value}`); + }); + input.value = ""; +} + +function handleNicknameSubmit(event) { + event.preventDefault(); + const input = room.querySelector("#name input"); + socket.emit("nickname", input.value); +} + +function showRoom() { + welcome.hidden = true; + room.hidden = false; + const h3 = room.querySelector("h3"); + h3.innerText = `Room : ${roomName}`; + const msgForm = room.querySelector("#msg"); + const nameForm = room.querySelector("#name"); + msgForm.addEventListener("submit", handleMessageSubmit); + nameForm.addEventListener("submit", handleNicknameSubmit); +} +function handleRoomSubmit(event) { + event.preventDefault(); + const input = form.querySelector("input"); + + socket.emit( + "enter_room", + input.value, + showRoom + ); + roomName = input.value; + input.value = ""; +} + +form.addEventListener("submit", handleRoomSubmit); + +socket.on("welcome", (user, count) => { + const h3 = room.querySelector("h3"); + h3.innerText = `Room : ${roomName} (${count})`; + addMessage(`${user} joined!`); +}) + +socket.on("bye", (left, count) => { + const h3 = room.querySelector("h3"); + h3.innerText = `Room : ${roomName} (${count})`; + addMessage(`${left} left...`); +}) + +socket.on("message", addMessage); + +socket.on("room_change", (rooms) => { + const roomList = welcome.querySelector("ul"); + roomList.innerHTML = ""; + + if (rooms.length === 0) { + return; + } + rooms.forEach(room => { + const li = document.createElement("li"); + li.innerText = room; + roomList.appendChild(li); + }); +}); \ No newline at end of file diff --git a/zoom/src/server.js b/zoom/src/server.js index 15ee53a5..dcd610c7 100644 --- a/zoom/src/server.js +++ b/zoom/src/server.js @@ -1,73 +1,17 @@ import http from "http"; -import { Server } from "socket.io"; -import { instrument } from "@socket.io/admin-ui"; -import express, { application } from "express"; +import SocketIO from "socket.io"; +import express from "express"; const app = express(); app.set("view engine", "pug"); app.set("views", __dirname + "/views"); - app.use("/public", express.static(__dirname + "/public")); - -app.get("/", (req, res) => res.render("home")); -app.get("/*", (req, res) => res.redirect("/")); -const handleListen = () => console.log(`Listening on http://localhost:3000`); +app.get("/", (_, res) => res.render("home")); +app.get("/*", (_, res) => res.redirect("/")); const httpServer = http.createServer(app); -const wsServer = new Server(httpServer, { - cors: { - origin: ["https://admin.socket.io"], - credentials: true, - }, -}); - -instrument(wsServer, { - auth: false, -}); - -function publicRooms() { - const {sockets: {adapter: {sids, rooms}}} = wsServer; - - const publicRooms = []; - rooms.forEach((_, key) => { - if(sids.get(key) === undefined) { - publicRooms.push(key); - } - }); - return publicRooms; -} - -function countUsers(roomName) { - return wsServer.sockets.adapter.rooms.get(roomName)?.size; -} - -wsServer.on("connection", socket => { - socket['nickname'] = "Anonymous"; - socket.onAny((event) => { - console.log(`Socket Event: ${event}`) - }); - socket.on("enter_room", (roomName, done) => { - socket.join(roomName); - done(); - socket.to(roomName).emit("welcome", socket.nickname, countUsers(roomName)); - wsServer.sockets.emit("room_change", publicRooms()) - }); - socket.on("disconnecting", () => { - socket.rooms.forEach((room) => { - socket.to(room).emit("bye", socket.nickname, countUsers(room) - 1); - }); - }) - socket.on("disconnect", () => { - wsServer.sockets.emit("room_change", publicRooms()) - }) - socket.on("message", (msg, room, done) => { - socket.to(room).emit("message", `${socket.nickname}: ${msg}`); - done(); - }) - socket.on("nickname", (nickname) => { - socket["nickname"] = nickname; - }) -}); +const wsServer = SocketIO(httpServer); +const handleListen = () => console.log(`Listening on http://localhost:3000`); httpServer.listen(3000, handleListen); \ No newline at end of file diff --git a/zoom/src/server_socketIO.js b/zoom/src/server_socketIO.js new file mode 100644 index 00000000..15ee53a5 --- /dev/null +++ b/zoom/src/server_socketIO.js @@ -0,0 +1,73 @@ +import http from "http"; +import { Server } from "socket.io"; +import { instrument } from "@socket.io/admin-ui"; +import express, { application } from "express"; + +const app = express(); + +app.set("view engine", "pug"); +app.set("views", __dirname + "/views"); + +app.use("/public", express.static(__dirname + "/public")); + +app.get("/", (req, res) => res.render("home")); +app.get("/*", (req, res) => res.redirect("/")); +const handleListen = () => console.log(`Listening on http://localhost:3000`); + +const httpServer = http.createServer(app); +const wsServer = new Server(httpServer, { + cors: { + origin: ["https://admin.socket.io"], + credentials: true, + }, +}); + +instrument(wsServer, { + auth: false, +}); + +function publicRooms() { + const {sockets: {adapter: {sids, rooms}}} = wsServer; + + const publicRooms = []; + rooms.forEach((_, key) => { + if(sids.get(key) === undefined) { + publicRooms.push(key); + } + }); + return publicRooms; +} + +function countUsers(roomName) { + return wsServer.sockets.adapter.rooms.get(roomName)?.size; +} + +wsServer.on("connection", socket => { + socket['nickname'] = "Anonymous"; + socket.onAny((event) => { + console.log(`Socket Event: ${event}`) + }); + socket.on("enter_room", (roomName, done) => { + socket.join(roomName); + done(); + socket.to(roomName).emit("welcome", socket.nickname, countUsers(roomName)); + wsServer.sockets.emit("room_change", publicRooms()) + }); + socket.on("disconnecting", () => { + socket.rooms.forEach((room) => { + socket.to(room).emit("bye", socket.nickname, countUsers(room) - 1); + }); + }) + socket.on("disconnect", () => { + wsServer.sockets.emit("room_change", publicRooms()) + }) + socket.on("message", (msg, room, done) => { + socket.to(room).emit("message", `${socket.nickname}: ${msg}`); + done(); + }) + socket.on("nickname", (nickname) => { + socket["nickname"] = nickname; + }) +}); + +httpServer.listen(3000, handleListen); \ No newline at end of file diff --git a/zoom/src/views/home.pug b/zoom/src/views/home.pug index 5787973b..d64b6833 100644 --- a/zoom/src/views/home.pug +++ b/zoom/src/views/home.pug @@ -1,32 +1,21 @@ doctype html html(lang="en") - head - meta(charset="UTF-8") - meta(http-equiv="X-UA-Compatible", content="IE=edge") - meta(name="viewport", content="width=device-width, initial-scale=1.0") + head + meta(charset="UTF-8") + meta(http-equiv="X-UA-Compatible", content="IE=edge") + meta(name="viewport", content="width=device-width, initial-scale=1.0") - link(rel="stylesheet", href="https://unpkg.com/mvp.css") - title Zooom - body - header - h1 Zooom! - main - div#welcome - form - input(placeholder="room name", required, type="text") - button Enter Room - h4 Open Rooms: - ul - - div#room - h3 - ul - form#name - input(placeholder="nickname", required, type="text") - button Save - form#msg - input(placeholder="message", required, type="text") - button Send + link(rel="stylesheet", href="https://unpkg.com/mvp.css") + title Zooom + body + header + h1 Zooom! + main + div#myStream + video#myFace(autoplay, playsinline, width="400", height="400") + button#mute Mute + button#camera Turn Camera Off + select#cameras - script(src="/socket.io/socket.io.js") - script(src="/public/js/app.js") \ No newline at end of file + script(src="/socket.io/socket.io.js") + script(src="/public/js/app.js") \ No newline at end of file diff --git a/zoom/src/views/home_socketIO.pug b/zoom/src/views/home_socketIO.pug new file mode 100644 index 00000000..5787973b --- /dev/null +++ b/zoom/src/views/home_socketIO.pug @@ -0,0 +1,32 @@ +doctype html +html(lang="en") + head + meta(charset="UTF-8") + meta(http-equiv="X-UA-Compatible", content="IE=edge") + meta(name="viewport", content="width=device-width, initial-scale=1.0") + + link(rel="stylesheet", href="https://unpkg.com/mvp.css") + title Zooom + body + header + h1 Zooom! + main + div#welcome + form + input(placeholder="room name", required, type="text") + button Enter Room + h4 Open Rooms: + ul + + div#room + h3 + ul + form#name + input(placeholder="nickname", required, type="text") + button Save + form#msg + input(placeholder="message", required, type="text") + button Send + + script(src="/socket.io/socket.io.js") + script(src="/public/js/app.js") \ No newline at end of file