diff --git a/FFMpeg-Compressor/ffmpeg-comp.toml b/FFMpeg-Compressor/ffmpeg-comp.toml index 9f117bb..800584d 100644 --- a/FFMpeg-Compressor/ffmpeg-comp.toml +++ b/FFMpeg-Compressor/ffmpeg-comp.toml @@ -2,14 +2,14 @@ FFmpegParams = "-hide_banner -loglevel error" [AUDIO] -Extension = "mp3" +Extension = "original" BitRate = "320k" [IMAGE] -Extension = "jpg" -CompLevel = 100 +Extension = "original" +CompLevel = 20 JpegComp = 3 [VIDEO] -Extension = "webm" +Extension = "original" Codec = "libvpx-vp9" diff --git a/FFMpeg-Compressor/main.py b/FFMpeg-Compressor/main.py index 3a14022..c410721 100755 --- a/FFMpeg-Compressor/main.py +++ b/FFMpeg-Compressor/main.py @@ -23,11 +23,23 @@ printer.bar_init(orig_folder) if os.path.exists(f"{orig_folder}_compressed"): shutil.rmtree(f"{orig_folder}_compressed") + printer.info("Creating folders...") for folder, folders, files in os.walk(orig_folder): if not os.path.exists(folder.replace(orig_folder, f"{orig_folder}_compressed")): os.mkdir(folder.replace(orig_folder, f"{orig_folder}_compressed")) printer.info(f"Compressing \"{folder.replace(orig_folder, orig_folder.split('/').pop())}\" folder...") - compressor.compress(orig_folder, folder) + target_folder = folder.replace(orig_folder, f"{orig_folder}_compressed") + for file in os.listdir(folder): + if os.path.isfile(f'{folder}/{file}'): + match compressor.get_file_type(file): + case "audio": + compressor.compress_audio(folder, file, target_folder) + case "image": + compressor.compress_image(folder, file, target_folder) + case "video": + compressor.compress_video(folder, file, target_folder) + case "unknown": + compressor.compress(folder, file, target_folder) utils.get_compression_status(orig_folder) diff --git a/FFMpeg-Compressor/modules/compressor.py b/FFMpeg-Compressor/modules/compressor.py index 5f3d959..1022d97 100644 --- a/FFMpeg-Compressor/modules/compressor.py +++ b/FFMpeg-Compressor/modules/compressor.py @@ -1,25 +1,39 @@ from modules import printer +from modules import configloader from PIL import Image -import tomllib import os -audio_exts = ['.aac', '.flac', '.m4a', '.mp3', '.ogg', '.opus', '.raw', '.wav', '.wma'] -image_exts = ['.apng', '.avif', '.jfif', '.pjpeg', '.pjp', '.svg', '.webp', '.jpg', '.jpeg', '.png', '.raw'] -video_exts = ['.3gp' '.amv', '.avi', '.gif', '.m4v', '.mkv', '.mov', '.mp4', '.m4v', '.mpeg', '.mpv', '.webm', '.ogv'] -try: - config = tomllib.load(open("ffmpeg-comp.toml", "rb")) -except FileNotFoundError: - try: - config = tomllib.load(open("/etc/ffmpeg-comp.toml", "rb")) - except FileNotFoundError: - printer.error("Config file not found. Please put it next to binary or in to /etc folder.") - exit() +def get_req_ext(file): + if configloader.config['AUDIO']['Extension'] == "original" or \ + configloader.config['IMAGE']['Extension'] == "original" or \ + configloader.config['VIDEO']['Extension'] == "original": + return os.path.splitext(file)[1][1:] -ffmpeg_params = config['FFMPEG']['FFmpegParams'] -req_audio_ext = config['AUDIO']['Extension'] -req_image_ext = config['IMAGE']['Extension'] -req_video_ext = config['VIDEO']['Extension'] + match get_file_type(file): + case "audio": + return configloader.config['AUDIO']['Extension'] + case "image": + return configloader.config['IMAGE']['Extension'] + case "video": + return configloader.config['VIDEO']['Extension'] + + +def get_file_type(file): + audio_ext = ['.aac', '.flac', '.m4a', '.mp3', '.ogg', '.opus', '.raw', '.wav', '.wma'] + image_ext = ['.apng', '.avif', '.jfif', '.pjpeg', '.pjp', '.svg', '.webp', '.jpg', '.jpeg', '.png', '.raw'] + video_ext = ['.3gp' '.amv', '.avi', '.gif', '.m4v', '.mkv', '.mov', '.mp4', '.m4v', '.mpeg', '.mpv', '.webm', + '.ogv'] + file_extension = os.path.splitext(file)[1] + + if file_extension in audio_ext: + return "audio" + elif file_extension in image_ext: + return "image" + elif file_extension in video_ext: + return "video" + else: + return "unknown" def has_transparency(img): @@ -38,43 +52,45 @@ def has_transparency(img): return False -def compress(root_folder, folder): - target_folder = folder.replace(root_folder, f"{root_folder}_compressed") - for file in os.listdir(folder): - if os.path.isfile(f'{folder}/{file}'): - if os.path.splitext(file)[1] in audio_exts: +def compress_audio(folder, file, target_folder): + ffmpeg_params = configloader.config['FFMPEG']['FFmpegParams'] + bitrate = configloader.config['AUDIO']['BitRate'] - bitrate = config['AUDIO']['BitRate'] - printer.files(file, os.path.splitext(file)[0], req_audio_ext, f"{bitrate}bit/s") - os.system(f"ffmpeg -i '{folder}/{file}' {ffmpeg_params} " - f"'{target_folder}/{os.path.splitext(file)[0]}.{req_audio_ext}'") + printer.files(file, os.path.splitext(file)[0], get_req_ext(file), f"{bitrate}") + os.system(f"ffmpeg -i '{folder}/{file}' {ffmpeg_params} -q:a {bitrate} " + f"'{target_folder}/{os.path.splitext(file)[0]}.{get_req_ext(file)}'") - elif os.path.splitext(file)[1] in image_exts: - if req_image_ext == "jpg" or req_image_ext == "jpeg": +def compress_video(folder, file, target_folder): + ffmpeg_params = configloader.config['FFMPEG']['FFmpegParams'] + codec = configloader.config['VIDEO']['Codec'] - if not has_transparency(Image.open(f'{folder}/{file}')): - jpg_comp = config['IMAGE']['JpegComp'] - printer.files(file, os.path.splitext(file)[0], req_image_ext, f"level {jpg_comp}") - os.system(f"ffmpeg -i '{folder}/{file}' {ffmpeg_params} -q {jpg_comp} " - f"'{target_folder}/{os.path.splitext(file)[0]}.{req_image_ext}'") + printer.files(file, os.path.splitext(file)[0], get_req_ext(file), codec) + os.system(f"ffmpeg -i '{folder}/{file}' {ffmpeg_params} -vcodec {codec} " + f"'{target_folder}/{os.path.splitext(file)[0]}.{get_req_ext(file)}'") - else: - printer.warning(f"{file} has transparency (.jpg not support it). Skipping...") - else: - comp_level = config['IMAGE']['CompLevel'] - printer.files(file, os.path.splitext(file)[0], req_image_ext, f"{comp_level}%") - os.system(f"ffmpeg -i '{folder}/{file}' {ffmpeg_params} -compression_level {comp_level} " - f"'{target_folder}/{os.path.splitext(file)[0]}.{req_image_ext}'") +def compress_image(folder, file, target_folder): + ffmpeg_params = configloader.config['FFMPEG']['FFmpegParams'] + comp_level = configloader.config['IMAGE']['CompLevel'] + jpg_comp = configloader.config['IMAGE']['JpegComp'] - elif os.path.splitext(file)[1] in video_exts: - codec = config['VIDEO']['Codec'] - printer.files(file, os.path.splitext(file)[0], req_video_ext, codec) - os.system(f"ffmpeg -i '{folder}/{file}' {ffmpeg_params} -vcodec {codec} " - f"'{target_folder}/{os.path.splitext(file)[0]}.{req_video_ext}'") + if get_req_ext(file) == "jpg" or get_req_ext(file) == "jpeg": - else: - printer.warning("File extension not recognized. This may affect the quality of the compression.") - printer.unknown_file(file) - os.system(f"ffmpeg -i '{folder}/{file}' {ffmpeg_params} '{target_folder}/{file}'") + if not has_transparency(Image.open(f'{folder}/{file}')): + printer.files(file, os.path.splitext(file)[0], get_req_ext(file), f"level {jpg_comp}") + os.system(f"ffmpeg -i '{folder}/{file}' {ffmpeg_params} -q {jpg_comp} " + f"'{target_folder}/{os.path.splitext(file)[0]}.{get_req_ext(file)}'") + else: + printer.warning(f"{file} has transparency (.jpg not support it). Skipping...") + else: + printer.files(file, os.path.splitext(file)[0], get_req_ext(file), f"{comp_level}%") + os.system(f"ffmpeg -i '{folder}/{file}' {ffmpeg_params} -compression_level {comp_level} " + f"'{target_folder}/{os.path.splitext(file)[0]}.{get_req_ext(file)}'") + + +def compress(folder, file, target_folder): + ffmpeg_params = configloader.config['FFMPEG']['FFmpegParams'] + printer.warning("File extension not recognized. This may affect the quality of the compression.") + printer.unknown_file(file) + os.system(f"ffmpeg -i '{folder}/{file}' {ffmpeg_params} '{target_folder}/{file}'") diff --git a/FFMpeg-Compressor/modules/configloader.py b/FFMpeg-Compressor/modules/configloader.py new file mode 100644 index 0000000..1a4db0b --- /dev/null +++ b/FFMpeg-Compressor/modules/configloader.py @@ -0,0 +1,11 @@ +import tomllib +from modules import printer + +try: + config = tomllib.load(open("ffmpeg-comp.toml", "rb")) +except FileNotFoundError: + try: + config = tomllib.load(open("/etc/ffmpeg-comp.toml", "rb")) + except FileNotFoundError: + printer.error("Config file not found. Please put it next to binary or in to /etc folder.") + exit()