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
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
PYTHON FLASK VIDEO GALLERY
All right, let us now get into the details of building a very simple video gallery with Python Flask.
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
# (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.
- Load the required modules and a couple of settings.
- Get a list of the video files in the
static
folder. - Pass the list of video files into the gallery HTML page.
- Start the HTTP server.
Yep, that’s all.
PART 2) GALLERY PAGE
2A) THE 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>
- When the user clicks on a video, it will play on full screen. This is just a close button to “minimize” it.
- Remember the list of videos above? We simply loop through it, and generate the respective
<video>
tags.
2B) THE 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
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
# 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/CAT1
,static/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)
- Use a dictionary, not a list –
- 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
- Python Flask
- Custom Video Player With Playlist – Code Boxx
- Free Videos – Pixabay | Pexels
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!