Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add API and WebUI to export recordings #6550

Merged
merged 20 commits into from
Jun 8, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add separate ffmpeg preset for timelapse
  • Loading branch information
NickM-27 committed Jun 7, 2023
commit 6c2621799cf915c26c88eaa2eebb4b30442d300f
33 changes: 29 additions & 4 deletions frigate/ffmpeg_presets.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import logging
import os

from enum import Enum
from typing import Any

from frigate.const import BTBN_PATH
Expand Down Expand Up @@ -116,7 +118,7 @@ def get_selected_gpu(self) -> str:
"default": "-r {0} -s {1}x{2}",
}

PRESETS_HW_ACCEL_ENCODE = {
PRESETS_HW_ACCEL_ENCODE_BIRDSEYE = {
"preset-rpi-32-h264": "ffmpeg -hide_banner {0} -c:v h264_v4l2m2m {1}",
"preset-rpi-64-h264": "ffmpeg -hide_banner {0} -c:v h264_v4l2m2m {1}",
"preset-vaapi": "ffmpeg -hide_banner -hwaccel vaapi -hwaccel_output_format vaapi -hwaccel_device {2} {0} -c:v h264_vaapi -g 50 -bf 0 -profile:v high -level:v 4.1 -sei:v 0 -an -vf format=vaapi|nv12,hwupload {1}",
Expand All @@ -127,6 +129,17 @@ def get_selected_gpu(self) -> str:
"default": "ffmpeg -hide_banner {0} -c:v libx264 -g 50 -profile:v high -level:v 4.1 -preset:v superfast -tune:v zerolatency {1}",
}

PRESETS_HW_ACCEL_ENCODE_TIMELAPSE = {
"preset-rpi-32-h264": "ffmpeg -hide_banner {0} -c:v h264_v4l2m2m {1}",
"preset-rpi-64-h264": "ffmpeg -hide_banner {0} -c:v h264_v4l2m2m {1}",
"preset-vaapi": "ffmpeg -hide_banner -hwaccel vaapi -hwaccel_output_format vaapi -hwaccel_device {2} {0} -c:v h264_vaapi {1}",
"preset-intel-qsv-h264": "ffmpeg -hide_banner {0} -c:v h264_qsv -g 50 -bf 0 -profile:v high -level:v 4.1 -async_depth:v 1 {1}",
"preset-intel-qsv-h265": "ffmpeg -hide_banner {0} -c:v hevc_qsv -g 50 -bf 0 -profile:v high -level:v 4.1 -async_depth:v 1 {1}",
"preset-nvidia-h264": "ffmpeg -hide_banner -hwaccel cuda -hwaccel_output_format cuda -extra_hw_frames 8 {0} -c:v h264_nvenc {1}",
"preset-nvidia-h265": "ffmpeg -hide_banner -hwaccel cuda -hwaccel_output_format cuda -extra_hw_frames 8 {0} -c:v hevc_nvenc {1}",
"default": "ffmpeg -hide_banner {0} -c:v libx264 -preset:v ultrafast -tune:v zerolatency {1}",
}


def parse_preset_hardware_acceleration_decode(arg: Any) -> list[str]:
"""Return the correct preset if in preset format otherwise return None."""
Expand Down Expand Up @@ -161,12 +174,24 @@ def parse_preset_hardware_acceleration_scale(
return scale


def parse_preset_hardware_acceleration_encode(arg: Any, input: str, output: str) -> str:
class EncodeTypeEnum(str, Enum):
birdseye = "birdseye"
timelapse = "timelapse"


def parse_preset_hardware_acceleration_encode(
arg: Any, input: str, output: str, type: EncodeTypeEnum = EncodeTypeEnum.birdseye
) -> str:
"""Return the correct scaling preset or default preset if none is set."""
if type == EncodeTypeEnum.birdseye:
arg_map = PRESETS_HW_ACCEL_ENCODE_BIRDSEYE
elif type == EncodeTypeEnum.timelapse:
arg_map = PRESETS_HW_ACCEL_ENCODE_TIMELAPSE

if not isinstance(arg, str):
return PRESETS_HW_ACCEL_ENCODE["default"].format(input, output)
return arg_map["default"].format(input, output)

return PRESETS_HW_ACCEL_ENCODE.get(arg, PRESETS_HW_ACCEL_ENCODE["default"]).format(
return arg_map.get(arg, arg_map["default"]).format(
input,
output,
_gpu_selector.get_selected_gpu(),
Expand Down
10 changes: 8 additions & 2 deletions frigate/record/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@

from frigate.config import FrigateConfig
from frigate.const import EXPORT_DIR, MAX_PLAYLIST_SECONDS
from frigate.ffmpeg_presets import parse_preset_hardware_acceleration_encode
from frigate.ffmpeg_presets import (
EncodeTypeEnum,
parse_preset_hardware_acceleration_encode,
)

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -76,6 +79,7 @@ def run(self) -> None:
self.config.ffmpeg.hwaccel_args,
ffmpeg_input,
f"-vf setpts=0.04*PTS -r 30 -an {file_name}",
EncodeTypeEnum.timelapse,
)
).split(" ")

Expand All @@ -87,7 +91,9 @@ def run(self) -> None:
)

if p.returncode != 0:
logger.error(f"Failed to export recording for command {' '.join(ffmpeg_cmd)}")
logger.error(
f"Failed to export recording for command {' '.join(ffmpeg_cmd)}"
)
logger.error(p.stderr)
return

Expand Down