-
Notifications
You must be signed in to change notification settings - Fork 309
Adding diff feature (otiodiff) to otiotool #1922
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
cato-o
wants to merge
31
commits into
AcademySoftwareFoundation:main
Choose a base branch
from
cato-o:otiodiff
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
31 commits
Select commit
Hold shift + click to select a range
e091865
added otiodiff script
cato-o 619ca8b
added command line arg and function framework for otiodiff
cato-o ab4ecac
ported otiodiff into console scripts and added otiodiff as an option …
cato-o 814c261
updated file output of otiodiff to use output of otiotool
cato-o 2eaae82
comments cleanup
cato-o d6efa99
added track type to processTracks and makeTrack to support timelines …
cato-o b4cf7ef
added clipDB to hold all sorted clips and added check for clips that …
cato-o 8978296
sort out moved clips in db and make new moved track with new color in…
cato-o cf3288f
removed move classification if move within same track
cato-o db1022b
added handling of unmatched extra tracks back in
cato-o 9a2831d
reorder audio timeline display order to have B on top
cato-o 8cc3ad8
added overall summary stats and did some code cleanup
cato-o 5899116
added unit test file for otiodiff and ported existing tests over
cato-o ad82f25
code organization and adding comments
cato-o 4d6a751
renamed otiodif.py to otiodiff.py, fixed bugs, and added todo's
cato-o 16d0fff
added input otio error handling/warnings, added video/audio tracks ex…
cato-o 64ea08e
changed ClipData init to pull info from source OTIO clip, updated ins…
cato-o fb26df8
added otiodiff description and example to otiotool description, fixed…
cato-o b40e417
added docstrings, comments, and updated variable names
cato-o f86d739
fixed timeline output bug and return empty timeline instead of None
cato-o 2debbb6
switched color in makeOtio to use OTIO Color rather than strings, add…
cato-o e7972f4
made color an optional parameter in addMarker and added examples for …
cato-o 7e862e6
added edit tests
cato-o d34ef9d
Merge remote-tracking branch 'upstream/main' into otiodiff
cato-o c1bf13b
added variables to specify color-coding, and updated formatting
cato-o 15d88f8
fixed trackA to use unchanged clips from timeline A instead of timeli…
cato-o afa7ba4
padded track set that have less tracks with empty tracks for matched …
cato-o 22e8692
added ability to specify comparisons by name or by full_name for clip…
cato-o 704a4f9
Added docstrings for clipData
cato-o cae61a4
added todo's
cato-o cb34d06
Code cleanup
cato-o File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Empty file.
130 changes: 130 additions & 0 deletions
130
src/py-opentimelineio/opentimelineio/console/otiodiff/clipData.py
This file contains hidden or 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
import opentimelineio as otio | ||
|
||
# TODO: clip comparable??? ClipInfo | ||
# source clip or clip ref? | ||
|
||
class ClipData: | ||
"""ClipData holds information from an OTIO clip that's necessary for | ||
comparing differences. It also keeps some information associated with | ||
the clip after comparisons are made, such as a matched ClipData and a note | ||
about what has changed. | ||
|
||
source_clip = original OTIO clip the ClipData represents | ||
full_name = full name of source_clip | ||
name and version splits full_name on space | ||
ex: full_name: clipA version1, name: clipA, version: version1 | ||
""" | ||
def __init__(self, source_clip, track_num, note=None): | ||
self.full_name = source_clip.name | ||
self.name, self.version = self.splitFullName(source_clip) | ||
self.media_ref = source_clip.media_reference | ||
self.source_range = source_clip.source_range | ||
self.timeline_range = source_clip.trimmed_range_in_parent() | ||
self.track_num = track_num | ||
self.source_clip = source_clip | ||
self.note = note | ||
self.matched_clipData = None | ||
|
||
# split full name into name of clip and version by white space | ||
# uses structure of "clipA v1" where clipA is the name and v1 is the version | ||
def splitFullName(self, clip): | ||
"""Split full name into name and version by space. Returns None for | ||
version if full name contains no spaces.""" | ||
parts = clip.name.split(" ") | ||
shortName = parts[0] | ||
version = parts[1] if len(parts) > 1 else None | ||
|
||
return shortName, version | ||
|
||
def printData(self): | ||
"""Prints to console all parameters of ClipData""" | ||
print("name: ", self.name) | ||
print("version: ", self.version) | ||
print("media ref: ", self.media_ref) | ||
print("source start time: ", self.source_range.start_time.value, | ||
" duration: ", self.source_range.duration.value) | ||
print("timeline start time:", self.timeline_range.start_time.value, | ||
" duration: ", self.timeline_range.duration.value) | ||
if (self.note != ""): | ||
print("note: ", self.note) | ||
print("source clip: ", self.source.name) | ||
|
||
def sameName(self, cA): | ||
"""Compare names and returns if they are the same""" | ||
if (self.name.lower() == cA.name.lower()): | ||
return True | ||
else: | ||
return False | ||
|
||
# note: local and source duration should always match, can assume same | ||
def sameDuration(self, cA): | ||
"""Compare duration within the timeline of this ClipData | ||
against another ClipData""" | ||
return self.timeline_range.duration.value == cA.timeline_range.duration.value | ||
|
||
|
||
def checkSame(self, cA): | ||
"""Check if this ClipData is the exact same as another ClipData or if | ||
it's the same just moved along the timeline. Updates note based on edits""" | ||
isSame = False | ||
# check names are same | ||
if self.sameName(cA): | ||
# check source range is same | ||
if (self.source_range == cA.source_range): | ||
# check in same place on timeline | ||
if (self.timeline_range == cA.timeline_range): | ||
isSame = True | ||
# check duration is same but not necessarily in same place | ||
# on timeline | ||
# TODO: change to else? (does the elif always run?) | ||
elif (self.sameDuration(cA)): | ||
# Note: currently only checks for lateral shifts, doesn't | ||
# check for reordering of clips | ||
isSame = True | ||
self.note = "shifted laterally in track" | ||
return isSame | ||
|
||
def checkEdited(self, cA): | ||
"""Compare 2 ClipDatas and see if they have been edited""" | ||
isEdited = False | ||
|
||
# Note: assumption that source range and timeline range duration always equal | ||
# TODO: sometimes asserts get triggered, more investigation needed | ||
# assert(self.source_range.duration.value == self.timeline_range.duration.value | ||
# ), "clip source range and timeline range durations don't match" | ||
# assert(cA.source_range.duration.value == cA.timeline_range.duration.value | ||
# ), "clip source range and timeline range durations don't match" | ||
|
||
selfDur = self.source_range.duration | ||
cADur = cA.source_range.duration | ||
|
||
selfSourceStart = self.source_range.start_time | ||
cASourceStart = cA.source_range.start_time | ||
|
||
if (self.source_range != cA.source_range): | ||
self.note = "source range changed" | ||
isEdited = True | ||
deltaFramesStr = str(abs(selfDur.to_frames() - cADur.to_frames())) | ||
|
||
if (selfDur.value == cADur.value): | ||
self.note = "start time in source range changed" | ||
|
||
# clip duration shorter | ||
elif (selfDur.value < cADur.value): | ||
self.note = "trimmed " + deltaFramesStr + " frames" | ||
|
||
if (selfSourceStart.value == cASourceStart.value): | ||
self.note = "trimmed tail by " + deltaFramesStr + " frames" | ||
elif (selfSourceStart.value < cASourceStart.value): | ||
self.note = "trimmed head by " + deltaFramesStr + " frames" | ||
|
||
# clip duration longer | ||
elif (selfDur.value > cADur.value): | ||
self.note = "lengthened " + deltaFramesStr + " frames" | ||
|
||
if (selfSourceStart.value == cASourceStart.value): | ||
self.note = "lengthened tail by " + deltaFramesStr + " frames" | ||
elif (selfSourceStart.value > cASourceStart.value): | ||
self.note = "lengthened head by " + deltaFramesStr + " frames" | ||
|
||
return isEdited |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's go with ClipInfo