diff --git a/pipeline/feature_extractors.py b/pipeline/feature_extractors.py index f9ab1ad..05c1f7d 100644 --- a/pipeline/feature_extractors.py +++ b/pipeline/feature_extractors.py @@ -258,6 +258,46 @@ class VideoActivityFeatureExtractor(FeatureExtractor): #TODO: minimum duration -- consider whether to do here, or expand duration post-consolidation """ + def __init__(self, input_files=None, config=None): + if not input_files: + raise ValueError("No input files provided!") + self.input_files = input_files + self.config = config + self.features = [] + + def _scdet(self, video_file): + """Run scdet filter on the video file""" + ffmpeg_cmd = ["ffmpeg", "-i", video_file, "-vf", "scdet=threshold=0", "-f", "null", "-"] + # output is of the form: + # [scdet @ 0x7f0798003d00] lavfi.scd.score: 0.031, lavfi.scd.time: 23.65 + # [scdet @ 0x7f0798003d00] lavfi.scd.score: 0.006, lavfi.scd.time: 23.70 + # capture output, extract time & score + scdet_output = subprocess.run(ffmpeg_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stderr.decode("utf-8") + # extract time & score + scores = [] + for line in scdet_output.splitlines(): + if "lavfi.scd.score" in line: + scores.append( (float(line.split(",")[1].split(":")[1]), + float(line.split(",")[0].split(":")[1])) + ) + return scores + + def setup(self): + pass + + def run(self): + for file in self.input_files: + scores = self._scdet(file.path) + means = sorted(self._nonoverlap_mean(scores), key=lambda x: x[1], reverse=True) + for time, score in self._drop_lowest(means, 66): + self.features.append(Feature(interval=Interval(start=time, duration=0.500), + source=file, feature_extractor="videoactivity", + score=score)) + + def teardown(self): + pass + + def teardown(self): pass