Last active
April 1, 2017 04:25
-
-
Save vicnaum/6882071 to your computer and use it in GitHub Desktop.
Extracts lens Focal Length metadata from Canon C300 MXF files. Put the search dir in "rootdir" variable, where the MXF files are located (can be in subdirs also). Outputs "output.txt" with ShotName / FocalLength range tabulated values on each line.
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
import sys | |
import struct | |
import os | |
rootdir = "D:/MXF_Day1_Shots" | |
# MXF Keys | |
MXF_KEYS = { | |
'\x06\x0E\x2B\x34\x02\x43\x01\x01\x0D\x01\x03\x01\x04\x01\x02\x02' : 'FRAME' | |
} | |
def _as_hex_str(bytes): | |
""" | |
Pretty-prints bytes as hex values separated by dots | |
""" | |
return '.'.join(map(lambda x: '%02X' % ord(x), bytes)) | |
def _decode_ber_length(reader): | |
""" | |
Dynamically works out a BER-encoded length value from a stream.read function. | |
Returns the decoded length and nr of bytes read | |
""" | |
length = struct.unpack('>B', reader(1))[0] # Get the first byte and decode it | |
bytes_read = 1 | |
if length > 127: | |
bytes_read += length - 128 | |
length = int(reader(length - 128).encode('hex'), 16) # Read the bytes and convert | |
return (length, bytes_read) | |
def klvs(stream): | |
""" | |
Generator that iterates through KLVs that are | |
dynamically read from a stream | |
""" | |
klv_key_length = 16 | |
pos = 0 | |
while True: | |
key = stream.read(klv_key_length) | |
if not key: | |
break | |
(length, len_bytes) = _decode_ber_length(stream.read) | |
value = stream.read(length) | |
pos += 4 + len_bytes + length | |
yield (MXF_KEYS.get(key, _as_hex_str(key)), value) | |
def print_klv_keys(mxf_filename): | |
""" | |
Prints out all klv keys found in an mxf file | |
""" | |
with open(mxf_filename, 'rb') as mxf_file: | |
for klv in klvs(mxf_file): | |
print klv[0] | |
def toFocalLength(data): | |
return str(data)[:-1] + "." + str(data)[-1:] | |
def essence_type(mxf_filename): | |
with open(mxf_filename, 'rb') as mxf_file: | |
mindata = 100000 | |
maxdata = 0 | |
for klv in klvs(mxf_file): | |
if klv[0] == "FRAME": | |
data = int(klv[1][97:99].encode('hex'), 16) | |
if data < mindata: | |
mindata = data | |
if data > maxdata: | |
maxdata = data | |
if mindata == maxdata: | |
f1.write(file + "\t" + toFocalLength(mindata) + " mm\n") | |
else: | |
f1.write(file + "\t" + toFocalLength(mindata) + " - " + toFocalLength(maxdata) + " mm\n") | |
f1 = open('output.txt', 'w') | |
for root, subFolders, files in os.walk(rootdir): | |
for file in files: | |
if file.endswith(".MXF"): | |
print file | |
essence_type(os.path.join(root, file)) | |
f1.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment