diff --git a/ptulsconv/__main__.py b/ptulsconv/__main__.py index c2c9ee5..48b4e03 100644 --- a/ptulsconv/__main__.py +++ b/ptulsconv/__main__.py @@ -1,9 +1,13 @@ from ptulsconv.commands import convert +import ptulsconv.broadcast_timecode from optparse import OptionParser import sys parser = OptionParser() parser.usage = "ptulsconv TEXT_EXPORT.txt" +parser.add_option('-i', dest='in_time', help='Set in time to grab a subsequence of events. ' + 'Give value as a timecode in current session\'s rate.') +parser.add_option('-o', dest='out_time', help='Set out time to grab a subsequence of events.') if __name__ == "__main__": (options, args) = parser.parse_args(sys.argv) @@ -12,4 +16,4 @@ if __name__ == "__main__": parser.print_help(sys.stderr) exit(-1) - convert(input_file=args[1], output=sys.stdout) + convert(input_file=args[1], start=options.in_time, end=options.out_time, output=sys.stdout) diff --git a/ptulsconv/commands.py b/ptulsconv/commands.py index 3725056..d87a86e 100644 --- a/ptulsconv/commands.py +++ b/ptulsconv/commands.py @@ -12,6 +12,10 @@ def fmp_dump(data, output): (['Sc'], 'Scene', str), (['Ver'], 'Version', str), (['Reel'], 'Reel', str), + (['PT.Clip.Start'], 'Start', str), + (['PT.Clip.Finish'], 'Finish', str), + (['PT.Clip.Start_Frames'], 'Start Frames', int), + (['PT.Clip.Finish_Frames'], 'Finish Frames', int), (['P'], 'Priority', int), (['QN'], 'Cue Number', str), (['Char', 'PT.Track.Name'], 'Charater Name', str), @@ -67,7 +71,7 @@ def fmp_dump(data, output): doc.start('DATA') for key_attempt in field[0]: if key_attempt in event.keys(): - doc.data(event[key_attempt]) + doc.data(str(event[key_attempt])) break doc.end('DATA') doc.end('COL') @@ -81,18 +85,32 @@ def fmp_dump(data, output): -def convert(input_file, format='fmp', output=sys.stdout): +def convert(input_file, format='fmp', start=None, end=None, output=sys.stdout): with open(input_file, 'r') as file: ast = ptulsconv.protools_text_export_grammar.parse(file.read()) dict_parser = ptulsconv.DictionaryParserVisitor() - parsed = dict_parser.visit(ast) + raw_parsed = dict_parser.visit(ast) tcxform = ptulsconv.transformations.TimecodeInterpreter() tagxform = ptulsconv.transformations.TagInterpreter() - final = tagxform.transform( tcxform.transform(parsed) ) - if format == 'json': - json.dump(final, output) - elif format == 'fmp': - fmp_dump(final, output) + parsed = tagxform.transform(tcxform.transform(raw_parsed)) + + if start is not None and end is not None: + + start_fs = tcxform.convert_time(start, + frame_rate=raw_parsed['header']['timecode_format'], + drop_frame=raw_parsed['header']['timecode_drop_frame'])['frame_count'] + + end_fs = tcxform.convert_time(end, + frame_rate=raw_parsed['header']['timecode_format'], + drop_frame=raw_parsed['header']['timecode_drop_frame'])['frame_count'] + + subclipxform = ptulsconv.transformations.SubclipOfSequence(start=start_fs, end=end_fs) + parsed = subclipxform.transform(parsed) + + if format == 'json': + json.dump(parsed, output) + elif format == 'fmp': + fmp_dump(parsed, output) diff --git a/ptulsconv/transformations.py b/ptulsconv/transformations.py index c317c4c..6d03460 100644 --- a/ptulsconv/transformations.py +++ b/ptulsconv/transformations.py @@ -56,7 +56,7 @@ class TimecodeInterpreter(Transformation): return dict(frame_count=frame_count, logical_fps=lfps, drop_frame=drop_frame) -class TagInterpreter: +class TagInterpreter(Transformation): tag_grammar = Grammar( r""" document = modifier? line? word_sep? tag_list? @@ -153,8 +153,10 @@ class TagInterpreter: event['PT.Session.Name'] = title_tags['line'] event['PT.Clip.Number'] = clip['event'] event['event_name'] = clip_tags['line'] + event['PT.Clip.Start'] = clip['start_time'] + event['PT.Clip.Finish'] = clip['end_time'] event['PT.Clip.Start_Frames'] = clip_start - event['PT.Clip.End_Frames'] = clip['end_time_decoded']['frame_count'] + event['PT.Clip.Finish_Frames'] = clip['end_time_decoded']['frame_count'] transformed.append(event) elif clip_tags['mode'] == 'Append': @@ -200,5 +202,21 @@ class TagInterpreter: parse_tree = self.tag_grammar.parse(source) return self.visitor.visit(parse_tree) +class SubclipOfSequence(Transformation): + + def __init__(self, start, end): + self.start = start + self.end = end + + def transform(self, input_dict: dict) -> dict: + out_events = [] + for event in input_dict['events']: + if self.start <= event['PT.Clip.Start_Frames'] <= self.end: + e = event + e['PT.Clip.Start_Frames'] = event['PT.Clip.Start_Frames'] - self.start + e['PT.Clip.Finish_Frames'] = event['PT.Clip.Finish_Frames'] - self.start + out_events.append(e) + + return dict(events=out_events)