Last active
April 8, 2019 14:24
-
-
Save nkrabben/9576531b16787ee23c5cb38765b1d3c9 to your computer and use it in GitHub Desktop.
PAL/NTSC aware v210/MOV to FFV1/MKV recipe
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env/python | |
import os | |
import argparse | |
import subprocess | |
import multiprocessing | |
### For extra utitily when running this script remotely | |
# nohup transcode.py -d directory/of/mov -e mov -o directory/of/future/mkv & | |
# The & puts the job in the background | |
# The nohup autologs ffmpeg output to a nohup.out file and keeps the process alive even when the ssh session stops | |
# Turn into command line script | |
def _make_parser(): | |
parser = argparse.ArgumentParser() | |
parser.description = "survey designated folder and child folders for files by extensions" | |
parser.add_argument("-d", "--directory", | |
help = "path of directory to survey", | |
required = True | |
) | |
parser.add_argument("-e", "--extension", | |
help = "type of extension to find", | |
required = True | |
) | |
parser.add_argument("-o", "--output", | |
help = "directory to store stuff", | |
required = True | |
) | |
return parser | |
# Create ffmpeg recipe based on height of video | |
def get_transcode_video_cmd(fn, height, output): | |
ffv1_command = [ | |
'ffmpeg', | |
'-vsync', '0', | |
'-i', fn, | |
'-map', '0', | |
'-dn', | |
'-c:v', 'ffv1', | |
'-level', '3', | |
'-coder', '1', | |
'-context', '1', | |
'-g', '1', | |
'-slicecrc', '1', | |
'-slices', '24', | |
'-c:a', 'flac', | |
] | |
if height == '486': | |
ffv1_command += [ | |
'-field_order', 'bt', | |
'-vf', 'setfield=bff,setdar=4/3', | |
'-color_primaries', 'smpte170m', | |
'-color_range', 'tv', | |
'-color_trc', 'bt709', | |
'-colorspace', 'smpte170m', | |
] | |
if height == '576': | |
ffv1_command += [ | |
'-field_order', 'tb', | |
'-vf', 'setfield=tff,setdar=4/3', | |
'-color_primaries', 'bt470bg', | |
'-color_range', 'tv', | |
'-color_trc', 'bt709', | |
'-colorspace', 'bt470bg', | |
] | |
ffv1_command += [os.path.join(output, os.path.splitext(os.path.basename(fn))[0] + '.mkv',)] | |
return ffv1_command | |
# function to run the ffmpeg command | |
def work(cmd): | |
subprocess.check_call(cmd) | |
return | |
# This is where the script actually starts | |
def main(): | |
# Get the arguments entered on the command line | |
args = _make_parser().parse_args() | |
# Create a list to hold a whole bunch of transcode commands | |
queue = [] | |
# Generate a command for every file in a directory that matches the extension. | |
for dirpath, dirnames, filenames in os.walk(args.directory): | |
for filename in [f for f in filenames if f.endswith(args.extension)]: | |
# Make sure to use full path so we don't deal with working directory hijinks | |
full_path = os.path.join(dirpath, filename) | |
# Run MediaInfo to check height of video (and so NTSCness or PALness) | |
# Might be good to use pymediainfo in the future, but .rstrip().decode('UTF-8') works well enough to get the data we want | |
height = subprocess.check_output( | |
['mediainfo', '--Language=raw', '--Full', | |
"--Inform=Video;%Height%", full_path]).rstrip().decode('UTF-8') | |
# Use the input file name, height, and output path to generate an ffmpeg command, and then append that line to the list | |
queue.append(get_transcode_video_cmd(full_path, height, args.output)) | |
# Quick sanity check for fun | |
print(queue) | |
# Use multiprocess to manage the queue of transcode work. | |
# It will take one command from the list at-a-time, run the command, and on completion take the next one | |
# ffmpeg already know how to parallize work well, so it's probably not useful to use processes= >1 | |
pool = multiprocessing.Pool(processes=1) | |
r = pool.map_async(work, queue) | |
r.wait() | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment