From b7024717d50be8051bac92b80b1f8249ca4354b4 Mon Sep 17 00:00:00 2001 From: Rob Hallam <0504004h@student.gla.ac.uk> Date: Mon, 5 Aug 2024 11:55:51 +0100 Subject: [PATCH] feat: add VAFE functionality Uses ffmpeg's scdet under the hood apropos of recommendation on ffmpeg-user ML [1] [1]: https://ffmpeg.org/pipermail/ffmpeg-user/2024-August/058535.html --- pipeline/feature_extractors.py | 40 ++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) 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