Skip to content

Commit

Permalink
Add ability to export from recordings page (#10692)
Browse files Browse the repository at this point in the history
* Add dialog to export recordings

* Add export dialog functionality

* Add ability to name exports

* Add ability to choose custom time range on timeline

* Add ability to choose custom time range on timeline

* Add custom time selection

* Make hot keys optional for typing name of export

* Tweaks to dialog

* Tweaks to dialog

* round corners more

* Final tweaks
  • Loading branch information
NickM-27 committed Mar 26, 2024
1 parent c82ed43 commit 8f69ede
Show file tree
Hide file tree
Showing 10 changed files with 483 additions and 18 deletions.
3 changes: 3 additions & 0 deletions frigate/api/media.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import subprocess as sp
import time
from datetime import datetime, timedelta, timezone
from typing import Optional
from urllib.parse import unquote

import cv2
Expand Down Expand Up @@ -618,6 +619,7 @@ def export_recording(camera_name: str, start_time, end_time):

json: dict[str, any] = request.get_json(silent=True) or {}
playback_factor = json.get("playback", "realtime")
name: Optional[str] = json.get("name")

recordings_count = (
Recordings.select()
Expand All @@ -641,6 +643,7 @@ def export_recording(camera_name: str, start_time, end_time):
exporter = RecordingExporter(
current_app.frigate_config,
camera_name,
secure_filename(name.replace(" ", "_")) if name else None,
int(start_time),
int(end_time),
(
Expand Down
22 changes: 14 additions & 8 deletions frigate/record/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,15 @@ def __init__(
self,
config: FrigateConfig,
camera: str,
name: str,
start_time: int,
end_time: int,
playback_factor: PlaybackFactorEnum,
) -> None:
threading.Thread.__init__(self)
self.config = config
self.camera = camera
self.user_provided_name = name
self.start_time = start_time
self.end_time = end_time
self.playback_factor = playback_factor
Expand All @@ -57,8 +59,12 @@ def run(self) -> None:
logger.debug(
f"Beginning export for {self.camera} from {self.start_time} to {self.end_time}"
)
file_name = f"{EXPORT_DIR}/in_progress.{self.camera}@{self.get_datetime_from_timestamp(self.start_time)}__{self.get_datetime_from_timestamp(self.end_time)}.mp4"
final_file_name = f"{EXPORT_DIR}/{self.camera}_{self.get_datetime_from_timestamp(self.start_time)}__{self.get_datetime_from_timestamp(self.end_time)}.mp4"
file_name = (
self.user_provided_name
or f"{self.camera}@{self.get_datetime_from_timestamp(self.start_time)}__{self.get_datetime_from_timestamp(self.end_time)}"
)
file_path = f"{EXPORT_DIR}/in_progress.{file_name}.mp4"
final_file_path = f"{EXPORT_DIR}/{file_name}.mp4"

if (self.end_time - self.start_time) <= MAX_PLAYLIST_SECONDS:
playlist_lines = f"http://127.0.0.1:5000/vod/{self.camera}/start/{self.start_time}/end/{self.end_time}/index.m3u8"
Expand Down Expand Up @@ -97,14 +103,14 @@ def run(self) -> None:

if self.playback_factor == PlaybackFactorEnum.realtime:
ffmpeg_cmd = (
f"ffmpeg -hide_banner {ffmpeg_input} -c copy {file_name}"
f"ffmpeg -hide_banner {ffmpeg_input} -c copy {file_path}"
).split(" ")
elif self.playback_factor == PlaybackFactorEnum.timelapse_25x:
ffmpeg_cmd = (
parse_preset_hardware_acceleration_encode(
self.config.ffmpeg.hwaccel_args,
f"{TIMELAPSE_DATA_INPUT_ARGS} {ffmpeg_input}",
f"{self.config.cameras[self.camera].record.export.timelapse_args} {file_name}",
f"{self.config.cameras[self.camera].record.export.timelapse_args} {file_path}",
EncodeTypeEnum.timelapse,
)
).split(" ")
Expand All @@ -122,9 +128,9 @@ def run(self) -> None:
f"Failed to export recording for command {' '.join(ffmpeg_cmd)}"
)
logger.error(p.stderr)
Path(file_name).unlink(missing_ok=True)
Path(file_path).unlink(missing_ok=True)
return

logger.debug(f"Updating finalized export {file_name}")
os.rename(file_name, final_file_name)
logger.debug(f"Finished exporting {file_name}")
logger.debug(f"Updating finalized export {file_path}")
os.rename(file_path, final_file_path)
logger.debug(f"Finished exporting {file_path}")
Loading

0 comments on commit 8f69ede

Please sign in to comment.