@ -0,0 +1 @@
|
|||||||
|
web: node index.js
|
@ -0,0 +1,124 @@
|
|||||||
|
## Debugit 2022
|
||||||
|
[](https://hackalog.copsiitbhu.co.in/hackathon/debug-it-2022)
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
Debugit is a week long hackathon open to ideas in a very literal sense. You can make anything from the projects' list we'll share or ignite the inquisitive Bob the Builder inside you to make something exciting and completely new!
|
||||||
|
|
||||||
|
## How to make a submission?
|
||||||
|
Submissions are to be made through GitHub Pull Requests. To know more about how to make a GitHub Pull Request you can refer the [Fundamentals of Git](https://www.youtube.com/playlist?list=PLLt4yMoVgczVgFcTzT60U5IXtNX1qjHL9) playlist which contains everything that you would need.
|
||||||
|
|
||||||
|
## Make sure to include
|
||||||
|
- A README.md file with your name, contact information, project description and how to run the code (and other necessary information).
|
||||||
|
- A folder containing a demo video of your project.
|
||||||
|
|
||||||
|
## Here is a detailed step by step walkthrough if you don't know how to make a Debugit submission.
|
||||||
|
|
||||||
|
- Create a fork of this [repository](https://github.com/COPS-IITBHU/Debugit_2022)
|
||||||
|
A fork is a copy of a repository. Forking a repository allows you to freely experiment with changes without affecting the original project.
|
||||||
|
1. Click on the fork icon in the repository that you might find at the top right corner.
|
||||||
|
|
||||||
|
Demo:
|
||||||
|

|
||||||
|
|
||||||
|
2. It will ask you what would you like to name the forked repository. By default they are named the same as the parent directory. Lets keep the name as it is.
|
||||||
|
|
||||||
|
Demo:
|
||||||
|

|
||||||
|
|
||||||
|
- Clone the repository that you forked
|
||||||
|
1. Find the link which you would need to clone and copy it.
|
||||||
|
|
||||||
|
Demo:
|
||||||
|

|
||||||
|
|
||||||
|
2. Go to the directory in which you want to clone your repository and open the terminal.
|
||||||
|
|
||||||
|
Demo:
|
||||||
|

|
||||||
|
|
||||||
|
3. Run the `git clone` command in the terminal (in case of windows, git bash terminal) and append the link that you copied.
|
||||||
|
```
|
||||||
|
git clone <repository_link>
|
||||||
|
```
|
||||||
|
|
||||||
|
Demo:
|
||||||
|

|
||||||
|
|
||||||
|
4. You will find that the repository is cloned in the directory.
|
||||||
|
- Now you can open the directory in vs code and play with the code and complete your project.
|
||||||
|
- After completing the project, its time to push your code:
|
||||||
|
1. Open the vs code (or any other editor of your choice) terminal in the project folder.
|
||||||
|
2. Create a new branch in which you want to push your code using the following code.
|
||||||
|
```
|
||||||
|
git checkout -b <branch_name>
|
||||||
|
```
|
||||||
|
You can name your branch whatever you like.
|
||||||
|
|
||||||
|
Demo:
|
||||||
|

|
||||||
|
|
||||||
|
3. Check which branch are you on using the `git branch` command.
|
||||||
|
```
|
||||||
|
git branch
|
||||||
|
```
|
||||||
|
4. The branch name with a `*` on it is the current branch. If it is different from the branch that you created, then switch to your branch using the `git checkout`
|
||||||
|
```
|
||||||
|
git checkout <branch_name>
|
||||||
|
```
|
||||||
|
5. You can check the status of the files using
|
||||||
|
```
|
||||||
|
git status
|
||||||
|
```
|
||||||
|
6. Add (Stage) all the files you want to upload using the `git add` command.
|
||||||
|
To add individual files run the following command:
|
||||||
|
```
|
||||||
|
git add <filename>
|
||||||
|
```
|
||||||
|
If you want to add all the files from your project directory you can run
|
||||||
|
```
|
||||||
|
git add .
|
||||||
|
```
|
||||||
|
It is recommended not to add the some directories like node_modules directory in your commit. You can prevent it by adding it in a `.gitignore` file (For more reference [here](https://www.w3schools.com/git/git_ignore.asp?remote=github)).
|
||||||
|
|
||||||
|
Demo:
|
||||||
|

|
||||||
|
|
||||||
|
6. Commmit your code.
|
||||||
|
You can commit all your staged code (to the local git repository) using the `git commit` command
|
||||||
|
Run the following command:
|
||||||
|
```
|
||||||
|
git commit -m "first commit"
|
||||||
|
```
|
||||||
|
You can replace `first commit` with anything. It is actually a message to let you keep a brief track of what changes has been done in that commit.
|
||||||
|
|
||||||
|
Demo:
|
||||||
|

|
||||||
|
|
||||||
|
7. Push your code.
|
||||||
|
Push all of your commited code using the `git push` command.
|
||||||
|
Run the following command:
|
||||||
|
```
|
||||||
|
git push --set-upstream origin <branch_name>
|
||||||
|
```
|
||||||
|
|
||||||
|
Demo:
|
||||||
|

|
||||||
|
|
||||||
|
- Make the Pull Request and submit your code.
|
||||||
|
1. After you push your code, it gets uploaded to your forked directory and creates a new branch that you created.
|
||||||
|
2. If it notices any difference in the code of your forked repo and the parent repo. It automatically shows you an option to create a pull request.
|
||||||
|
|
||||||
|
Demo:
|
||||||
|

|
||||||
|
|
||||||
|
3. Write down a brief description of your project in the Pull Request description and give the PR a proper title and click on create pull request. Now GitHub might run some checks. If you pass all the checks, you are good to go.
|
||||||
|
|
||||||
|
Demo:
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
- Pat yourself on the back
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
> All The Best 🎉🎉.
|
@ -0,0 +1,105 @@
|
|||||||
|
#header img {
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#root-div {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
#left-div {
|
||||||
|
width: 50vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
#large-message {
|
||||||
|
margin-top: 25vh;
|
||||||
|
font-size: 2.5rem;
|
||||||
|
font-family: sans-serif;
|
||||||
|
margin-left: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#small-message {
|
||||||
|
margin-top: 1rem;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
font-family: sans-serif;
|
||||||
|
margin-left: 2rem;
|
||||||
|
color: gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
#start-meeting a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
#new-meeting-root {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 35vw;
|
||||||
|
height: 10vh;
|
||||||
|
margin-top: 3rem;
|
||||||
|
margin-left: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#enter-meeting-link {
|
||||||
|
border: 1px solid grey;
|
||||||
|
border-radius: .2rem;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
color: rgb(97, 94, 94);
|
||||||
|
height: 2rem;
|
||||||
|
padding: .5rem;
|
||||||
|
line-height: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#enter-meeting-link input {
|
||||||
|
border: none;
|
||||||
|
height: 2rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#join-button {
|
||||||
|
font-family: sans-serif;
|
||||||
|
color: #063d86;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
height: 3rem;
|
||||||
|
width: 4rem;
|
||||||
|
border-radius: .2rem;
|
||||||
|
line-height: 3rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#join-button:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: hsla(214, 93%, 47%, .1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#enter-meeting-link input:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#start-meeting {
|
||||||
|
width: 150px;
|
||||||
|
height: 2.1rem;
|
||||||
|
padding-top: 1rem;
|
||||||
|
border-radius: .2rem;
|
||||||
|
color: white;
|
||||||
|
background-color: #096ae7;
|
||||||
|
font-family: sans-serif;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#start-meeting:hover {
|
||||||
|
background-color: #1b66ca;
|
||||||
|
transition: background-color .5s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#right-div {
|
||||||
|
width: 40vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
#right-div img {
|
||||||
|
width: 40vw;
|
||||||
|
margin-top: 20vh;
|
||||||
|
margin-left: -5rem;
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
#left-message {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 10vh;
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#span-div {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
margin-left: 36vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#rejoin {
|
||||||
|
border: .5px solid lightgray;
|
||||||
|
width: 100px;
|
||||||
|
height: 1.8rem;
|
||||||
|
font-family: sans-serif;
|
||||||
|
color: #1B66CA;
|
||||||
|
text-align: center;
|
||||||
|
padding-top: .5rem;
|
||||||
|
border-radius: .2rem;
|
||||||
|
margin-right: 3rem;
|
||||||
|
margin-top: 10vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
#home {
|
||||||
|
width: 200px;
|
||||||
|
height: 1.8rem;
|
||||||
|
padding-top: .5rem;
|
||||||
|
border-radius: .2rem;
|
||||||
|
background-color: #1B66CA;
|
||||||
|
color: white;
|
||||||
|
text-align: center;
|
||||||
|
font-family: sans-serif;
|
||||||
|
margin-top: 10vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
#home:hover {
|
||||||
|
background-color: #0d54af;
|
||||||
|
transition: background-color .5s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#rejoin:hover {
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
transition: background-color .5s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#root {
|
||||||
|
text-align: center;
|
||||||
|
}
|
@ -0,0 +1,238 @@
|
|||||||
|
body {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
background-color: #202124;
|
||||||
|
}
|
||||||
|
|
||||||
|
.centered {
|
||||||
|
position: relative;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%)
|
||||||
|
}
|
||||||
|
|
||||||
|
#main-div {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
#video-grid {
|
||||||
|
height: 90vh;
|
||||||
|
width: 1000px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: start;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-content: flex-start;
|
||||||
|
margin: 1px solid black;
|
||||||
|
}
|
||||||
|
|
||||||
|
#screen-share-grid {
|
||||||
|
display: hidden;
|
||||||
|
height: 90vh;
|
||||||
|
width: 1000px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#screen-share-grid video {
|
||||||
|
display: hidden;
|
||||||
|
height: 80vh;
|
||||||
|
width: 900px;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat-box {
|
||||||
|
width: 350px;
|
||||||
|
margin: 1rem;
|
||||||
|
height: 78vh;
|
||||||
|
border-radius: 1rem;
|
||||||
|
background-color: rgb(236, 183, 226);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat-header {
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
#close-chat-div {
|
||||||
|
cursor: pointer;
|
||||||
|
margin-right: .5rem;
|
||||||
|
height: 22px;
|
||||||
|
width: 23px;
|
||||||
|
padding: .5rem;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-top: -.5rem;
|
||||||
|
margin-left: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#close-chat-div:hover {
|
||||||
|
background-color: rgb(233, 233, 233);
|
||||||
|
transition: background-color .5s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chats {
|
||||||
|
min-height: 57vh;
|
||||||
|
overflow-y: scroll;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
#form {
|
||||||
|
background-color: #F1F3F4;
|
||||||
|
border-radius: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
width: 80%;
|
||||||
|
height: 3rem;
|
||||||
|
border-radius: 1.5rem;
|
||||||
|
border: none;
|
||||||
|
background-color: #F1F3F4;
|
||||||
|
padding-left: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
border: none;
|
||||||
|
background-color: #F1F3F4;
|
||||||
|
font-size: 1.3rem;
|
||||||
|
color: #1A73E8;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-video {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
video {
|
||||||
|
width: 250px;
|
||||||
|
height: 150px;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: .5rem;
|
||||||
|
margin: .5rem;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-video:hover {
|
||||||
|
opacity: .6;
|
||||||
|
transition: opacity .5s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#controls-tab {
|
||||||
|
background-color: #202124;
|
||||||
|
width: 100%;
|
||||||
|
height: 10vh;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex-direction: row;
|
||||||
|
margin-right: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icons {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
#time {
|
||||||
|
color: white;
|
||||||
|
margin-right: 4rem;
|
||||||
|
font-family: sans-serif;
|
||||||
|
padding-left: 2rem;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
border-radius: 50%;
|
||||||
|
height: 33px;
|
||||||
|
width: 45px;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: white;
|
||||||
|
margin-right: 1rem;
|
||||||
|
background-color: #434649;
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
a .end-btn {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.end-btn {
|
||||||
|
background-color: rgb(245, 69, 38);
|
||||||
|
color: white;
|
||||||
|
width: 60px;
|
||||||
|
padding-top: 12px;
|
||||||
|
height: 30px;
|
||||||
|
border-radius: 2rem;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.end-btn i {
|
||||||
|
transform: rotateY(-180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.end-btn:hover {
|
||||||
|
background-color: rgb(250, 64, 32);
|
||||||
|
transition: background-color .5s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:hover {
|
||||||
|
background-color: #3a3c3d;
|
||||||
|
transition: background-color .5s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#messages li {
|
||||||
|
font-family: sans-serif;
|
||||||
|
color: black;
|
||||||
|
font-size: 1rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
margin-left: -1rem;
|
||||||
|
font-size: .8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#messages-info {
|
||||||
|
font-size: .7rem;
|
||||||
|
color: rgb(66, 66, 66);
|
||||||
|
background-color: #F1F3F4;
|
||||||
|
height: 2rem;
|
||||||
|
width: 250px;
|
||||||
|
padding: 1rem;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 1rem;
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
video {
|
||||||
|
position: relative;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-name {
|
||||||
|
position: absolute;
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 4px;
|
||||||
|
color: white;
|
||||||
|
margin-top: -2rem;
|
||||||
|
margin-left: 1rem;
|
||||||
|
font-size: .7rem;
|
||||||
|
z-index: 5;
|
||||||
|
}
|
After Width: | Height: | Size: 15 KiB |
@ -0,0 +1,261 @@
|
|||||||
|
const socket = io();
|
||||||
|
const videoGrid = document.getElementById('video-grid'); //div where our video will be loaded
|
||||||
|
|
||||||
|
var myPeer = new Peer();
|
||||||
|
let count = 0;
|
||||||
|
let myVideoStream; //the video stram is stored in this variable
|
||||||
|
const myVideo = document.createElement('video'); //div which contains the video
|
||||||
|
let currentPeer = null;
|
||||||
|
myVideo.muted = true;
|
||||||
|
const peers = {};
|
||||||
|
const names = {};
|
||||||
|
const userName = prompt("Please enter your name", "");
|
||||||
|
|
||||||
|
function formatAMPM(date) {
|
||||||
|
var hours = date.getHours();
|
||||||
|
var minutes = date.getMinutes();
|
||||||
|
var ampm = hours >= 12 ? 'PM' : 'AM';
|
||||||
|
hours = hours % 12;
|
||||||
|
hours = hours ? hours : 12; // the hour '0' should be '12'
|
||||||
|
minutes = minutes < 10 ? '0' + minutes : minutes;
|
||||||
|
var strTime = hours + ':' + minutes + ' ' + ampm;
|
||||||
|
return strTime;
|
||||||
|
}
|
||||||
|
document.getElementById('time').innerText = formatAMPM(new Date) + " | Meeting";
|
||||||
|
setInterval(setTime, 1000);
|
||||||
|
function setTime() {
|
||||||
|
document.getElementById('time').innerText = formatAMPM(new Date) + " | Meeting";
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('chat-box-btn').addEventListener('click', function () {
|
||||||
|
if (document.getElementById('chat-box').style.display == "none") {
|
||||||
|
document.getElementById('chat-box').style.display = "block"
|
||||||
|
} else {
|
||||||
|
document.getElementById('chat-box').style.display = "none"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
document.getElementById('close-chat-div').addEventListener('click', function () {
|
||||||
|
document.getElementById('chat-box').style.display = "none";
|
||||||
|
})
|
||||||
|
|
||||||
|
navigator.mediaDevices.getUserMedia({
|
||||||
|
video: true, //we want video
|
||||||
|
audio: true //we want audio
|
||||||
|
}).then(stream => {
|
||||||
|
myVideoStream = stream; //storing the video stream returned to the myVideoStream variable
|
||||||
|
addVideoStream(myVideo, stream, userName); //appended my stream to 'video-grid' div
|
||||||
|
|
||||||
|
myPeer.on('call', call => {
|
||||||
|
call.answer(stream);
|
||||||
|
console.log('Hello')
|
||||||
|
const video = document.createElement('video');
|
||||||
|
let html = '<i class="fas fa-microphone"></i>'
|
||||||
|
video.innerHTML = html;
|
||||||
|
call.on('stream', userVideoStream => {
|
||||||
|
console.log('video displayed');
|
||||||
|
addVideoStream(video, userVideoStream, userName)
|
||||||
|
})
|
||||||
|
currentPeer = call;
|
||||||
|
})
|
||||||
|
socket.on('user-connected', (userId) => {
|
||||||
|
setTimeout(connectToNewUser, 1000, userId, userName, stream);
|
||||||
|
});
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
socket.on('user-disconnected', userId => {
|
||||||
|
if (peers[userId]) peers[userId].close()
|
||||||
|
})
|
||||||
|
|
||||||
|
myPeer.on('open', id => {
|
||||||
|
socket.emit('join-room', ROOM_ID, id, userName);
|
||||||
|
})
|
||||||
|
|
||||||
|
function connectToNewUser(userId, userName, stream) {
|
||||||
|
const call = myPeer.call(userId, stream);
|
||||||
|
const video = document.createElement('video');
|
||||||
|
call.on('stream', userVideoStream => {
|
||||||
|
addVideoStream(video, userVideoStream, userName);
|
||||||
|
})
|
||||||
|
call.on('close', () => {
|
||||||
|
video.remove();
|
||||||
|
})
|
||||||
|
peers[userId] = call
|
||||||
|
currentPeer = call;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addVideoStream(video, stream, userName) {
|
||||||
|
video.srcObject = stream; //setting the source of my video
|
||||||
|
video.addEventListener('loadedmetadata', () => {
|
||||||
|
video.play(); //start to play the video once loaded
|
||||||
|
});
|
||||||
|
let outerDiv = document.createElement('div');
|
||||||
|
outerDiv.classList.add('user-video');
|
||||||
|
outerDiv.setAttribute('id', 'video-' + count);
|
||||||
|
count++;
|
||||||
|
outerDiv.appendChild(video);
|
||||||
|
let nameDiv = document.createElement('div');
|
||||||
|
let pinDiv = document.createElement('div');
|
||||||
|
nameDiv.classList.add('user-name');
|
||||||
|
nameDiv.innerHTML = userName;
|
||||||
|
outerDiv.appendChild(nameDiv);
|
||||||
|
videoGrid.appendChild(outerDiv); //appending to 'video-grid' div
|
||||||
|
}
|
||||||
|
|
||||||
|
function muteUnmuteUser() {
|
||||||
|
let enabled = myVideoStream.getAudioTracks()[0].enabled;
|
||||||
|
if (enabled == true) {
|
||||||
|
myVideoStream.getAudioTracks()[0].enabled = false;
|
||||||
|
setUnmuteAudio();
|
||||||
|
} else {
|
||||||
|
myVideoStream.getAudioTracks()[0].enabled = true;
|
||||||
|
setMuteAudio();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function turnUserVideoOnOff() {
|
||||||
|
let enabled = myVideoStream.getVideoTracks()[0].enabled;
|
||||||
|
if (enabled == true) {
|
||||||
|
myVideoStream.getVideoTracks()[0].enabled = false;
|
||||||
|
setStopVideo()
|
||||||
|
} else {
|
||||||
|
setPlayVideo()
|
||||||
|
myVideoStream.getVideoTracks()[0].enabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setPlayVideo() {
|
||||||
|
const html = `<i class="fas fa-video"></i>`
|
||||||
|
document.getElementById('video-off').innerHTML = html;
|
||||||
|
document.getElementById('video-off').style.backgroundColor = '#434649';
|
||||||
|
}
|
||||||
|
|
||||||
|
function setStopVideo() {
|
||||||
|
const html = `<i class="stop fas fa-video-slash"></i>`
|
||||||
|
document.getElementById('video-off').innerHTML = html;
|
||||||
|
document.getElementById('video-off').style.backgroundColor = 'tomato';
|
||||||
|
}
|
||||||
|
|
||||||
|
function setMuteAudio() {
|
||||||
|
const html = `<i class="fas fa-microphone"></i>`
|
||||||
|
document.getElementById('mute').innerHTML = html;
|
||||||
|
document.getElementById('mute').style.backgroundColor = '#434649';
|
||||||
|
}
|
||||||
|
|
||||||
|
function setUnmuteAudio() {
|
||||||
|
const html = `<i class="unmute fas fa-microphone-slash"></i>`
|
||||||
|
document.getElementById('mute').innerHTML = html;
|
||||||
|
document.getElementById('mute').style.backgroundColor = 'tomato';
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('video-off').addEventListener('click', turnUserVideoOnOff);
|
||||||
|
document.getElementById('mute').addEventListener('click', muteUnmuteUser);
|
||||||
|
|
||||||
|
function urlify(text) {
|
||||||
|
var urlRegex = /(https?:\/\/[^\s]+)/g;
|
||||||
|
return text.replace(urlRegex, function(url) {
|
||||||
|
return '<a href="' + url + '">' + url + '</a>';
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$('form').submit(function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
let inputMsg = $('input').val();
|
||||||
|
if (inputMsg != '')
|
||||||
|
socket.emit('send-message', inputMsg, userName);
|
||||||
|
$('input').val('');
|
||||||
|
})
|
||||||
|
|
||||||
|
socket.on('recieve-message', (inputMsg, userName) => {
|
||||||
|
inputMsg = urlify(inputMsg);
|
||||||
|
$('#messages').append(`<li><b style="font-size:.9rem">${userName}</b> ${formatAMPM(new Date)}<br/><br/>${inputMsg}</li>`);
|
||||||
|
console.log('From server :: ', inputMsg);
|
||||||
|
})
|
||||||
|
|
||||||
|
const scrollToBottom = () => {
|
||||||
|
var d = $('#chats');
|
||||||
|
d.scrollTop(d.prop("scrollHeight"));
|
||||||
|
}
|
||||||
|
scrollToBottom();
|
||||||
|
|
||||||
|
|
||||||
|
var screenSharing = false
|
||||||
|
function startScreenShare() {
|
||||||
|
if (screenSharing) {
|
||||||
|
stopScreenSharing()
|
||||||
|
}
|
||||||
|
navigator.mediaDevices.getDisplayMedia({ video: true }).then((stream) => {
|
||||||
|
screenStream = stream;
|
||||||
|
let videoTrack = screenStream.getVideoTracks()[0];
|
||||||
|
videoTrack.onended = () => {
|
||||||
|
console.log('Screen sharing stopped!');
|
||||||
|
stopScreenSharing()
|
||||||
|
}
|
||||||
|
if (myPeer) {
|
||||||
|
let sender = currentPeer.peerConnection.getSenders().find(function (s) {
|
||||||
|
return s.track.kind == videoTrack.kind;
|
||||||
|
})
|
||||||
|
sender.replaceTrack(videoTrack)
|
||||||
|
screenSharing = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopScreenSharing() {
|
||||||
|
if (!screenSharing) return;
|
||||||
|
let videoTrack = myVideoStream.getVideoTracks()[0];
|
||||||
|
if (myPeer) {
|
||||||
|
let sender = currentPeer.peerConnection.getSenders().find(function (s) {
|
||||||
|
return s.track.kind == videoTrack.kind;
|
||||||
|
})
|
||||||
|
sender.replaceTrack(videoTrack)
|
||||||
|
}
|
||||||
|
screenStream.getTracks().forEach(function (track) {
|
||||||
|
track.stop();
|
||||||
|
});
|
||||||
|
screenSharing = false
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('screen-share-btn').addEventListener('click', startScreenShare);
|
||||||
|
|
||||||
|
var isExpanded = false;
|
||||||
|
document.addEventListener('click', function(e) {
|
||||||
|
let clickedElem = e.target;
|
||||||
|
let clickedElemId = e.target.id;
|
||||||
|
if(isExpanded == false) {
|
||||||
|
console.log(clickedElem);
|
||||||
|
if(clickedElem.classList.contains('user-video')) {
|
||||||
|
let ele = document.getElementById(clickedElemId);
|
||||||
|
//ele.style.height = "80vh";
|
||||||
|
// ele.style.width = "70vw";
|
||||||
|
ele.firstChild.style.height = "80vh";
|
||||||
|
ele.firstChild.style.width = "70vw";
|
||||||
|
isExpanded = true;
|
||||||
|
let arr = document.getElementsByClassName('user-video');
|
||||||
|
for(let i=0;i<arr.length;i++) {
|
||||||
|
let elem = arr[i];
|
||||||
|
if(elem.id != clickedElemId) {
|
||||||
|
elem.style.display = "none";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}else {
|
||||||
|
if(clickedElem.classList.contains('user-video')) {
|
||||||
|
let ele = document.getElementById(clickedElemId);
|
||||||
|
//ele.style.height = "150px";
|
||||||
|
//ele.style.width = "250px";
|
||||||
|
ele.firstChild.style.height = "200px";
|
||||||
|
ele.firstChild.style.width = "300px";
|
||||||
|
document.getElementById('video-grid').style.display = "flex";
|
||||||
|
isExpanded = false;
|
||||||
|
let arr = document.getElementsByClassName('user-video');
|
||||||
|
for(let i=0;i<arr.length;i++) {
|
||||||
|
arr[i].style.display = "flex";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
After Width: | Height: | Size: 99 KiB |
@ -0,0 +1,18 @@
|
|||||||
|
//used to get unique room ids
|
||||||
|
const { v4: uuidv4 } = require('uuid');
|
||||||
|
|
||||||
|
module.exports.renderHome = function(req, res) {
|
||||||
|
return res.render('home');
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.createNewRoom = function(req, res) {
|
||||||
|
return res.redirect(`/room/${uuidv4()}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.joinRoom = function(req, res) {
|
||||||
|
return res.render('room', { roomId: req.params.room });
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.leaveRoom = function(req, res) {
|
||||||
|
return res.render('meeting_end', { roomId: req.params.room });
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
//requiring express
|
||||||
|
|
||||||
|
const express = require('express');
|
||||||
|
|
||||||
|
//app has all the properties of express
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
//creting http server
|
||||||
|
|
||||||
|
const server = require('http').Server(app);
|
||||||
|
|
||||||
|
//socket runs on this server
|
||||||
|
const io = require('socket.io')(server);
|
||||||
|
|
||||||
|
//WebRTC api for real time media communication
|
||||||
|
const { ExpressPeerServer } = require('peer');
|
||||||
|
//port on which server runs
|
||||||
|
const PORT = process.env.PORT || 8000;
|
||||||
|
|
||||||
|
const peerServer = ExpressPeerServer(server, {
|
||||||
|
debug: true
|
||||||
|
});
|
||||||
|
|
||||||
|
//setting up static path
|
||||||
|
app.use(express.static('./assets'));
|
||||||
|
//setting up view engine
|
||||||
|
app.set('view engine', 'ejs');
|
||||||
|
//setting up view path
|
||||||
|
app.set('views', './views');
|
||||||
|
|
||||||
|
|
||||||
|
app.use('/', require('./routes/index'));
|
||||||
|
|
||||||
|
|
||||||
|
//socket handels users joining/leaving and messaging
|
||||||
|
io.on('connection', socket => {
|
||||||
|
//request for joining room
|
||||||
|
socket.on('join-room', (roomId, userId, userName) => {
|
||||||
|
//joining the mentioned room
|
||||||
|
socket.join(roomId);
|
||||||
|
|
||||||
|
socket.broadcast.to(roomId).emit('user-connected', userId, userName);
|
||||||
|
socket.on('send-message', (inputMsg, userName) => {
|
||||||
|
io.to(roomId).emit('recieve-message', inputMsg, userName);
|
||||||
|
})
|
||||||
|
socket.on('disconnect', () => {
|
||||||
|
socket.broadcast.to(roomId).emit('user-disconnected', userId, userName);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// running the server
|
||||||
|
server.listen(PORT, function(err) {
|
||||||
|
if (err) {
|
||||||
|
console.log(`Error :: ${err} occured while starting the server in index.js!`);
|
||||||
|
}
|
||||||
|
console.log(`Server is up and running on port ${PORT}`);
|
||||||
|
});
|
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 80 KiB |
After Width: | Height: | Size: 41 KiB |
After Width: | Height: | Size: 276 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 77 KiB |
After Width: | Height: | Size: 55 KiB |
After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 1.7 MiB |
After Width: | Height: | Size: 78 KiB |
After Width: | Height: | Size: 48 KiB |
After Width: | Height: | Size: 101 KiB |
@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"name": "zoom-clone",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "A Zoom Conferencing App Clone",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"start": "nodemon index.js"
|
||||||
|
},
|
||||||
|
"author": "Lalit singh",
|
||||||
|
"license": "ISC",
|
||||||
|
"engines": {
|
||||||
|
"node": "16.14.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ejs": "^3.1.6",
|
||||||
|
"express": "^4.17.3",
|
||||||
|
"heroku": "^7.59.0",
|
||||||
|
"nodemon": "^2.0.14",
|
||||||
|
"peer": "^0.6.1",
|
||||||
|
"socket.io": "^4.2.0",
|
||||||
|
"uuid": "^8.3.2"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
const express = require('express');
|
||||||
|
const router = express.Router();
|
||||||
|
const indexController = require('../controller/index_controller');
|
||||||
|
|
||||||
|
|
||||||
|
router.get('/', indexController.renderHome);
|
||||||
|
router.use('/room', require('./room.js'));
|
||||||
|
|
||||||
|
module.exports = router;
|
@ -0,0 +1,13 @@
|
|||||||
|
const express = require('express');
|
||||||
|
const router = express.Router();
|
||||||
|
const indexController = require('../controller/index_controller');
|
||||||
|
|
||||||
|
//route for new meeting --> creates a new room
|
||||||
|
router.get('/', indexController.createNewRoom);
|
||||||
|
|
||||||
|
//route for opening a specific room
|
||||||
|
router.get('/:room', indexController.joinRoom);
|
||||||
|
|
||||||
|
router.get('/end/:room', indexController.leaveRoom);
|
||||||
|
|
||||||
|
module.exports = router;
|
@ -0,0 +1,28 @@
|
|||||||
|
<!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" type="text/css" href="/css/meeting_end_style.css">
|
||||||
|
<title>Meet</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="root">
|
||||||
|
<div id="left-message">You left the meet</div>
|
||||||
|
<div id="span-div">
|
||||||
|
<a href="/room/<%= roomId %>">
|
||||||
|
<div id="rejoin">Rejoin</div>
|
||||||
|
</a>
|
||||||
|
<a href="/">
|
||||||
|
<div id="home">Return to home screen</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
@ -0,0 +1,61 @@
|
|||||||
|
<!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" type="text/css" href="/css/style.css">
|
||||||
|
<title>Meet</title>
|
||||||
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
|
||||||
|
<script src="https://kit.fontawesome.com/6f0f83005a.js" crossorigin="anonymous"></script>
|
||||||
|
<script>
|
||||||
|
const ROOM_ID = "<%= roomId %>";
|
||||||
|
</script>
|
||||||
|
<script defer src="https://unpkg.com/peerjs@1.2.0/dist/peerjs.min.js"></script>
|
||||||
|
<script src="/socket.io/socket.io.js" defer></script>
|
||||||
|
<script src="/js/script.js" defer></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="main-div">
|
||||||
|
<div id="video-grid"></div>
|
||||||
|
<div id="screen-share-grid"></div>
|
||||||
|
<div id="chat-box">
|
||||||
|
<div id="chat-header">
|
||||||
|
<div>In-call messages</div>
|
||||||
|
<div id="close-chat-div"><i class="fa fa-times" aria-hidden="true"></i></div>
|
||||||
|
</div>
|
||||||
|
<div id="chats">
|
||||||
|
<div id="messages-info">Messages can only be seen by people in the call and are deleted when the call ends</div>
|
||||||
|
<ul id="messages">
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div id="form">
|
||||||
|
<form>
|
||||||
|
<input type="text" id="message-form" placeholder="Send a message to everyone" autocomplete="off">
|
||||||
|
<button type="submit"><i class="fa fa-paper-plane"></i></button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="controls-tab">
|
||||||
|
<div id="time"></div>
|
||||||
|
<div class="icons">
|
||||||
|
<div class="btn" id="mute"><i class="fa fa-microphone"></i></div>
|
||||||
|
<div class="btn" id="video-off"><i class="fa fa-video-camera"></i></div>
|
||||||
|
<div class="btn" id="screen-share-btn"><i class="fa fa-upload"></i></div>
|
||||||
|
<a href="/room/end/<%= roomId %>">
|
||||||
|
<div class="end-btn"><i class="fa fa-phone" aria-hidden="true"></i></div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="icons">
|
||||||
|
<div class="btn" id="chat-box-btn"><i class="fas fa-comment-alt"></i></i>
|
||||||
|
</div>
|
||||||
|
<div class="btn"><i class="fas fa-info-circle"></i></div>
|
||||||
|
<div class="btn"><i class="fas fa-user-friends"></i>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|