Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python3
- import os, re, subprocess, time
- import urllib.request
- # Add valid domains here
- VALID_DOMAINS = [
- "files.catbox.moe",
- ]
- # Add valid sound extensions here
- VALID_SOUNDEXTS = [
- "mp3",
- "wav",
- "ogg",
- "m4a",
- ]
- # Wait this number of seconds between each file download, just so catbox doesn't whine because we're
- # downloading too much shit too fast. This might no be needed since calling ffmpeg to mix the final
- # file takes time on its own anyway so that already throttles our server calls
- THROTTLE = 0
- # The mixed file's extension
- OUTPUT_EXTENSION = "mp4"
- # You can specify the output codec here like -c:v libvpx-vp9, you can also add things like -crf here or the audio codec
- # if it's empty, ffmpeg will choose default values for the output extension I think
- #OUTPUT_CODEC = "-c:v libvpx-vp9" # For webm
- #OUTPUT_CODEC = "-c:v libx264" # For mp4
- OUTPUT_CODEC = ""
- # 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)
- if THROTTLE > 0:
- print(f"Waiting {THROTTLE} seconds")
- time.sleep(THROTTLE)
- song_length = get_song_length(soundfname)
- video_length = 0
- if(ext in ['mp4', 'webm']):
- video_length = get_song_length(file)
- # Because we have to use a different ffmpeg command depending on each case
- if(ext in ['jpg', 'png', 'jpeg']):
- # Simple case a static image and an mp3
- ffmpeg_cmd = f'ffmpeg -hide_banner -loop 1 -i {file} -i {soundfname} -t {song_length} {OUTPUT_CODEC} -vf "fps=25,format=yuv420p" out-{imgname}.{OUTPUT_EXTENSION}'
- elif ext == 'gif':
- # Gif and mp3
- ffmpeg_cmd = f'ffmpeg -ignore_loop 0 -i {file} -i {soundfname} -t {song_length} {OUTPUT_CODEC} -vf "fps=25,format=yuv420p" out-{imgname}.{OUTPUT_EXTENSION}'
- elif song_length > video_length:
- # Song is longer than video so we will loop video
- ffmpeg_cmd = f'ffmpeg -hide_banner -stream_loop -1 -i {file} -i {soundfname} -t {song_length} {OUTPUT_CODEC} -vf "fps=25,format=yuv420p" out-{imgname}.{OUTPUT_EXTENSION}'
- else:
- # Else song has the same length as video, presumably
- ffmpeg_cmd = f'ffmpeg -hide_banner -i "{file}" -i {soundfname} {OUTPUT_CODEC} out-{imgname}.{OUTPUT_EXTENSION}'
- os.system(ffmpeg_cmd)
- print("\n\nPress enter to exit")
- input()
Add Comment
Please, Sign In to add comment