Video Player and Gallery Using React and Tailwind
A Video Player/Gallery is used to play a list of available videos on the browser, this helps the user to learn through visualization and is very helpful in reaching a large amount of audience effectively. Video Player is used generally by ed-tech companies to upload lectures online and provide demonstrations.
Preview of final output: Let us have a look at how the video player will look like:
Prerequisites:
Basic Feature of a Video Player and Gallery:
- Video Player: This plays the video selected by the user
- Video Gallery: This displays a list of videos to select from
- Welcome Slide: It acts as an introduction to the page
- Video Description: It is used to give additional information about the video
Advantages of Video Player and Gallery:
- It encourages user engagement on the website
- People can learn seamlessly
- Easy navigation results in a better User Experience
- Thumbnails provide a better way to understand the content of the video
Approach to Create a Video Player and Gallery:
- Set up a basic react project and install the required dependencies.
- Create the basic layout consisting of a Navbar and Welcome slide.
- Style the components using Tailwind.
- Pass the data dynamically in the components and render it on the screen.
Steps to Create React Application And Installing Module:
Step 1: Set up the project using the command
npx create-react-app <<Project_Name>>
Step 2: Navigate to the folder using the command
cd <<Project_Name>>
Step 3: Install the required dependencies using the command
npm install -D tailwindcss
Step 4: Create the tailwind config file using the command
npx tailwindcss init
Step 5: Rewrite the tailwind.config.js file as folllows
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./src/**/*.{js,jsx,ts,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}
Project Structure:
The updated dependencies in package.json file will look like:
"dependencies": { "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1", "web-vitals": "^2.1.4" } "devDependencies": { "tailwindcss": "^3.3.3"
}
Example: Write the following code in respective files:
- App.js: This file imports the components and renders them on the screen
- Data.js: This file contains the data to be rendered
- Gallery.js: This component displays the list of videos
- Navbar.js: This component displays the navbar screen
- Video.js: This file plays the currently selected video
- Welcome.js: This file displays the welcome screen
Javascript
// App.js import "./App.css" ; import Gallery from "./components/Gallery" ; import Video from "./components/Video" ; import Welcome from "./components/Welcome" ; function App() { return ( <div className= "" > <Welcome /> <Gallery /> </div> ); } export default App; |
Javascript
// Gallery.js import Video from "./Video" ; import { useState } from "react" ; import Data from "./Data" ; export default function Gallery() { const [activeVid, setActiveVid] = useState( "https://www.youtube.com/embed/0PfTU9JI6Lg?list=PLM68oyaqFM7TCNz4d5J_hxfFg8w41jTYJ" ); const [actTitle, setActTitle] = useState( "GFG POTD 1" ); const [description, setActiveDescription] = useState( "We will learn DFS of Graph in this problem" ); const arr = Data; return ( <div className= "flex flex-row w-11/12 h-full pt-2" > <Video link={activeVid} title={actTitle} description={description} /> <div className= "w-3/6 shadow-lg shadow-gray-600 overflow-y-scroll flex flex-col mt-4 mr-20 border-slate-200 border-2 rounded-lg" style={{ height: "min(38vw, 650px)" }}> <h3 className= "text-2xl p-2 font-semibold" >POTD-August</h3> <p className= "px-2" > GFG Practice</p> {arr.map((e) => { return ( <div className= "hover:bg-gray-300 p-2 border-2 rounded-xl h-2/6 shadow-xl shadow-gray-300" onClick={() => { setActiveVid(e.link); setActTitle(e.title); setActiveDescription(e.description); }}> <img className= "w-1/2 h-20 my-4 mx-2 float-left" src={e.img} /> <p className= "ml-2 font-semibold pt-6 pl-8 text-sm" > {e.title} </p> <p className= "px-2" >{e.description}</p> </div> ); })} </div> </div> ); } |
Javascript
// Navbar.js export default function Navbar() { return ( <div> <nav classNameName= "fixed w-full z-20 top-0 left-0" > <div className= "flex flex-wrap items-center justify-between mx-auto p-4" > <a href= "https://w3wiki.net/" className= "flex items-center" > <img src= "https://media.w3wiki.net/gfg-gg-logo.svg" className= "mr-2" alt= "GFG Logo" /> <span className= "self-center text-2xl font-semibold " > w3wiki </span> </a> <div className= "items-center justify-between hidden w-full md:flex md:w-auto md:order-1" id= "navbar-sticky" > <ul className= "flex flex-col p-4 md:p-0 font-medium md:flex-row md:space-x-8" > <li> <a href= "#" className= "block py-2 pl-3 pr-4 text-white bg-blue-700 rounded md:bg-transparent md:text-blue-700 md:p-0" > Home </a> </li> <li> <a href= "#" className= "block py-2 pl-3 pr-4 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:hover:text-blue-700 md:p-0" > Posts </a> </li> <li> <a href= "#" className= "block py-2 pl-3 pr-4 text-gray-900 rounded hover:bg-gray-100 md:hover:bg-transparent md:hover:text-blue-700 md:p-0" > About us </a> </li> </ul> </div> </div> </nav> </div> ) } |
Javascript
// Welcome.js import Navbar from "./Navbar" ; export default function Welcome() { return ( <div className= "h-40 bg-gray-300 px-24" > <Navbar /> <h1 className= "pt-2 text-center text-slate-800 font-semibold text-3xl" > w3wiki Video Gallery </h1> </div> ); } |
Javascript
// Video.js export default function Video(props) { return ( <div className= "w-screen flex h-screen flex-row mx-12" > <div className= "w-full h-2/3 ml-44 mt-4 px-2 pt-2 rounded-xl border-2 border-slate-400" > <iframe src={props.link} className= "w-full h-5/6" ></iframe> <div className= "mt-1 h-1/3 text-left text-xl text-slate-600" > Title: {props.title} <p className= "text-lg pt-2" > Description:{props.description} </p> </div> </div> </div> ); } |
Javascript
// Data.js import { useDeferredValue } from "react" ; const Data = [ { img: "https://i.ytimg.com/vi/0PfTU9JI6Lg/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBDx0FPXyl9asnEXeJeQRjcNOh6bQ" , link: "https://www.youtube.com/embed/0PfTU9JI6Lg?list=PLM68oyaqFM7TCNz4d5J_hxfFg8w41jTYJ" , title: "GFG POTD 1" , description: "We will learn DFS of Graph in this problem" , }, { img: "https://i.ytimg.com/vi/MxnpwpQA4I4/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDtUunWidfJK9vnjZIBTg9AwWI6KA" , link: "https://www.youtube.com/embed/MxnpwpQA4I4?list=PLM68oyaqFM7TCNz4d5J_hxfFg8w41jTYJ" , title: "GFG POTD 2" , description: "We will learn Shortest Source Path in this problem" , }, { img: "https://i.ytimg.com/vi/OzWNBHxUYO0/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCtPuRpTYFI24y71-DYiPaHcBmFfQ" , link: "https://www.youtube.com/embed/OzWNBHxUYO0?list=PLM68oyaqFM7TCNz4d5J_hxfFg8w41jTYJ" , title: "GFG POTD 3" , description: "We will learn Shortest Path in this problem 3" , }, { img: "https://i.ytimg.com/vi/X05eictbWIg/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLC0L4vTEifv_Rd1g4uSmOERQB3BsQ" , link: "https://www.youtube.com/embed/X05eictbWIg?list=PLM68oyaqFM7TCNz4d5J_hxfFg8w41jTYJ" , title: "GFG POTD 4" , description: "We will learn Reverse Stack in this problem" , }, { img: "https://i.ytimg.com/vi/T3sWA_ha1-w/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAB2JYkK6qTJFba5fUayiUyoyuNXg" , link: "https://www.youtube.com/embed/T3sWA_ha1-w?list=PLM68oyaqFM7TCNz4d5J_hxfFg8w41jTYJ" , title: "GFG POTD 5" , description: "We will learn Chocolate Distribution in this problem" , }, { img: "https://i.ytimg.com/vi/9SSIbuQPamk/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAdV3kVTVr-htccC52e_j6ydhdJkA" , link: "https://www.youtube.com/embed/9SSIbuQPamk?list=PLM68oyaqFM7TCNz4d5J_hxfFg8w41jTYJ" , title: "GFG POTD 6" , description: "We will learn String Permutation in this problem" , }, { img: "https://i.ytimg.com/vi/E5Fz4-ylZ3E/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLALcFccFfnJhyjUqaqTs1ihK6sc9Q" , link: "https://www.youtube.com/embed/E5Fz4-ylZ3E?list=PLM68oyaqFM7TCNz4d5J_hxfFg8w41jTYJ" , title: "GFG POTD 7" , description: "We will learn Solving Sudoku in this problem" , }, { img: "https://i.ytimg.com/vi/dz_tDiMo_eA/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLD9tGVL8i8BzyQ4TT4DpcAxRNNTMA" , link: "https://www.youtube.com/embed/dz_tDiMo_eA?list=PLM68oyaqFM7TCNz4d5J_hxfFg8w41jTYJ" , title: "GFG POTD 8" , description: "We will learn Fraction Pairs in this problem" , }, ]; export default Data; |
CSS
/* index.css */ @tailwind base; @tailwind components; @tailwind utilities; body { margin : 0 ; font-family : -apple-system, BlinkMacSystemFont, 'Segoe UI' , 'Roboto' , 'Oxygen' , 'Ubuntu' , 'Cantarell' , 'Fira Sans' , 'Droid Sans' , 'Helvetica Neue' , sans-serif ; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; height : 100 vh; } code { font-family : source-code-pro, Menlo, Monaco, Consolas, 'Courier New' , monospace ; } |
Steps to Run the application:
Step 1: Type the following command in the terminal of your project directory
npm start
Output: