diff --git a/pipeline/utils.py b/pipeline/utils.py index 7775cbc..9c8555a 100644 --- a/pipeline/utils.py +++ b/pipeline/utils.py @@ -14,3 +14,97 @@ class SourceMedia(): }] It should be possible to combine/merge/aggregate multiple SourceMedia into one + TODO: consider if we actually want that or if we just loop over a list of >0 SourceMedia + + Iterating over a SourceMedia object should return a list of Source objects. + """ + + def __init__(self, sources=[]): + self.sources = sources + + def __iter__(self): + return iter(self.sources) + +class Source(): + """A Source is a single media file (eg), used to populate SourceMedia objects. + + JSON type schema: + { + "source": "/path/to/video.mp4", + "path": "/path/to/video.mp4", + "provider": "FileInputJSON" + } + def __init__(self, source, path, provider): + if not source: + raise ValueError("Source must be provided") # TODO: #API -- decide if this is necessary + self.source = source + if not path: + # we need a file to work on for the rest of the pipeline + raise ValueError("Path must be provided") + self.path = path + if not provider: + raise ValueError("Provider must be provided") # TODO: #API -- decide if this is necessary + self.provider = provider + def __str__(self): + """See: 'accessing the object should return the path to the media file'""" + return self.path + + def __repr__(self): + return f"Source({self.source}, {self.path}, {self.provider})" +class Interval(): + """An interval of time in a media file + + This can be defined by a start and end time, a start time and a duration, or an end time and a duration. + + Instance variables: + + start -- the start time of the interval + end -- the end time of the interval + duration -- the duration of the interval (end - start) + + Notes: + + Sorts by start time, then end time + """ + # TODO: decide if ABC or will be used directly + # TODO: have default duration for intervals set by config + # TODO: consider if we want to permit adjusting intervals (eg, start time, end time, duration) [probably yes] + # NOTE: if we have more ways of defining, we could consider multipledispatch? + + DEFAULT_DURATION = 5 # seconds + DEFAUT_PRECISION = 3 # decimal places + def __init__(self, start=None, end=None, duration=None): + if start is None and end is None and duration is None: + raise ValueError("Two of start, end, or duration must be provided") + if start is not None and end is not None and duration is not None: + raise ValueError("Only two of start, end, or duration may be provided") + + # start and end + if start is not None and end is not None: + # some trivial validation + if start > end: + raise ValueError("Start time must be before end time") + self.start = start + self.end = end + self.duration = end - start + + # start and duration + elif start is not None and duration is not None: + if duration < 0: + raise ValueError("Duration must be positive") + self.start = start + self.duration = duration + self.end = start + duration + + # end and duration + elif end is not None and duration is not None: + if duration < 0: + raise ValueError("Duration must be positive") + self.end = end + self.duration = duration + self.start = end - duration + @classmethod + def from_start(cls, start=None): + """Create an interval from a start time using the default duration""" + return cls(start=start, duration=cls.DEFAULT_DURATION) +