Very Simple Video Gallery In Python Flask (Free Download)

Welcome to a tutorial on how to create a simple online video gallery with Python Flask. So you want to share some videos online, but don’t need all the “complex features”? Well, here’s a sharing of my simple version – Read on!

 

 

 

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

  • Create a virtual environment virtualenv venv and activate it – venv\Scripts\activate (Windows) venv/bin/activate (Linux/Mac)
  • Install required libraries – pip install flask
  • For those who are new, the default Flask folders are –
    • static Public files (JS/CSS/images/videos/audio)
    • templates HTML pages

 

PART 1) FLASK SERVER

S1_server.py
# (A) INIT
# (A1) LOAD MODULES
import os, glob
from flask import Flask, render_template
 
# (A2) FLASK SETTINGS + INIT
HOST_NAME = "localhost"
HOST_PORT = 80
PATH_BASE = os.path.dirname(os.path.abspath(__file__))
PATH_STATIC = os.path.join(PATH_BASE, "static")
app = Flask(__name__)
# app.debug = True
 
# (B) GET ALL VIDEO FILES
videos = []
for ext in ("avi", "mp4", "webm"):
  for vid in glob.iglob(PATH_STATIC + "/*." + ext):
    videos.append(os.path.basename(vid))
 
# (C) GALLERY PAGE
@app.route("/")
def index():
  return render_template("S2A_gallery.html", videos=videos)
 
# (D) START
if __name__ == "__main__":
  app.run(HOST_NAME, HOST_PORT)

Some beginners may panic, but keep calm and look closely.

  1. Load the required modules and a couple of settings.
  2. Get a list of the video files in the static folder.
  3. Pass the list of video files into the gallery HTML page.
  4. Start the HTTP server.

Yep, that’s all.

 

 

PART 2) GALLERY PAGE

2A) THE HTML

templates/S2A_gallery.html
<!-- (A) CLOSE FULLSCREEN VIDEO -->
<div id="vClose" onclick="vplay.toggle(false)">X</div>
 
<!-- (B) VIDEO GALLERY -->
<div class="gallery">
  {% for vid in videos: %}
  <div class="vWrap">
    <video src="static/{{ vid }}"></video>
    <div class="vCaption">{{ vid }}</div>
  </div>
  {% endfor %}
</div>
  1. When the user clicks on a video, it will play on full screen. This is just a close button to “minimize” it.
  2. Remember the list of videos above? We simply loop through it, and generate the respective <video> tags.

 

2B) THE CSS

static/S2B_gallery.css
/* (A) GALLERY WRAPPER */
/* (A1) BIG SCREENS - 3 IMAGES PER ROW */
.gallery {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 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, minmax(0, 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; }

Yikes. That’s quite a lot of CSS, but just a few noteworthy mechanics here:

  • (A1) grid-template-columns We lay 3 videos per row on big screens, 2 on small screens.
  • (B1 & B2)  object-fit Controls the resize behavior of the video. Change the values and see which one works for you.
  • (B2 & C) When the user clicks on a video, we add a .full CSS class on it. These should be obvious enough – We set the video to cover the entire window and show the close button.

 

 

2C) THE JAVASCRIPT

static/S2C_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, just a little bit of Javascript – Toggle the .full CSS class on the video when the user clicks on it.

 

 

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 VIDEO

S1_server.py
# SORT IN ASCENDING ORDER
videos.sort()
 
# SORT IN DESCENDING ORDER
videos.sort(reverse=True)

As you can see, videos is only a simple list. Just use the sort() function to sort in ascending or descending order. If you need “very specific sort order”, you will have to do your own research on “Python list custom sort”… Or this tutorial will never end.

 

CATEGORIES/SECTIONS

There is no database to store category data, so one simple way is to create multiple sub-folders in static. Quick pseudo-code and example:

  • static/CAT1static/CAT2, etc…
  • Modify S1_server.py.
    • Use a dictionary, not a list – videos = { CAT1 : [], CAT2 : [] }
    • for (cat in ("CAT1", "CAT2")): EXTRACT VIDEOS AS USUAL - videos[cat].append(VID)
  • Modify S2A_gallery.html –
    • for cat in videos : <h1>{{ cat }}</h1>
    • <div class="gallery">{{ for vid in cat: draw <video> as usual }}</div>

 

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!