Skip to content

Instantly share code, notes, and snippets.

@vicnaum
Last active April 1, 2017 04:25
Show Gist options
  • Save vicnaum/6882071 to your computer and use it in GitHub Desktop.
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.
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