Some checks failed
Build and Push Docker Image / build-and-push (push) Has been cancelled
76 lines
3.0 KiB
Python
76 lines
3.0 KiB
Python
import sys
|
|
import json
|
|
import subprocess
|
|
import os
|
|
import argparse
|
|
|
|
def download_and_crop(url, output_dir, start_time=None, end_time=None):
|
|
try:
|
|
os.makedirs(output_dir, exist_ok=True)
|
|
|
|
# Get video info
|
|
info_cmd = ["yt-dlp", "-J", url]
|
|
result = subprocess.run(info_cmd, capture_output=True, text=True, check=True)
|
|
info = json.loads(result.stdout)
|
|
|
|
# We will download the best single file with audio and video, or just let yt-dlp decide
|
|
video_id = info.get("id", "unknown")
|
|
title = info.get("title", "video").replace("/", "_").replace("\\", "_")
|
|
# Ensure ascii or keep some safe unicode
|
|
safe_title = "".join([c for c in title if c.isalpha() or c.isdigit() or c in (' ', '-', '_')]).rstrip()
|
|
filename = f"{safe_title}_{video_id}.mp4"
|
|
filepath = os.path.join(output_dir, filename)
|
|
|
|
# Construct download options
|
|
# We use ffmpeg to crop if start/end times are provided
|
|
if start_time or end_time:
|
|
# Using yt-dlp's native download range features to avoid full download if possible
|
|
# OR pass postprocessor args
|
|
download_args = [
|
|
"yt-dlp",
|
|
"-f", "bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best",
|
|
"--merge-output-format", "mp4",
|
|
"-o", filepath,
|
|
]
|
|
|
|
post_args = []
|
|
if start_time:
|
|
post_args.extend(["-ss", start_time])
|
|
if end_time:
|
|
post_args.extend(["-to", end_time])
|
|
|
|
if post_args:
|
|
download_args.extend(["--downloader", "ffmpeg", "--downloader-args", f"ffmpeg:{' '.join(post_args)}"])
|
|
|
|
download_args.append(url)
|
|
else:
|
|
download_args = [
|
|
"yt-dlp",
|
|
"-f", "bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best",
|
|
"--merge-output-format", "mp4",
|
|
"-o", filepath,
|
|
url
|
|
]
|
|
|
|
# Execute
|
|
subprocess.run(download_args, check=True)
|
|
|
|
print(json.dumps({"status": "success", "filepath": filepath, "title": title}))
|
|
return True
|
|
except subprocess.CalledProcessError as e:
|
|
print(json.dumps({"status": "error", "message": f"Command failed: {e.stderr or e.output}"}))
|
|
return False
|
|
except Exception as e:
|
|
print(json.dumps({"status": "error", "message": str(e)}))
|
|
return False
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser(description="Download and crop media via yt-dlp")
|
|
parser.add_argument("--url", required=True, help="Media URL")
|
|
parser.add_argument("--outdir", required=True, help="Output directory")
|
|
parser.add_argument("--start", help="Start time (hh:mm:ss)")
|
|
parser.add_argument("--end", help="End time (hh:mm:ss)")
|
|
|
|
args = parser.parse_args()
|
|
download_and_crop(args.url, args.outdir, args.start, args.end)
|