Hello Folks,
There are many reddit video downloaders available in the github that may seems easy to work on. However, unless you get some paid API, most of them are unusable.
So, I thought why not break the regular way of making a downloader and do something new.
Here you are going to get the easiest code ever to download reddit video.
You need:
A Framework (fast/flask), I will show with flask but you can make it in your way.
FFMPEG to convert the video and render the final output which will have both audio and video.
Find the Video Link From Reddit URL
If you go to any link with video from reddit and put .json on it you will get this kinda page which has all the data you need
From here you can find the video url in the
data["data"]["children"][0]["data"]["secure_media"]["reddit_video"]["fallback_url"]
in this location.
Well this url has the video but no audio, so what reddit does is create a HLSplaylist in m3u8 format to store audio and video both format which is not a proper format to download the video in usable format.
Here comes the ffmpeg part. Using ffmpeg we will be able to convert that into mp4
So here is the full flask code that you need
from flask import Flask, render_template, request, send_file
import requests
import os
import time
import threading
import ffmpeg
from urllib.parse import urlparse, urlunparse
app = Flask(__name__)
def download_video(giveurl):
parsed_url = urlparse(giveurl)
parsed_url = parsed_url._replace(path=parsed_url.path + '/')
url = urlunparse(parsed_url) + ".json"
headers = {
"User-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.74 Safari/537.36"
}
try:
for retry in range(5):
try:
r = requests.get(url, headers=headers, timeout=20)
r.raise_for_status()
data = r.json()[0]
video_url = data["data"]["children"][0]["data"]["secure_media"]["reddit_video"]["fallback_url"]
title = data["data"]["children"][0]["data"]["title"]
final_url = "https://v.redd.it/" + video_url.split("/")[3]+'/HLSPlaylist.m3u8'
output_filename = f"{title}.mp4"
ffmpeg.input(final_url).output(output_filename, codec="copy").run()
return output_filename
except (requests.RequestException, ValueError) as e:
if retry < 4:
time.sleep(2)
else:
return None
except KeyboardInterrupt:
return None
@app.route("/", methods=["GET", "POST"])
def index():
if request.method == "POST":
giveurl = request.form.get("giveurl")
if giveurl:
output_filename = download_video(giveurl)
if output_filename:
return render_template("index.html", output_filename=output_filename)
else:
return "An error occurred during download."
return render_template("index.html")
def delete_file_after_delay(file_path, delay_seconds):
try:
time.sleep(delay_seconds)
os.remove(file_path)
except Exception as e:
print(f"Error deleting file: {e}")
@app.route("/download/<filename>")
def download(filename):
file_path = os.path.join(app.root_path, filename)
delete_thread = threading.Thread(target=delete_file_after_delay, args=(file_path, 300))
delete_thread.daemon = True
delete_thread.start()
return send_file(file_path, as_attachment=True)
if __name__ == "__main__":
app.run(debug=True)
And a simple html to show a download form.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Reddit Video Downloader</title>
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="bg-light">
<div class="container py-5">
<div class="row justify-content-center">
<div class="col-md-6">
<div class="card shadow-lg border-0 rounded-3">
<div class="card-body p-4">
<h1 class="text-center mb-4 text-primary">Reddit Video Downloader</h1>
<form method="post">
<div class="mb-3">
<label for="giveurl" class="form-label">Enter Reddit Video URL:</label>
<input type="text" id="giveurl" name="giveurl" class="form-control" placeholder="Paste Reddit video link here..." required>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-primary btn-lg">Download</button>
</div>
</form>
{% if output_filename %}
<div class="alert alert-success mt-4 text-center">
✅ Video downloaded successfully!
</div>
<div class="d-grid">
<a href="{{ url_for('download', filename=output_filename) }}" class="btn btn-success btn-lg">Download Your Video</a>
</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
<!-- Bootstrap JS (optional, for components like modal/tooltips if needed) -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
Here is the github link if you want to just clone and use..
Top comments (0)