From fb5205c12a865f92c15b2d76a810a8a0dc69b362 Mon Sep 17 00:00:00 2001 From: Bel LaPointe <153096461+breel-render@users.noreply.github.com> Date: Tue, 26 Dec 2023 08:49:47 -0500 Subject: [PATCH] audio AND video silence now drops --- src-lib/testdata/poc.sh | 111 +++++++++++++++++++++++++++++----------- 1 file changed, 80 insertions(+), 31 deletions(-) diff --git a/src-lib/testdata/poc.sh b/src-lib/testdata/poc.sh index 5e4d091..6566afd 100644 --- a/src-lib/testdata/poc.sh +++ b/src-lib/testdata/poc.sh @@ -5,49 +5,98 @@ from sys import stdin, stderr lines = [i.strip() for i in stdin.readlines()] def frame_duplicate_status(line): - return "keep" if "keep" in line else "drop", "Parsed_mpdecimate_0" in line -somelines = [] + return "keep" if "keep" in line else "drop", "Parsed_mpdecimate_0" in line +def silence_status(line): + if not "[silencedetect @ " in line: + return None + return line.split()[3:5] +def parse_duration(line): + if not line.startswith("Duration: "): + return None + ts = line.split()[1].strip(",") + hours, minutes, seconds = [float(i) for i in ts.split(":")] + return seconds + 60.0 * minutes + 60.0 * 60.0 * hours + +state_transition_lines_video = [] +state_transition_lines_audio = [0.0] +state_total_duration = 0.0 for i in range(len(lines)): - status, relevant = frame_duplicate_status(lines[i]) - if not relevant: - continue - if not somelines: - somelines.append(lines[i]) - else: - prev_status, _ = frame_duplicate_status(somelines[-1]) - if status != prev_status: - somelines.append(lines[i-1]) - somelines.append(lines[i]) -somelines = [(frame_duplicate_status(i)[0], i.split("pts_time:")[1].split()[0]) for i in somelines] + status, relevant = frame_duplicate_status(lines[i]) + if relevant: + if not state_transition_lines_video: + state_transition_lines_video.append(lines[i]) + else: + prev_status, _ = frame_duplicate_status(state_transition_lines_video[-1]) + if status != prev_status: + state_transition_lines_video.append(lines[i-1]) + state_transition_lines_video.append(lines[i]) + status = silence_status(lines[i]) + if status: + state_transition_lines_audio.append(float(status[1])) + status = parse_duration(lines[i]) + if not status is None: + duration = status +state_transition_lines_audio.append(duration) +state_transition_lines_video = [(frame_duplicate_status(i)[0], i.split("pts_time:")[1].split()[0]) for i in state_transition_lines_video] # just the keeps -somelines = [i for i in somelines[2:] if i[0] == "keep"] +state_transition_lines_video = [i for i in state_transition_lines_video[2:] if i[0] == "keep"] -# translate to floats -drops = [] -for i in range(0, len(somelines), 2): - start = float(somelines[i][1]) - if len(somelines) > i+1: - stop = float(somelines[i+1][1]) +# translate to float spans +spans_to_keep_video = [] +spans_to_keep_audio = [] +for i in range(0, len(state_transition_lines_video), 2): + start = float(state_transition_lines_video[i][1]) + if len(state_transition_lines_video) > i+1: + stop = float(state_transition_lines_video[i+1][1]) if stop - start > 1: - drops.append((start, stop)) - #else: - # drops.append((start, "inf")) + spans_to_keep_video.append((start, stop)) + else: + spans_to_keep_video.append((start, duration)) +spans_to_keep_audio = [ + (state_transition_lines_audio[i], state_transition_lines_audio[i+1]) + for i in range(0, len(state_transition_lines_audio), 2) +] + +# drop zero len spans +spans_to_keep_video = [i for i in spans_to_keep_video if i[1]-i[0] > 0.1] +spans_to_keep_audio = [i for i in spans_to_keep_audio if i[1]-i[0] > 0.1] # extend around -for i in range(len(drops)): - drops[i] = (drops[i][0] - 1.0, drops[i][1] + 1.0) +for arr in [spans_to_keep_video, spans_to_keep_audio]: + for i in range(len(arr)): + arr[i] = ( + max(0.0, arr[i][0] - 1.0), + min(duration, arr[i][1] + 1.0), + ) # combine near -for i in range(len(drops)-1, 0, -1): - first_start, first_stop = drops[i-1] - secnd_start, secnd_stop = drops[i] +for arr in [spans_to_keep_video, spans_to_keep_audio]: + for i in range(len(arr)-1, 0, -1): + first_start, first_stop = arr[i-1] + secnd_start, secnd_stop = arr[i] + if secnd_start - first_stop < 5: + arr = arr[:i-1] + [(first_start, secnd_stop)] + arr[i+1:] + +# union audio, video spans +spans_to_keep = spans_to_keep_video + spans_to_keep_audio +spans_to_keep = sorted(spans_to_keep) +for i in range(len(spans_to_keep)-1, 0, -1): + first_start, first_stop = spans_to_keep[i-1] + secnd_start, secnd_stop = spans_to_keep[i] if secnd_start - first_stop < 5: - drops = drops[:i-1] + [(first_start, secnd_stop)] + drops[i+1:] + spans_to_keep = spans_to_keep[:i-1] + [(first_start, secnd_stop)] + spans_to_keep[i+1:] + +print("\n".join([ + f'AUDIO: {i[0]:.2f},{i[1]-i[0]:.2f}' for i in spans_to_keep_audio +]), file=stderr) +print("\n".join([ + f'VIDEO: {i[0]:.2f},{i[1]-i[0]:.2f}' for i in spans_to_keep_video +]), file=stderr) # output print("\n".join([ - f'{i[0]:.2f},{i[1]-i[0]:.2f}' for i in drops + f'{i[0]:.2f},{i[1]-i[0]:.2f}' for i in spans_to_keep ])) EOF )" @@ -61,7 +110,7 @@ for span in $( ) 2>&1 \ | grep -E 'silencedetect|Parsed_mpdecimate_0|Duration: *[0-9]' \ | grep -E 'silencedetect| (keep|drop) |Duration: *[0-9]' \ - | python3 -c "$py" >&2 + | python3 -c "$py" ); do n=$((n+1)) ffmpeg -y -ss ${span%,*} -i "$f" -t ${span#*,} "$d/$(printf "%05d" $(ls "$d" | wc -l)).${f##*.}"