Avoid clipping first clip

This commit is contained in:
Justin Wong 2022-08-26 01:26:22 +08:00
parent 9c44ad6a1c
commit 68e2f1231f
2 changed files with 1 additions and 39 deletions

View File

@ -28,7 +28,6 @@ from playhouse.shortcuts import model_to_dict
from frigate.const import CLIPS_DIR from frigate.const import CLIPS_DIR
from frigate.models import Event, Recordings from frigate.models import Event, Recordings
from frigate.stats import stats_snapshot from frigate.stats import stats_snapshot
from frigate.util import get_adjusted_offset
from frigate.version import VERSION from frigate.version import VERSION
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -847,21 +846,13 @@ def vod_ts(camera, start_ts, end_ts):
for recording in recordings: for recording in recordings:
clip = {"type": "source", "path": recording.path} clip = {"type": "source", "path": recording.path}
duration = int(recording.duration * 1000) duration = int(recording.duration * 1000)
clip["keyFrameDurations"] = [duration]
# Determine if offset is needed for first clip
if (target_offset := int((start_ts - recording.start_time) * 1000)) > 0:
# If we are clipping, we need to find the keyframe before start_ts and start
# from there. Otherwise we may lose data and our durations will be incorrect.
offset = get_adjusted_offset(recording.path, target_offset)
clip["clipFrom"] = offset
duration -= offset
# Determine if we need to end the last clip early # Determine if we need to end the last clip early
if recording.end_time > end_ts: if recording.end_time > end_ts:
duration -= int((recording.end_time - end_ts) * 1000) duration -= int((recording.end_time - end_ts) * 1000)
if duration > 0: if duration > 0:
clip["keyFrameDurations"] = [duration]
clips.append(clip) clips.append(clip)
durations.append(duration) durations.append(duration)
else: else:
@ -875,7 +866,6 @@ def vod_ts(camera, start_ts, end_ts):
return jsonify( return jsonify(
{ {
"cache": hour_ago.timestamp() > start_ts, "cache": hour_ago.timestamp() > start_ts,
"clipTo": sum(durations),
"discontinuity": False, "discontinuity": False,
"durations": durations, "durations": durations,
"sequences": [{"clips": clips}], "sequences": [{"clips": clips}],

View File

@ -690,31 +690,3 @@ class SharedMemoryFrameManager(FrameManager):
self.shm_store[name].close() self.shm_store[name].close()
self.shm_store[name].unlink() self.shm_store[name].unlink()
del self.shm_store[name] del self.shm_store[name]
def get_adjusted_offset(source: str, target_offset: int) -> int:
"""Get the timestamp of the nearest keyframe before target_offset.
This is used to pass information to the VOD module and is useful for codec variants
with long or variable keyframe intervals."""
ffprobe_cmd = [
"ffprobe",
"-skip_frame",
"nokey",
"-select_streams",
"v:0",
"-show_entries",
"frame=pts_time",
"-v",
"quiet",
"-of",
"default=noprint_wrappers=1:nokey=1",
source,
]
p = sp.run(ffprobe_cmd, capture_output=True)
keyframe_timestamps = [int(1000 * float(pts)) for pts in p.stdout.split()]
for ts in reversed(keyframe_timestamps):
if ts <= target_offset:
return ts
logger.warning("Couldn't find starting keyframe for VOD clip")
return 0