From a5e9c3089b6ee9d7c75f34a7b7cf7e7c24a0fde8 Mon Sep 17 00:00:00 2001 From: nin0dev Date: Sat, 22 Jun 2024 14:52:41 -0400 Subject: [PATCH] Added videobundler --- videobundler/.env.example | 4 +++ videobundler/README.md | 25 +++++++++++++++ videobundler/main.py | 64 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+) create mode 100644 videobundler/.env.example create mode 100644 videobundler/README.md create mode 100644 videobundler/main.py diff --git a/videobundler/.env.example b/videobundler/.env.example new file mode 100644 index 00000000..e226afe4 --- /dev/null +++ b/videobundler/.env.example @@ -0,0 +1,4 @@ +TIME_BEFORE_DELETE=30 +PORT=45872 +# DO NOT PUT A / AT THE END OF THE URL +PROXY_URL=https://eu-proxy.poketube.fun \ No newline at end of file diff --git a/videobundler/README.md b/videobundler/README.md new file mode 100644 index 00000000..c1ea44a4 --- /dev/null +++ b/videobundler/README.md @@ -0,0 +1,25 @@ +# poke-videobundler + +Takes 2 input streams, downloads them, and spits out a combined file. + +## Installation + +1. Make sure `ffmpeg`, `wget`, and Python 3 are all installed. +2. Download the program files to your computer - `main.py` and `.env.example`. +3. Run `python3 -m pip install flask python-dotenv waitress`. + +## Configuration + +1. Run `mv .env.example .env`, **even if you don't want to configure anything**. +2. Edit and fill in the values if needed. + +## Usage + +1. `python3 main.py`. +2. If everything went well, you shouldn't see any output at launch. +3. You will now be able to call the server at the configured port. + +## Endpoints + +- `/`: Will return `{success:true}` if alive. +- `/get_merged_video?id=VIDEO_ID&audio_itag=AUDIO_ITAG&video_itag=VIDEO_ITAG`: Returns a merged video. ID is the youtube video ID, and itags are self explanatory. diff --git a/videobundler/main.py b/videobundler/main.py new file mode 100644 index 00000000..a8d662f2 --- /dev/null +++ b/videobundler/main.py @@ -0,0 +1,64 @@ +from datetime import datetime +from dotenv import load_dotenv +from flask import Flask, request, Response, send_file +from threading import Thread +from time import sleep + +import io +import json +import os +import random +import string +import subprocess +import uuid + +load_dotenv() + +app = Flask(__name__) + +def autodelete(job_id: str): + sleep(os.getenv("TIME_BEFORE_DELETE")) + os.remove(f"{job_id}.mp4") + os.remove(f"{job_id}.m4a") + os.remove(f"output.{job_id}.mp4") + +def get_random_string(length): + # choose from all lowercase letter + letters = string.ascii_lowercase + result_str = "".join(random.choice(letters) for i in range(length)) + return result_str + +@app.route("/") +def ping(): + return json.loads(""" + { + "success": true + } + """) + +@app.route("/get_merged_video") +def get_merged_video(): + pwd = os.getcwd() + video_id = request.args.get("id") + job_id = get_random_string(10) + audio_itag = request.args.get("audio_itag") + video_itag = request.args.get("video_itag") + # Download both audio and video + subprocess.run(["wget", f"-O{job_id}.m4a", f"{os.getenv("PROXY_URL")}/latest_version?id={video_id}&itag={audio_itag}&local=true"], check=True) + subprocess.run(["wget", f"-O{job_id}.mp4", f"{os.getenv("PROXY_URL")}/latest_version?id={video_id}&itag={video_itag}&local=true"], check=True) + # Merge both files + subprocess.run(f"ffmpeg -i {pwd}/{job_id}.m4a -i {pwd}/{job_id}.mp4 -c copy {pwd}/output.{job_id}.mp4", shell=True, check=True) + thread = Thread(target=autodelete, args = (job_id, )) + thread.start() + with open(f"output.{job_id}.mp4", "rb") as bytes: + return send_file( + io.BytesIO(bytes.read()), + mimetype="video/mp4", + download_name=f"output.{job_id}.mp4", + as_attachment=True + ) + + +if __name__ == "__main__": + from waitress import serve + serve(app, host="0.0.0.0", port=os.getenv("PORT")) \ No newline at end of file