Av1an/main.py

95 lines
2.8 KiB
Python
Raw Normal View History

2020-01-08 00:39:49 +00:00
#!/usr/bin/python3
"""
mkvmerge required (python-pymkv)
2020-01-08 01:36:20 +00:00
ffmpeg required
TODO:
2020-01-08 22:43:20 +00:00
DONE make encoding queue with limiting by workers
DONE make concatenating videos after encoding
2020-01-08 01:36:20 +00:00
make passing your arguments for encoding,
2020-01-08 01:52:57 +00:00
make separate audio and encode it separately,
2020-01-08 00:39:49 +00:00
"""
2020-01-08 00:20:18 +00:00
import os
import subprocess
2020-01-08 20:44:44 +00:00
from multiprocessing import Pool
2020-01-08 18:56:47 +00:00
try:
import scenedetect
except:
print('ERROR: No PyScenedetect installed, try: sudo pip install scenedetect')
2020-01-08 00:20:18 +00:00
def get_cpu_count():
return os.cpu_count()
def get_ram():
return round((os.sysconf('SC_PAGE_SIZE') * os.sysconf('SC_PHYS_PAGES')) / (1024. ** 3), 3)
2020-01-08 22:43:20 +00:00
def extract_audio(input_vid):
cmd = f'ffmpeg -i {os.getcwd()}/{input_vid} -vn -acodec copy {os.getcwd()}/temp/audio.aac'
2020-01-08 00:39:49 +00:00
def split_video(input_vid):
2020-01-08 21:16:53 +00:00
cmd2 = f'scenedetect -i {input_vid} --output temp/split detect-content split-video -c'
2020-01-08 00:39:49 +00:00
subprocess.call(cmd2, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
2020-01-08 00:20:18 +00:00
2020-01-08 18:56:47 +00:00
def get_video_queue(source_path):
videos = []
for root, dirs, files in os.walk(source_path):
for file in files:
f = os.path.getsize(os.path.join(root, file))
videos.append([file, f])
videos = sorted(videos, key=lambda x: -x[1])
return videos
2020-01-08 20:44:44 +00:00
def encode(commands):
cmd = f'ffmpeg {commands}'
2020-01-08 22:43:20 +00:00
subprocess.Popen(cmd, shell=True).wait()
def concat():
"""
Using FFMPEG to concatenate all encoded videos to 1 file.
Reading all files in A-Z order and saving it to concat.txt
"""
with open(f'{os.getcwd()}/temp/concat.txt', 'w') as f:
2020-01-08 20:44:44 +00:00
2020-01-08 22:43:20 +00:00
for root, firs, files in os.walk(f'{os.getcwd()}/temp/encoded'):
for file in sorted(files):
f.write(f"file '{os.path.join(root, file)}'\n")
2020-01-08 20:44:44 +00:00
2020-01-08 22:43:20 +00:00
cmd = f'ffmpeg -f concat -safe 0 -i {os.getcwd()}/temp/concat.txt -c copy output.mp4'
subprocess.Popen(cmd, shell=True).wait()
2020-01-08 21:27:21 +00:00
2020-01-08 20:44:44 +00:00
def main(input_video):
2020-01-08 21:27:21 +00:00
# Make temporal directories
2020-01-08 21:16:53 +00:00
os.makedirs(f'{os.getcwd()}/temp/split', exist_ok=True)
os.makedirs(f'{os.getcwd()}/temp/encoded', exist_ok=True)
2020-01-08 21:27:21 +00:00
# Passing encoding parameters
2020-01-08 22:43:20 +00:00
# no audio av1 codec adding tiles speed quality
encoding_params = ' -an -c:v libaom-av1 -strict -2 -row-mt 1 -tiles 2x2 -cpu-used 8 -crf 60 '
2020-01-08 21:27:21 +00:00
# Spliting video and sorting big-first
2020-01-08 20:44:44 +00:00
split_video(input_video)
vid_queue = get_video_queue('temp')
files = [i[0] for i in vid_queue[:-1]]
2020-01-08 21:27:21 +00:00
# Making list of commands for encoding
2020-01-08 21:16:53 +00:00
commands = [f'-i {os.getcwd()}/temp/split/{file} {encoding_params} {os.getcwd()}/temp/encoded/{file}' for file in files]
2020-01-08 21:27:21 +00:00
# Creating threading pool to encode fixed amount of files at the same time
2020-01-08 22:43:20 +00:00
pool = Pool(6)
2020-01-08 20:44:44 +00:00
pool.map(encode, commands)
2020-01-08 22:43:20 +00:00
# Merging all encoded videos to 1
concat()
2020-01-08 20:44:44 +00:00
if __name__ == '__main__':
main('bruh.mp4')