diff --git a/convert_to_dnx.py b/convert_to_dnx.py index 9480f41..eec7fdd 100644 --- a/convert_to_dnx.py +++ b/convert_to_dnx.py @@ -22,8 +22,6 @@ import pprint # https://askubuntu.com/questions/907398/how-to-convert-a-video-with-ffmpeg-into-the-dnxhd-dnxhr-format # https://en.wikipedia.org/wiki/List_of_Avid_DNxHD_resolutions - - # Resolution,Frame Width, Frame Height,Chroma Subsampling,Bits,Frames Per Second,Megabits per second,Minutes per Gigabyte dnx_rates = """Avid DNxHD 440x,1920,1080,p,yuv422p10,60/1,440,0.325 @@ -94,6 +92,7 @@ Avid DNxHD 45,1280,720,p,yuv422p,24000/1001,43,3.504 + available_dnx_resolutions = [] dnx_reader = csv.DictReader(io.StringIO(dnx_rates), ["name","width","height","interlaced", @@ -105,9 +104,12 @@ for res in dnx_reader: available_dnx_resolutions = sorted(available_dnx_resolutions, key=lambda x: float(x["mins_per_gig"]), reverse=True) -# ffmpeg -loglevel error -f lavfi -i testsrc2 -c:v dnxhd -f null - +print(f"Loaded {len(available_dnx_resolutions)} available DNxHD resolutions...") -result = subprocess.run(["/usr/local/bin/ffmpeg", + +print(f"Detecting available DNxHD codecs...") + +result = subprocess.run(["ffmpeg", "-hide_banner", "-loglevel", "error", @@ -121,20 +123,20 @@ result = subprocess.run(["/usr/local/bin/ffmpeg", "null", "-"], capture_output=True) -# result.check_returncode() - ffmpeg_dnx_resolutions = [] for line in result.stderr.splitlines(): line = line.decode("utf-8") - matches = re.match(".*Frame size: (\d+)x(\d+)([pi]).*", line) + matches = re.match(r".*Frame size: (\d+)x(\d+)([pi]).*", line) if matches is not None: width, height = matches[1], matches[2] interlace = matches[3] - matches = re.match(".*format: (yuv\w+).*", line) + matches = re.match(r".*format: (yuv\w+).*", line) + assert matches fmt = matches[1] - matches = re.match(".*bitrate: (\d+)Mbps.*", line) + matches = re.match(r".*bitrate: (\d+)Mbps.*", line) + assert matches mbps = matches[1] ffmpeg_dnx_resolutions += [{ @@ -145,17 +147,16 @@ for line in result.stderr.splitlines(): "interlaced": interlace }] +print(f"Detected {len(ffmpeg_dnx_resolutions)} codec resolutions...") + def filter_pred(res): def inner_pred(ff_res): - # print(res, ff_res) - # input("Press return...") result = ff_res["interlaced"] == res["interlaced"] and \ ff_res["width"] == res["width"] and \ ff_res["height"] == res["height"] and \ ff_res["pix_fmt"] == res["pix_fmt"] and \ ff_res["mb"] == res["mb"] - # print("Result", result) return result found = filter(inner_pred,ffmpeg_dnx_resolutions) @@ -163,10 +164,11 @@ def filter_pred(res): available_dnx_resolutions = list(filter(filter_pred, available_dnx_resolutions)) -# probe input file +print(f"{len(available_dnx_resolutions)} resolutions are available and detected...") input_file = sys.argv[1] -result = subprocess.run(["/usr/local/bin/ffprobe","-hide_banner","-of","json", +print(f"Probing input file {input_file}") +result = subprocess.run(["ffprobe","-hide_banner","-of","json", "-show_streams","-select_streams","v", input_file], capture_output=True) @@ -179,6 +181,12 @@ frame_size = (probe_output["streams"][0]["width"], probe_output["streams"][0]["h frame_rate = probe_output["streams"][0]["r_frame_rate"] field_order_progressive = "p" if probe_output["streams"][0]["field_order"] == "progressive" else "i" +print("Input file characteristics...") +print(f" - pix fmt = {pix_fmt}") +print(f" - frame size = {frame_size[0]}x{frame_size[1]}") +print(f" - frame rate = {frame_rate}") +print(f" - field order = {field_order_progressive}") + def filter_for_frame_rate(res): return res["frame_rate"] == frame_rate and res["interlaced"] == field_order_progressive @@ -186,15 +194,17 @@ def filter_for_scale(res): return res["width"] == frame_size[0] and res["height"] == frame_size[1] and \ res["interlaced"] == field_order_progressive -# print("Available DNx resolutions:") +print("Available DNx resolutions:") for n in filter(lambda r: filter_for_frame_rate(r) and filter_for_scale(r), available_dnx_resolutions): - print(f"-vcodec dnxhd -b:v {n['mb']}M -pix_fmt {n['pix_fmt']}") + print(f" -vcodec dnxhd -b:v {n['mb']}M -pix_fmt {n['pix_fmt']}") -# print("Available with scaling:") +print("Available with scaling:") for n in filter(filter_for_frame_rate, available_dnx_resolutions): # https://superuser.com/questions/991371/ffmpeg-scale-and-pad - print(f"""-vf "scale=w={n['width']}:h={n['height']}:force_original_aspect_ratio=1,""" + print(f""" -vf "scale=w={n['width']}:h={n['height']}:force_original_aspect_ratio=1,""" f"""pad={n['width']}:{n['height']}:(ow-iw)/2:(oh-ih)/2" -vcodec dnxhd -b:v {n['mb']}M -pix_fmt {n['pix_fmt']}""") + +