Initial commit
This commit is contained in:
parent
9a1d04b6d6
commit
3d2130a17e
7 changed files with 4245 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
node_modules
|
4023
package-lock.json
generated
Normal file
4023
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
21
package.json
Normal file
21
package.json
Normal 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
53
public/script.js
Normal 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
98
public/style.css
Normal 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
25
server.js
Normal 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
24
views/room.ejs
Normal 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>
|
Reference in a new issue