Browse Source

Add function to find nearest keyframe to time

Can be tested using existing json files eg:

    import random
    for source in json_in["sources"]:
        time = round(random.uniform(30, 600), 2)
        print("Finding nearest keyframe to {} in {}".format(
            time, source["filepath"]))
        print("Nearest keyframe: {}-{}".format(
            time, nearest_keyframe(source["filepath"], time)))

    import sys
    sys.exit(0)
master
bertieb 3 years ago
parent
commit
13059815a3
1 changed files with 46 additions and 0 deletions
  1. +46
    -0
      efficientjson.py

+ 46
- 0
efficientjson.py View File

@@ -222,6 +222,52 @@ def process_highlights(jsonfile):

return outputfile

def nearest_keyframe(videofile=None, checktime=0):
"""Find nearest keyframe to checktime using ffprobe

see eg https://superuser.com/a/1426307"""
import subprocess

if checktime > 15:
skiptime = checktime - 15
else:
skiptime = checktime

frames = []

ffprobe_args = ["ffprobe", "-read_intervals", str(skiptime),
"-select_streams", "v",
"-skip_frame", "nokey", # skip all non keyframes
"-show_frames", "-show_entries",
"frame=pkt_pts_time",
videofile]

# complete = subprocess.run(ffprobe_args, capture_output=True)
proc = subprocess.Popen(ffprobe_args,
stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL,
universal_newlines=True)
while not proc.poll():
line = proc.stdout.readline()
if "pkt_pts_time" in line:
frametime = float(line.split("=")[1])
frames.append(frametime)
if len(frames) > 20:
proc.kill()

# if "stdout" in complete:
# for line in complete["stdout"].split("\n"):
# if "pkt_pts_time" in line:
# frames.extend(line.split("=")[1])

# get closest value, see https://stackoverflow.com/a/12141207
keyframetime = min(frames, key=lambda x: abs(x-checktime))

return str(round(keyframetime-0.1, 2))
# we return the time just before it
# so that ffmpeg seeks to that when
# cutting

# Start
import os



Loading…
Cancel
Save