Created
August 17, 2012 10:53
-
-
Save mjohnsullivan/3377918 to your computer and use it in GitHub Desktop.
Determines the essence type of an mxf file for DCI digital cinema content: JPEG2000, MPEG or PCM
This file contains 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 | |
# MXF Keys | |
MXF_KEYS = { | |
'\x06\x0e\x2b\x34\x02\x53\x01\x01\x0d\x01\x01\x01\x01\x01\x51\x00' : 'MPEG2VIDEODESCRIPTOR', | |
'\x06\x0e\x2b\x34\x02\x53\x01\x01\x0d\x01\x01\x01\x01\x01\x5a\x00' : 'JPEG2000PICTURESUBDESCRIPTOR', | |
'\x06\x0e\x2b\x34\x02\x53\x01\x01\x0d\x01\x01\x01\x01\x01\x48\x00' : 'WAVEAUDIODESCRIPTOR', | |
'\x06\x0e\x2b\x34\x02\x53\x01\x01\x0d\x01\x01\x01\x01\x01\x37\x00' : 'SOURCEPACKAGE', | |
'\x06\x0e\x2b\x34\x01\x02\x01\x01\x0d\x01\x03\x01\x15\x01\x05\x00' : 'MPEG2ESSENCE', | |
'\x06\x0e\x2b\x34\x01\x02\x01\x01\x0d\x01\x03\x01\x15\x01\x08\x00' : 'JPEG2000ESSENCE', | |
'\x06\x0e\x2b\x34\x01\x02\x01\x01\x0d\x01\x03\x01\x16\x01\x01\x00' : 'WAVESSENCE' | |
} | |
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 essence_type(mxf_filename): | |
""" | |
Returns 'JPEG2000', 'MPEG2' or 'PCM' depending on the | |
essence type contained within the mxf file | |
""" | |
with open(mxf_filename, 'rb') as mxf_file: | |
for klv in klvs(mxf_file): | |
if klv[0] == 'JPEG2000PICTURESUBDESCRIPTOR': | |
return 'JPEG2000' | |
elif klv[0] == 'MPEG2VIDEODESCRIPTOR': | |
return 'MPEG2' | |
elif klv[0] == 'WAVEAUDIODESCRIPTOR': | |
return 'PCM' | |
if __name__ == '__main__': | |
if len(sys.argv) != 2: | |
print 'USAGE: python mxf.py <mxf file name>' | |
else: | |
# print_klv_keys(sys.argv[1]) | |
print essence_type(sys.argv[1]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment