Initial commit

This commit is contained in:
Henry Hiles 2022-02-07 14:09:12 -05:00
parent 9a1d04b6d6
commit 3d2130a17e
7 changed files with 4245 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
node_modules

4023
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

21
package.json Normal file
View file

@ -0,0 +1,21 @@
{
"name": "zoom-clone",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"devStart": "nodemon server.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"ejs": "^3.1.6",
"express": "^4.17.2",
"socket.io": "^2.4.1",
"uuid": "^8.3.2"
},
"devDependencies": {
"nodemon": "^2.0.15"
}
}

53
public/script.js Normal file
View file

@ -0,0 +1,53 @@
const socket = io("/")
const videos = document.getElementById("videos")
const myPeer = new Peer()
const myVideo = document.createElement("video")
myVideo.muted = true
const connectToNewUser = (userId, stream) => {
const call = myPeer.call(userId, stream)
const video = document.createElement("video")
call.on("stream", (userVideoStream) =>
addVideoStream(video, userVideoStream)
)
call.on("close", () => video.remove())
}
const addVideoStream = (video, stream) => {
video.srcObject = stream
video.addEventListener("loadedmetadata", () => video.play())
videos.append(video)
}
navigator.mediaDevices
.getUserMedia({
video: true,
audio: true,
})
.then((stream) => {
addVideoStream(myVideo, stream)
myPeer.on("call", (call) => {
call.answer(stream)
const video = document.createElement("video")
// const fullscreen = document.createElement("button")
// fullscreen.dataset.id =
call.on("close", () => video.remove())
call.on("stream", (userVideoStream) =>
addVideoStream(video, userVideoStream)
)
})
socket.on("user-connected", (userId) =>
connectToNewUser(userId, stream)
)
})
socket.on("user-disconnected", (userId) => {
const call = myPeer.connections[userId]
if (call) call[0].close()
})
myPeer.on("open", (id) => socket.emit("join-room", ROOM_ID, id))

98
public/style.css Normal file
View file

@ -0,0 +1,98 @@
:root {
--primary: #14bbaa;
--secondary: #2c3c4c;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
body {
margin: 0;
font-family: "Lato", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
"Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji",
"Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
font-size: 1.2em;
scroll-behavior: smooth;
width: 100%;
height: 100vh;
grid-auto-rows: 10vh 74vh 16vh;
display: grid;
}
nav,
footer {
background-color: var(--secondary);
color: white;
display: flex;
flex-direction: row;
align-items: center;
max-width: 100vw;
padding: 20px;
}
nav a {
font-size: 1.5em;
}
a {
margin: 0 0.5em;
text-decoration: none;
width: fit-content;
color: white;
grid-template-columns: 1fr 500px;
}
#videos {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(33%, 1fr));
grid-template-rows: repeat(auto-fit, minmax(33%, 1fr));
background-color: var(--primary);
color: white;
padding: 4px 0 4px 0;
gap: 2px;
}
video {
width: 100%;
max-height: 100%;
}
button {
border: none;
border-radius: 2em;
color: #f5f0f0;
background-color: transparent;
font-size: 1em;
padding: 0.7rem 1.6rem;
text-decoration: none;
}
.button-primary {
background-color: var(--primary);
}
.medium-header {
font-size: 2.5rem;
font-weight: 200;
line-height: 1.2;
margin-bottom: 20px;
}
.button-secondary {
background-color: var(--secondary);
}
button:not(:disabled) {
cursor: pointer;
}
button:is(:disabled, :hover) {
filter: brightness(0.9);
}
video.your-video {
display: none;
}

25
server.js Normal file
View file

@ -0,0 +1,25 @@
const express = require("express")
const app = express()
const server = require("http").Server(app)
const io = require("socket.io")(server)
const { v4: uuidV4 } = require("uuid")
app.set("view engine", "ejs")
app.use(express.static("public"))
app.get("/", (_, res) => res.redirect(`/${uuidV4()}`))
app.get("/:room", (req, res) => res.render("room", { roomId: req.params.room }))
io.on("connection", (socket) =>
socket.on("join-room", (roomId, userId) => {
socket.join(roomId)
socket.to(roomId).emit("user-connected", userId)
socket.on("disconnect", () => {
socket.to(roomId).broadcast.emit("user-disconnected", userId)
})
})
)
server.listen(3000)

24
views/room.ejs Normal file
View file

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<script>
const ROOM_ID = "<%= roomId %>"
</script>
<script
src="https://unpkg.com/peerjs@1.3.1/dist/peerjs.min.js"
defer
></script>
<script src="/socket.io/socket.io.js" defer></script>
<script src="script.js" defer></script>
<link rel="stylesheet" href="style.css" />
<title>Document</title>
</head>
<body>
<nav><a href="#">Home</a></nav>
<div id="videos"></div>
<footer></footer>
</body>
</html>