#!/usr/bin/env python3 import os, re, subprocess import urllib.request # Add valid domains here VALID_DOMAINS = [ "files.catbox.moe", ] # Add valid sound extensions here VALID_SOUNDEXTS = [ "mp3", "wav", ] # The mixed file's extension OUTPUT_EXTENSION = "mp4" # Don't mess with this VALID_FILENAME = r"(.+)\[sound=((?:https%3A%2F%2F)?(?:" + "|".join(VALID_DOMAINS) + ")%2F(.+\.(?:" + "|".join(VALID_SOUNDEXTS) + ")))\]\.(png|gif|jpeg|webm|mp4|jpg)" def urldecode(text): def subfunc(el): return chr(int(el[0][1:], 16)) return re.sub("%[\da-fA-F]{2}", subfunc, text) # Check if we can call a program with os.system() def program_exists(prog_name): if os.name == 'nt': # for Windows syscall = f"WHERE {prog_name}" ret, err = subprocess.Popen(syscall, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() if os.name == 'posix': # for Linux syscall = f"which {prog_name}" ret, err = subprocess.Popen(syscall, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicate() if err or not ret: return False return True def download_soundfile(url, filename): headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.5756.197 Safari/537.36', 'Accept-Encoding': 'deflate', 'Accept-Language': 'en-US,en;q=0.5', 'Cache-Control' : 'no-cache', } req = urllib.request.Request(url, headers=headers) data = urllib.request.urlopen(req) with open(filename,'wb') as output: output.write(data.read()) def system_call(cmd): if os.name == 'nt': # for Windows ret, err = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() if os.name == 'posix': # for Linux ret, err = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicate() return ret, err def get_song_length(fname): cmd = f'ffprobe -hide_banner "{fname}"' # For some reason ffprobe returns data in err ret, err = system_call(cmd) res = re.findall("Duration: (\d+:\d{2}:\d{2}(?:\.\d+))", err.decode('utf-8')) if not res: return None tmp = res[0].split(":") hours, minutes, seconds = int(tmp[0]), int(tmp[1]), float(tmp[2]) return (hours * 3600) + (minutes * 60) + seconds # Check if we have ffmpeg if not program_exists("ffmpeg"): print("ffmpeg couldn't be found") exit() for file in os.listdir(): res = re.match(VALID_FILENAME, file) if not res: continue imgname, soundurl, soundfname, ext = res[1], urldecode(res[2]), res[3], res[4] if not soundurl.startswith("https://"): soundurl = "https://" + soundurl if not os.path.exists(soundfname): print(f"File {soundfname} does not exist, downloading") download_soundfile(soundurl, soundfname) song_length = get_song_length(soundfname) video_length = 0 if(ext in ['mp4', 'webm']): video_length = get_song_length(file) ffmpeg_cmd = f'ffmpeg -hide_banner -i "{file}" -i {soundfname} out-{imgname}.{OUTPUT_EXTENSION}' os.system(ffmpeg_cmd)