Very Simple NodeJS Express Video Gallery (Free Download)

Welcome to a tutorial on how to create a very simple video gallery with NodeJS and Express. So you want to share some videos online, but don’t want to go through all of those “crazy video galleries”? Well, here’s how to build a very simple one – Read on!

 

 

TABLE OF CONTENTS

 

DOWNLOAD & NOTES

Here is the download link to the example code, so you don’t have to copy-paste everything.

 

EXAMPLE CODE DOWNLOAD

Source code on GitHub Gist

Just click on “download zip” or do a git clone. I have released it under the MIT license, so feel free to build on top of it or use it in your own project.

 

SORRY FOR THE ADS...

But someone has to pay the bills, and sponsors are paying for it. I insist on not turning Code Boxx into a "paid scripts" business, and I don't "block people with Adblock". Every little bit of support helps.

Buy Me A Coffee Code Boxx eBooks

 

 

 

 

QUICK SETUP

  • Run npm i glob express ejs to install the required modules.
  • There are 3 folders in this project:
    • gallery Put all your videos in this folder.
    • public CSS, Javascript, fonts.
    • views HTML templates.

 

 

PART 1) EXPRESS HTTP SERVER

1-server.js
// (A) LOAD REQUIRED MODULES
const express = require("express"),
path = require("path"),
glob = require("glob");
 
// (B) INIT EXPRESS SERVER
const app = express();
app.set("view engine", "ejs");
 
// (C) GET VIDEOS
var videos = glob.sync("gallery/**/*.{avi,mp4,ogg,webm}");
var names = [];
videos.forEach(vid => names.push(path.parse(vid).name));
 
// (D) GALLERY VIDEOS & PAGE
app.use("/public", express.static(path.join(__dirname, "public")))
app.use("/gallery", express.static(path.join(__dirname, "gallery")))
app.get("/", (req, res) => res.render("2a-gallery.ejs" , { videos: videos, names: names }));
 
// (E) START SERVER
app.listen(80, () => console.log(`Server running at port 80`));

Let us start with the Express HTTP server, this should not be too much trouble.

  • (A & B) Load the required modules and initialize Express.
  • (C) Get a list of the video files inside the gallery folder.
  • (D) Define the HTTP “endpoints”.
    • Serve static files from both gallery and public.
    • Serve views/2a-gallery.ejs at http://your-site.com/. Take note, we are using EJS to handle the HTML templates, and passing in a list of videos into the HTML template.
  • (E) Start the HTTP server.

 

 

PART 2) GALLERY PAGE

2A) THE HTML

views/2a-gallery.ejs
<!-- (A) CLOSE FULLSCREEN VIDEO -->
<div id="vClose" onclick="vplay.toggle(false)">X</div>
 
<!-- (B) VIDEO GALLERY -->
<div class="gallery">
  <% videos.forEach((vid, i) => { %>
  <div class="vWrap">
    <video src="<%= vid %>"></video>
    <div class="vCaption"><%= names[i] %></div>
  </div>
  <% }); %>
</div>

Yep, that’s all for the HTML video gallery.

  1. This “close” button will only show when the user clicks on a video to play on full screen.
  2. Remember that we passed in a list of videos in the server script above? We simply loop through and create the <video> tags here.

 

2B) THE CSS

public/2b-gallery.css
/* (A) GALLERY WRAPPER */
/* (A1) BIG SCREENS - 3 IMAGES PER ROW */
.gallery {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-gap: 10px;
  max-width: 1200px;
  margin: 0 auto; /* horizontal center */
}
 
/* (A2) SMALL SCREENS - 2 IMAGES PER ROW */
@media screen and (max-width: 768px) {
  .gallery { grid-template-columns: repeat(2, 1fr); }
}
 
/* (B) GALLERY VIDEOS */
/* (B1) THUMBNAIL VIDEO */
.gallery video {
  width: 100%;
  height: 200px;
  object-fit: cover; /* fill | contain | cover | scale-down */
  cursor: pointer;
}
 
/* (B2) FULLSCREEN VIDEO */
.gallery video.full {
  position: fixed;
  top: 0; left: 0; z-index: 999;
  width: 100vw; height: 100vh;
  background: #000;
  object-fit: scale-down;
}
 
/* (C) EXIT FULLSCREEN */
#vClose {
  position: fixed; display: none;
  top: 0; right: 0; z-index: 9999;
  font-size: 20px; font-weight: 700;
  padding: 10px 15px;
  color: #fff;
  background: #741414;
  cursor: pointer;
}
#vClose.show { display: block; }
 
/* (D) CAPTION */
.vWrap {
  color: #fff;
  background: #000;
}
.vCaption { padding: 10px; }

This can be kind of “scary” for beginners, but a quick walkthrough:

  • (A1 & A2) We set the gallery to show 3 videos per row on big screens, and 2 on the smaller screens.
  • (B1) Styles for the thumbnail videos, object-fit is the resize behavior. Change this to your own liking.
  • (B2) When the user clicks on a video, we will add a .full CSS class on it. This section simply sets the selected video to fill up the entire window.
  • (C) Well, show the “close video” button when there is a video playing on full screen.
  • (D) Cosmetics for the video captions.

 

 

2C) JAVASCRIPT

public/2c-gallery.js
var vplay = {
  // (A) INIT - CLICK VIDEO TO GO FULL SCREEN
  init : () => { for (let v of document.querySelectorAll(".gallery video")) {
    v.onclick = () => {
      if (!v.classList.contains("full")) { vplay.toggle(v); }
    };
  }},
 
  // (B) TOGGLE FULLSCREEN
  toggle : e => {
    // (B1) TOGGLE CLOSE BUTTON
    document.getElementById("vClose").classList.toggle("show");
 
    // (B2) TOGGLE VIDEO
    let v = e===false ? document.querySelector(".gallery .full") : e ;
    v.classList.toggle("full");
    v.controls = e===false ? false : true ;
    if (e===false) { v.pause(); }
  }
};
window.onload = vplay.init;

Finally, a bit of Javascript to drive the “toggle fullscreen video”.

  1. On window load, we get all videos – Click to play in fullscreen.
  2. This function simply adds the .full CSS on the selected video to set it to fullscreen; Removes the .full CSS class to revert.

 

EXTRAS

That’s all for the tutorial, and here is a small section on some extras and links that may be useful to you.

 

SORTING THE VIDEOS

Not a mystery, var videos in 1-server.js is an array containing the list of videos. Just use the native array sort functions to sort the list of videos.

  • videos.sort() In ascending order.
  • videos.sort().reverse() In descending order.
  • If you want a very specific sort order, you can pass a custom function into sort – videos.sort(MY-SORT-FUNCTION). You will have to do a search for “Javascript custom array sort” on your own… Or this tutorial will never end.

 

 

VIDEO FORMAT SUPPORT

Take note that not all browsers support all kinds of videos, the safest format at the time of writing is H.264 MP4. For a better list of supported videos, see the Wikipedia link below.

 

VIDEO THUMBNAIL IS NOT SHOWING

  • As above, not all browsers support all kinds of video formats.
  • Depending on the browser/Internet connection, the browser may decide to not preload any data.
  • You can encourage the browser to preload the metadata – <video preload="metadata">. No guarantees though, this is a recommendation, not a directive.
  • Alternatively, you can set an image as the video poster – <video poster="image.jpg">.

 

LINKS & REFERENCES

 

THE END

Thank you for reading, and we have come to the end. I hope that it has helped you to better understand, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!