import os import glob import ffmpeg from subprocess import PIPE, run, Popen import re import threading import time # Global variable to store the movie file being processed inprogress_file = "" def shell_command(command): process = Popen(command, stdout=PIPE, stderr=PIPE, universal_newlines=True, shell=True) return process.communicate() def is_video_unsupported(file: str): output = shell_command("ffmpeg -i '"+file + "' -f ffmetadata") video_metadata_search = re.search('Video:(.*)\n', output[1], re.IGNORECASE) video_metadata = "" if video_metadata_search: video_metadata = video_metadata_search.group(1) if(video_metadata.find("progressive") != -1): return True return False def get_file_size(file: str): if not os.path.exists(file): return "N/A", 0 total_bytes = os.path.getsize(file) total_kbs = int(total_bytes / 1024) total_mbs = int(total_kbs / 1024) total_gbs = int(total_mbs / 1024) return "{}G{}M".format((total_gbs % 1024), (total_mbs % 1024)), total_bytes def retrieve_unsupported_videos(path): files = glob.glob(path + '/**/*.mp4', recursive=True) unsupported_videos = [] for file in files: if file.find("@eaDir") == -1 and is_video_unsupported(file): unsupported_videos.append(file) return unsupported_videos def convert_movie_to_mp4(file: str): temp_file = file + "_inprogress.mp4" global inprogress_file inprogress_file = temp_file output = shell_command("ffmpeg -i '"+file+"' -qscale 0 '"+temp_file+"'") if os.path.exists(temp_file) and not is_video_unsupported(temp_file): original_size, _ = get_file_size(file) new_size, _ = get_file_size(temp_file) print("Succeeds to convert the {} file to mp4, size changed from {} to {}".format( file, original_size, new_size)) try: os.remove(file) os.rename(temp_file, file) except OSError as e: print("Error: %s : %s" % (file, e.strerror)) return False return True else: print("Fails to convert the {} file to mp4 due to the error {}".format( file, output)) return False def stat_tracker(): while True: global inprogress_file if inprogress_file != "" and os.path.exists(inprogress_file): file = inprogress_file.replace("_inprogress.mp4", "") original_readable_size, original_raw = get_file_size(file) new_readable_size, new_raw = get_file_size(inprogress_file) print("Converting {}: {:.0%} - ({} / {})".format(file, (new_raw / original_raw), new_readable_size, original_readable_size)) time.sleep(175) time.sleep(5) if __name__ == "__main__": threading.Thread(target=stat_tracker, daemon=True).start() movies = retrieve_unsupported_videos("/nas/video") for movie in movies: convert_movie_to_mp4(movie)