@@ -137,7 +137,8 @@ def main():
137137 args .list_media or
138138 args .verify_media or
139139 args .list_tracks or
140- args .list_markers )
140+ args .list_markers or
141+ args .verify_ranges )
141142 if should_summarize :
142143 for timeline in timelines :
143144 summarize_timeline (
@@ -146,6 +147,7 @@ def main():
146147 args .list_media ,
147148 args .verify_media ,
148149 args .list_markers ,
150+ args .verify_ranges ,
149151 timeline )
150152
151153 # Final Phase: Output
@@ -207,8 +209,8 @@ def parse_arguments():
207209
2082106. Inspect
209211 Options such as --stats, --list-clips, --list-tracks, --list-media,
210- --verify-media, --list-markers, and --inspect will examine the OTIO and
211- print information to standard output.
212+ --verify-media, --list-markers, --verify-ranges, and --inspect
213+ will examine the OTIO and print information to standard output.
212214
2132157. Output
214216 Finally, if the "--output <filename>" option is specified, the resulting
@@ -397,6 +399,13 @@ def parse_arguments():
397399 action = 'store_true' ,
398400 help = "List summary of all markers"
399401 )
402+ parser .add_argument (
403+ "--verify-ranges" ,
404+ action = 'store_true' ,
405+ help = """Verify that each clip in a timeline has a source range
406+ within the available range of media
407+ (acceptable in some use cases, not in others)"""
408+ )
400409 parser .add_argument (
401410 "--inspect" ,
402411 type = str ,
@@ -852,7 +861,7 @@ def inspect_timelines(name_regex, timeline):
852861
853862
854863def summarize_timeline (list_tracks , list_clips , list_media , verify_media ,
855- list_markers , timeline ):
864+ list_markers , verify_ranges , timeline ):
856865 """Print a summary of a timeline, optionally listing the tracks, clips, media,
857866 and/or markers inside it."""
858867 print ("TIMELINE:" , timeline .name )
@@ -861,8 +870,30 @@ def summarize_timeline(list_tracks, list_clips, list_media, verify_media,
861870 if list_tracks :
862871 print (f"TRACK: { child .name } ({ child .kind } )" )
863872 if isinstance (child , otio .schema .Clip ):
864- if list_clips :
865- print (" CLIP:" , child .name )
873+ if list_clips or verify_ranges :
874+ if verify_ranges :
875+ range_msg = ""
876+ try :
877+ source = child .source_range
878+ available = child .available_range ()
879+
880+ # contains() uses end_time_exclusive(),
881+ # does not handle case when
882+ # the end of the source range
883+ # meets available range exactly
884+ available_start = available .start_time
885+ available_end = available .end_time_inclusive ()
886+ src_start = source .start_time
887+ src_end = source .end_time_inclusive ()
888+ if src_start < available_start or available_end < src_end :
889+ range_msg = "SOURCE MEDIA OUT OF BOUNDS"
890+ else :
891+ range_msg = "IN BOUNDS"
892+ except Exception : # available range is, well, unavailable
893+ pass
894+ print (" CLIP:" , child .name , range_msg )
895+ else :
896+ print (" CLIP:" , child .name )
866897 if list_media or verify_media :
867898 try :
868899 url = child .media_reference .target_url
0 commit comments