def probe_mxf_clean(in_meta): """ Format asdcp-info probe result. Args: in_meta (dict): MXF probe metadata returned by asdcp-info. Returns: Dictionary containing MXF metadata as parsed by asdcp-info. """ out_meta = {} # Generic cleanup for k, v in six.iteritems(in_meta): # Remove BitRate unit suffix if v.endswith('Mb/s'): v = v[:-4] # Try to transform ratios string try: if '/' in v: v = format_ratio(v) except ValueError: pass # Try to convert to number v = try_convert_number(v) # Use boolean instead of string if v == 'Yes': v = True if v == 'No': v = False # Remove empty value key if v == '': continue out_meta[k] = v # Specific helper keys is_picture = 'AspectRatio' in out_meta if is_picture: out_meta['Resolution'] = "{}x{}".format( out_meta['StoredWidth'], out_meta['StoredHeight']) is_sound = 'AudioSamplingRate' in out_meta if is_sound: config_map = DCP_SETTINGS['sound']['configuration_channels'] mxf_format = out_meta['ChannelFormat'] if mxf_format in config_map: label, _, _ = config_map[mxf_format] out_meta['ChannelConfiguration'] = label return out_meta
def cpl_asset_parse_cut(asset, position): """ Parse an asset Cut """ edit_r = 0 # Format Editrate if 'EditRate' in asset: edit_r = format_ratio(asset['EditRate']) asset['EditRate'] = edit_r # Format Cut if all_keys_in_dict(asset, ["EditRate", "Duration", "EntryPoint"]): asset['OutPoint'] = asset['Duration'] + asset['EntryPoint'] asset['CPLEntryPoint'] = position asset['CPLOutPoint'] = position + asset['Duration'] asset['TimeCodeIn'] = frame_to_tc(asset['CPLEntryPoint'], edit_r) asset['TimeCodeOut'] = frame_to_tc(asset['CPLOutPoint'], edit_r) asset['TimeCodeDuration'] = frame_to_tc(asset['Duration'], edit_r)
def cpl_reels_parse(cpl_node): """ Transform Reels list to a more uniform representation """ in_reels = cpl_node['ReelList']['Reel'] out_reels = [] global_editrate = 0 total_frame_duration = 0 is_dvi = False is_ec = False is_dbox = False eidr = '' for pos, in_reel in enumerate(in_reels, 1): assetlist = in_reel.get('AssetList') if not assetlist: continue out_reel = {} out_reel['Position'] = pos out_reel['Id'] = in_reel.get('Id', '') out_reel['AnnotationText'] = in_reel.get('AnnotationText', '') out_reel['Assets'] = {} # Recognized asset categories asset_mapping = { 'MainPicture': 'Picture', 'MainStereoscopicPicture': 'Picture', 'MainSound': 'Sound', 'AuxData': 'AuxData', 'MainSubtitle': 'Subtitle', 'MainMarkers': 'Markers', 'CompositionMetadataAsset': 'Metadata', 'MainCaption': 'OpenCaption', 'ClosedCaption': 'ClosedCaption', 'MainClosedCaption': 'ClosedCaption', } # Generic asset parsing for key, val in six.iteritems(asset_mapping): if key in assetlist: out_reel['Assets'][val] = assetlist[key] asset = out_reel['Assets'][val] # Duplicated assets is a fatal error if isinstance(asset, list): raise ProbeException( "Duplicated {} asset in CPL {}, Reel {}".format( key, cpl_node.get('ContentTitleText', ''), pos)) discover_schema(asset) # Encryption asset['Encrypted'] = 'KeyId' in asset # Format Cut cpl_asset_parse_cut(asset, total_frame_duration) if 'Picture' in out_reel['Assets']: picture = out_reel['Assets']['Picture'] editrate_r = float(picture.get('EditRate', 0)) picture['Stereoscopic'] = 'MainStereoscopicPicture' in assetlist min_hfr_editrate = DCP_SETTINGS['picture']['min_hfr_editrate'] picture['HighFrameRate'] = editrate_r >= min_hfr_editrate picture['FrameRate'] = format_ratio(picture.get('FrameRate')) picture["ScreenAspectRatio"] = format_ratio( picture.get('ScreenAspectRatio')) # Picture track is the reference for EditRate / Duration global_editrate = editrate_r total_frame_duration += picture.get('Duration', 0) if 'Markers' in out_reel['Assets']: marker = out_reel['Assets']['Markers'] editrate_r = format_ratio(marker.get('EditRate')) marker['EditRate'] = editrate_r marker_list = marker['MarkerList']['Marker'] if not type(marker_list) is list: marker['MarkerList'] = [marker_list] else: marker['MarkerList'] = marker_list if 'Metadata' in out_reel['Assets']: meta = out_reel['Assets']['Metadata'] exts = meta.get('ExtensionMetadataList', {}).get('ExtensionMetadata', []) for ext in exts: ext_name = ext.get('Name') properties = ext.get('PropertyList') if ext_name == 'Dolby EDR': is_dvi = True elif ext_name == 'Eclair Color': is_ec = True elif ext_name == 'D-BOX Enabled': is_dbox = True elif ext_name == 'EIDR': for p in properties: prop_name = p['Property'].get('Name', '') if prop_name != 'structural-type': continue eidr = p['Property'].get('Value', '') eidr = eidr.replace('urn:eidr:10.5240:', '').strip() out_reels.append(out_reel) cpl_node['DolbyVision'] = is_dvi cpl_node['EclairColor'] = is_ec cpl_node['D-BOX'] = is_dbox cpl_node['EIDR'] = eidr cpl_node['ReelList'] = out_reels cpl_node['TotalDuration'] = total_frame_duration cpl_node['TotalTimeCodeDuration'] = frame_to_tc(total_frame_duration, global_editrate)
def cpl_reels_parse(cpl_node): """ Transform Reels list to a more uniform representation """ in_reels = cpl_node['ReelList']['Reel'] out_reels = [] global_editrate = 0 total_frame_duration = 0 is_dvi = False is_ec = False is_dbox = False for pos, in_reel in enumerate(in_reels, 1): assetlist = in_reel.get('AssetList') if not assetlist: continue out_reel = {} out_reel['Position'] = pos out_reel['Id'] = in_reel.get('Id', '') out_reel['AnnotationText'] = in_reel.get('AnnotationText', '') out_reel['Assets'] = {} # Recognized asset categories asset_mapping = { 'MainPicture': 'Picture', 'MainStereoscopicPicture': 'Picture', 'MainSound': 'Sound', 'AuxData': 'AuxData', 'MainSubtitle': 'Subtitle', 'MainMarkers': 'Markers', 'CompositionMetadataAsset': 'Metadata', 'ClosedCaption': 'ClosedCaption' } # Generic asset parsing for key, val in six.iteritems(asset_mapping): if key in assetlist: out_reel['Assets'][val] = assetlist[key] asset = out_reel['Assets'][val] discover_schema(asset) # Encryption asset['Encrypted'] = 'KeyId' in asset # Format Cut cpl_asset_parse_cut(asset, total_frame_duration) if 'Picture' in out_reel['Assets']: picture = out_reel['Assets']['Picture'] editrate_r = float(picture.get('EditRate', 0)) picture['Stereoscopic'] = 'MainStereoscopicPicture' in assetlist min_hfr_editrate = DCP_SETTINGS['picture']['min_hfr_editrate'] picture['HighFrameRate'] = editrate_r >= min_hfr_editrate picture['FrameRate'] = format_ratio(picture.get('FrameRate')) picture["ScreenAspectRatio"] = format_ratio( picture.get('ScreenAspectRatio')) # Picture track is the reference for EditRate / Duration global_editrate = editrate_r total_frame_duration += picture.get('Duration', 0) if 'Markers' in out_reel['Assets']: marker = out_reel['Assets']['Markers'] editrate_r = format_ratio(marker.get('EditRate')) marker['EditRate'] = editrate_r marker_list = marker['MarkerList']['Marker'] if type(marker_list) is list: marker['MarkerList'] = marker_list else: marker['MarkerList'] = [{ marker_list["Label"]: marker_list["Offset"] }] if 'Metadata' in out_reel['Assets']: meta = out_reel['Assets']['Metadata'] exts = meta['ExtensionMetadataList'].get('ExtensionMetadata', []) for ext in exts: ext_name = ext.get('Name') if ext_name == 'Dolby EDR': is_dvi = True elif ext_name == 'Eclair Color': is_ec = True elif ext_name == 'D-BOX Enabled': is_dbox = True out_reels.append(out_reel) cpl_node['DolbyVision'] = is_dvi cpl_node['EclairColor'] = is_ec cpl_node['D-BOX'] = is_dbox cpl_node['ReelList'] = out_reels cpl_node['TotalDuration'] = total_frame_duration cpl_node['TotalTimeCodeDuration'] = frame_to_tc( total_frame_duration, global_editrate)