WE WILL DISPLAY THE VIDEOS IN A GRID SYSTEM, PREVIOUSLY (IN NOTES) WE DISPLAYED THE VIDEOS IN THE SAME MANNER THAT IS THE SAME STYLE NO MATTER THE NUMBER OF USERS.
LATER , WE UPDATED IT TO A DIFFERENT STYLE , WHERE WE TAKE THE COUNT OF USERS AND DISPLAY THEIR VIDEOS ACCORDINGLY. HERE, WHEN THE
NUMBER OF USERS ARE >=4 ,WE DISPLAY THEIR VIDEOS INTO 2X2 GRID SYSTEM.
IF THERE ARE MORE , THEN WE INCREASE THE COLUMNS.
WE BEGIN BY FINDING THE NUMBER OF USERS IN THE MEETING.
WE ALSO DISPLAY THE USERNAMES AND THE HOST (CREATOR OF THE MEETING). IN THE NEXT BLOG.
VIDEOCONFERENCE.JSX
const count = videos.length + 1;
const getCount = (count) => {
console.log(count);
if (count === 3 || count === 4) return styles.grid2;
if (count > 4 || count >= 9) return styles.grid3;
if (count > 9) return styles.gird4;
return styles.grid1;
};
WE DISPLAY THE VIDEOS, BY THE NUMBER OF USERS, IF THERE IS ONLY ONE OR 2 USERS, THEN WE DIVIDE THE ENTIRE SCREEN INTO TWO COLUMNS.
.grid1 {
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
grid-auto-rows: 1fr;
}
WHEN THERE ARE 3 OR 4 USERS THEN 2X2 GRID,
.grid2 {
grid-template-columns: repeat(2, 1fr);
grid-auto-rows: minmax(200px, 1fr);
}
WHEN THERE ARE 4 TO 9 , THEN
.grid3 {
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: minmax(200px, 1fr);
}
WHEN THERE ARE MORE THAN 9 USERS,
.grid4 {
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: minmax(200px, 1fr);
}
BUT DURING THIS PROCESS, WE FACED A MAJOR ISSUE THAT WAS THE SIZE OF VIDEO WAS CHANGING AND THE VIDEOS WERE OVERFLOWING, AND HENCE WE GAVE THEM A MAX-HEIGHT.
<div className={styles.vcContainer}>
{askForUsername ? (
<>
<h2
style={{
fontFamily: "Josefin Sans",
color: "#4035351",
fontSize: "3rem",
}}
>
Enter into lobby
</h2>
{isHost ? (
<p style={{fontSize:"2rem"}}>
Share this Meeting Code with your Troop: <b>{room}</b>
</p>
) : (
<></>
)}
<div className={styles.MeetContainer}>
<TextField
className={styles.inputsRequired}
label="Username"
value={username}
variant="outlined"
onChange={(e) => setUsername(e.target.value)}
/>
<Button variant="contained" onClick={connect}>
Connect
</Button>
</div>
<video
className={styles.videoInMeet}
ref={localVideoRef}
autoPlay
muted
></video>
</>
) : (
<div className={styles.displayPage}>
<div className={`${styles.videosContainer} ${getCount(count)}`}>
<div className={styles.userVideo}>
{" "}
<video ref={localVideoRef} autoPlay muted></video>
<Typography className={styles.youLabel}>you</Typography>
</div>
{videos.map(({ socketId, username, stream, role }) => (
<div key={socketId} className={styles.userDisplay}>
<video
ref={(ref) => ref && (ref.srcObject = stream)}
autoPlay
playsInline
/>
<div>
<Typography className={styles.userLabel}>
{username}
</Typography>
{role === "host" && (
<span style={{ color: "gold", position: "absolute" }}>
⭐ Host
</span>
)}
</div>
</div>
))}
</div>
WE USED A LINEAR GRADIENT FROM UI GRADIENT, WE ALSO DISPLAY THE USERLABEL(USERNAME) WHEN HOVERED OVER THE VIDEO.
VC.CSS
.vcContainer {
background: linear-gradient(135deg, #1e1e2f, #4a4a75);
width: 100vw;
height: 100vh;
font-family: Cambria, Cochin, Georgia, Times, "Times New Roman", serif;
display: flex;
flex-direction: column;
align-items: center;
}
.MuiInputBase-root input {
color: white;
}
.inputsRequired .MuiFormLabel-root {
color: gray;
padding: 1rem;
}
.inputsRequired .MuiOutlinedInput-notchedOutline {
border-color: white;
}
.inputsRequired .MuiOutlinedInput-root:hover .MuiOutlinedInput-notchedOutline {
border-color: gray;
}
.inputsRequired .MuiInputBase-root {
margin: 1rem;
}
.MeetContainer {
display: flex;
align-items: center;
justify-content: space-around;
padding: 20px;
width: 50vh;
}
.videoInMeet {
height: 50vh;
width: 50vh;
min-height: 20vh;
min-width: 30vh;
border-radius: 25px;
}
.displayPage {
display: flex;
flex-direction: column;
width: 100vw;
position: relative;
height: 100vh;
}
.videosContainer {
flex: 1;
height: 100vh;
display: grid;
position: relative;
gap: 1rem;
align-items: center;
overflow: auto;
justify-items: center;
}
.grid1 {
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
grid-auto-rows: 1fr;
}
.grid2 {
grid-template-columns: repeat(2, 1fr);
grid-auto-rows: minmax(200px, 1fr);
}
.grid3 {
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: minmax(200px, 1fr);
}
.grid4 {
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: minmax(200px, 1fr);
}
.userVideo,
.userDisplay {
position: relative;
border-radius: 8px;
aspect-ratio: 16 / 9;
background-color: #1e1e2f;
display: flex;
align-content: flex-end;
flex-direction: column;
flex-wrap: wrap;
justify-content: center;
max-width: 500px;
align-items: center;
}
.userVideo video,
.userDisplay video {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 12px;
}
.youLabel,
.userLabel {
position: absolute;
bottom: 4px;
left: 4px;
color: white;
background: rgba(0, 0, 0, 0.6);
padding: 2px 6px;
border-radius: 4px;
font-size: 14px;
}
.youLabel {
display: none;
}
.userVideo:hover .youLabel {
display: block;
}
.userLabel {
display: none;
}
.userDisplay:hover .userLabel {
display: block;
}
Comments
Post a Comment