Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

utils.py 3.9 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. class SourceMedia():
  2. """Source media used by eg feature extractors. This is a list of Source objects.
  3. JSON type schema:
  4. [{
  5. "source": "/path/to/video.mp4",
  6. "path": "/path/to/video.mp4",
  7. "provider": "FileInputJSON"
  8. },
  9. {
  10. "source": "http://example.com/video.mp4",
  11. "path": "/path/to/downloaded_video.mp4",
  12. "provider": "InputYAML"
  13. }]
  14. It should be possible to combine/merge/aggregate multiple SourceMedia into one
  15. TODO: consider if we actually want that or if we just loop over a list of >0 SourceMedia
  16. Iterating over a SourceMedia object should return a list of Source objects.
  17. """
  18. def __init__(self, sources=[]):
  19. self.sources = sources
  20. def __iter__(self):
  21. return iter(self.sources)
  22. class Source():
  23. """A Source is a single media file (eg), used to populate SourceMedia objects.
  24. JSON type schema:
  25. {
  26. "source": "/path/to/video.mp4",
  27. "path": "/path/to/video.mp4",
  28. "provider": "FileInputJSON"
  29. }
  30. def __init__(self, source, path, provider):
  31. if not source:
  32. raise ValueError("Source must be provided") # TODO: #API -- decide if this is necessary
  33. self.source = source
  34. if not path:
  35. # we need a file to work on for the rest of the pipeline
  36. raise ValueError("Path must be provided")
  37. self.path = path
  38. if not provider:
  39. raise ValueError("Provider must be provided") # TODO: #API -- decide if this is necessary
  40. self.provider = provider
  41. def __str__(self):
  42. """See: 'accessing the object should return the path to the media file'"""
  43. return self.path
  44. def __repr__(self):
  45. return f"Source({self.source}, {self.path}, {self.provider})"
  46. class Interval():
  47. """An interval of time in a media file
  48. This can be defined by a start and end time, a start time and a duration, or an end time and a duration.
  49. Instance variables:
  50. start -- the start time of the interval
  51. end -- the end time of the interval
  52. duration -- the duration of the interval (end - start)
  53. Notes:
  54. Sorts by start time, then end time
  55. """
  56. # TODO: decide if ABC or will be used directly
  57. # TODO: have default duration for intervals set by config
  58. # TODO: consider if we want to permit adjusting intervals (eg, start time, end time, duration) [probably yes]
  59. # NOTE: if we have more ways of defining, we could consider multipledispatch?
  60. DEFAULT_DURATION = 5 # seconds
  61. DEFAUT_PRECISION = 3 # decimal places
  62. def __init__(self, start=None, end=None, duration=None):
  63. if start is None and end is None and duration is None:
  64. raise ValueError("Two of start, end, or duration must be provided")
  65. if start is not None and end is not None and duration is not None:
  66. raise ValueError("Only two of start, end, or duration may be provided")
  67. # start and end
  68. if start is not None and end is not None:
  69. # some trivial validation
  70. if start > end:
  71. raise ValueError("Start time must be before end time")
  72. self.start = start
  73. self.end = end
  74. self.duration = end - start
  75. # start and duration
  76. elif start is not None and duration is not None:
  77. if duration < 0:
  78. raise ValueError("Duration must be positive")
  79. self.start = start
  80. self.duration = duration
  81. self.end = start + duration
  82. # end and duration
  83. elif end is not None and duration is not None:
  84. if duration < 0:
  85. raise ValueError("Duration must be positive")
  86. self.end = end
  87. self.duration = duration
  88. self.start = end - duration
  89. @classmethod
  90. def from_start(cls, start=None):
  91. """Create an interval from a start time using the default duration"""
  92. return cls(start=start, duration=cls.DEFAULT_DURATION)