|
|
@@ -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 |