Newer
Older
VideoConverter / src / main.py
@yangyang xie yangyang xie on 19 Jun 2021 2 KB first commit
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)