mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-12-19 19:06:16 +01:00
Fix iOS playback of H.265 clips (#10105)
* Fix iOS playback of H.265 clips * CI
This commit is contained in:
parent
9893741990
commit
5edaaceaf2
@ -614,6 +614,7 @@ class FfmpegOutputArgsConfig(FrigateBaseModel):
|
||||
default=RECORD_FFMPEG_OUTPUT_ARGS_DEFAULT,
|
||||
title="Record role FFmpeg output arguments.",
|
||||
)
|
||||
_force_record_hvc1: bool = PrivateAttr(default=False)
|
||||
|
||||
|
||||
class FfmpegConfig(FrigateBaseModel):
|
||||
@ -878,7 +879,10 @@ class CameraConfig(FrigateBaseModel):
|
||||
|
||||
if "record" in ffmpeg_input.roles and self.record.enabled:
|
||||
record_args = get_ffmpeg_arg_list(
|
||||
parse_preset_output_record(self.ffmpeg.output_args.record)
|
||||
parse_preset_output_record(
|
||||
self.ffmpeg.output_args.record,
|
||||
self.ffmpeg.output_args._force_record_hvc1,
|
||||
)
|
||||
or self.ffmpeg.output_args.record
|
||||
)
|
||||
|
||||
@ -1161,31 +1165,42 @@ class FrigateConfig(FrigateBaseModel):
|
||||
if camera_config.ffmpeg.hwaccel_args == "auto":
|
||||
camera_config.ffmpeg.hwaccel_args = config.ffmpeg.hwaccel_args
|
||||
|
||||
if (
|
||||
camera_config.detect.height is None
|
||||
or camera_config.detect.width is None
|
||||
):
|
||||
for input in camera_config.ffmpeg.inputs:
|
||||
if "detect" in input.roles:
|
||||
stream_info = {"width": 0, "height": 0}
|
||||
try:
|
||||
stream_info = asyncio.run(get_video_properties(input.path))
|
||||
except Exception:
|
||||
logger.warn(
|
||||
f"Error detecting stream resolution automatically for {input.path} Applying default values."
|
||||
)
|
||||
stream_info = {"width": 0, "height": 0}
|
||||
for input in camera_config.ffmpeg.inputs:
|
||||
need_record_fourcc = "record" in input.roles
|
||||
need_detect_dimensions = "detect" in input.roles and (
|
||||
camera_config.detect.height is None
|
||||
or camera_config.detect.width is None
|
||||
)
|
||||
|
||||
camera_config.detect.width = (
|
||||
stream_info["width"]
|
||||
if stream_info.get("width")
|
||||
else DEFAULT_DETECT_DIMENSIONS["width"]
|
||||
)
|
||||
camera_config.detect.height = (
|
||||
stream_info["height"]
|
||||
if stream_info.get("height")
|
||||
else DEFAULT_DETECT_DIMENSIONS["height"]
|
||||
if need_detect_dimensions or need_record_fourcc:
|
||||
stream_info = {"width": 0, "height": 0, "fourcc": None}
|
||||
try:
|
||||
stream_info = asyncio.run(get_video_properties(input.path))
|
||||
except Exception:
|
||||
logger.warn(
|
||||
f"Error detecting stream parameters automatically for {input.path} Applying default values."
|
||||
)
|
||||
stream_info = {"width": 0, "height": 0, "fourcc": None}
|
||||
|
||||
if need_detect_dimensions:
|
||||
camera_config.detect.width = (
|
||||
stream_info["width"]
|
||||
if stream_info.get("width")
|
||||
else DEFAULT_DETECT_DIMENSIONS["width"]
|
||||
)
|
||||
camera_config.detect.height = (
|
||||
stream_info["height"]
|
||||
if stream_info.get("height")
|
||||
else DEFAULT_DETECT_DIMENSIONS["height"]
|
||||
)
|
||||
|
||||
if need_record_fourcc:
|
||||
# Apple only supports HEVC if it is hvc1 (vs. hev1)
|
||||
camera_config.ffmpeg.output_args._force_record_hvc1 = (
|
||||
stream_info["fourcc"] == "hevc"
|
||||
if stream_info.get("hevc")
|
||||
else False
|
||||
)
|
||||
|
||||
# Default min_initialized configuration
|
||||
min_initialized = camera_config.detect.fps / 2
|
||||
|
@ -461,9 +461,18 @@ PRESETS_RECORD_OUTPUT = {
|
||||
}
|
||||
|
||||
|
||||
def parse_preset_output_record(arg: Any) -> list[str]:
|
||||
def parse_preset_output_record(arg: Any, force_record_hvc1: bool) -> list[str]:
|
||||
"""Return the correct preset if in preset format otherwise return None."""
|
||||
if not isinstance(arg, str):
|
||||
return None
|
||||
|
||||
return PRESETS_RECORD_OUTPUT.get(arg, None)
|
||||
preset = PRESETS_RECORD_OUTPUT.get(arg, None)
|
||||
|
||||
if not preset:
|
||||
return None
|
||||
|
||||
if force_record_hvc1:
|
||||
# Apple only supports HEVC if it is hvc1 (vs. hev1)
|
||||
preset += ["-tag:v", "hvc1"]
|
||||
|
||||
return preset
|
||||
|
@ -505,10 +505,20 @@ async def get_video_properties(url, get_duration=False) -> dict[str, any]:
|
||||
# Get the height of frames in the video stream
|
||||
height = video.get(cv2.CAP_PROP_FRAME_HEIGHT)
|
||||
|
||||
# Get the stream encoding
|
||||
fourcc_int = int(video.get(cv2.CAP_PROP_FOURCC))
|
||||
fourcc = (
|
||||
chr((fourcc_int >> 0) & 255)
|
||||
+ chr((fourcc_int >> 8) & 255)
|
||||
+ chr((fourcc_int >> 16) & 255)
|
||||
+ chr((fourcc_int >> 24) & 255)
|
||||
)
|
||||
|
||||
# Release the video stream
|
||||
video.release()
|
||||
|
||||
result["width"] = round(width)
|
||||
result["height"] = round(height)
|
||||
result["fourcc"] = fourcc
|
||||
|
||||
return result
|
||||
|
Loading…
Reference in New Issue
Block a user