From 204bfac3fa8399fa79ceea9b5d820e9c5c5b0fc7 Mon Sep 17 00:00:00 2001 From: ed Date: Sat, 9 Jul 2022 04:33:19 +0200 Subject: [PATCH] mtp/vidchk: write ffprobe metadata to file --- bin/mtag/vidchk.py | 56 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/bin/mtag/vidchk.py b/bin/mtag/vidchk.py index 24b57933..64722421 100755 --- a/bin/mtag/vidchk.py +++ b/bin/mtag/vidchk.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 import json +import re import sys import subprocess as sp @@ -14,6 +15,7 @@ except: _ = r""" inspects video files for errors and such +plus stores a bunch of metadata to filename.ff.json usage: -mtp vidchk=t600,ay,p,bin/mtag/vidchk.py @@ -33,6 +35,29 @@ FAST = True # parse entire file at container level # FAST = False # fully decode audio and video streams +# warnings to ignore +harmless = re.compile("^Unsupported codec with id ") + + +def wfilter(lines): + return [x for x in lines if not harmless.search(x)] + + +def errchk(so, se, rc): + if rc: + err = (so + se).decode("utf-8", "replace").split("\n", 1) + err = wfilter(err) or err + return f"ERROR {rc}: {err[0]}" + + if se: + err = se.decode("utf-8", "replace").split("\n", 1) + err = wfilter(err) + if err: + return f"Warning: {err[0]}" + + return None + + def main(): fp = sys.argv[1] zb = sys.stdin.buffer.read() @@ -46,6 +71,26 @@ def main(): except: return "could not determine resolution" + # grab streams/format metadata + the final keyframe (and the next 2 seconds of frames after it) + zs = "ffprobe -hide_banner -v warning -of json -show_streams -show_format -show_packets -show_data_hash crc32 -read_intervals 999999%+2" + cmd = zs.encode("ascii").split(b" ") + [fsenc(fp)] + p = sp.Popen(cmd, stdout=sp.PIPE, stderr=sp.PIPE) + so, se = p.communicate() + + # spaces to tabs, drops filesize from 69k to 48k + so = b"\n".join( + [ + b"\t" * int((len(x) - len(x.lstrip())) / 4) + x.lstrip() + for x in (so or b"").split(b"\n") + ] + ) + with open(fsenc(f"{fp}.ff.json"), "wb") as f: + f.write(so) + + err = errchk(so, se, p.returncode) + if err: + return err + if min(w, h) < 1080: return "resolution too small" @@ -66,16 +111,7 @@ def main(): p = sp.Popen(cmd, stdout=sp.PIPE, stderr=sp.PIPE) so, se = p.communicate() - rc = p.returncode - if rc: - err = (so + se).decode("utf-8", "replace").split("\n", 1)[0] - return f"ERROR {rc}: {err}" - - if se: - err = se.decode("utf-8", "replace").split("\n", 1)[0] - return f"Warning: {err}" - - return None + return errchk(so, se, p.returncode) if __name__ == "__main__":