mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-11-21 19:07:46 +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,
|
default=RECORD_FFMPEG_OUTPUT_ARGS_DEFAULT,
|
||||||
title="Record role FFmpeg output arguments.",
|
title="Record role FFmpeg output arguments.",
|
||||||
)
|
)
|
||||||
|
_force_record_hvc1: bool = PrivateAttr(default=False)
|
||||||
|
|
||||||
|
|
||||||
class FfmpegConfig(FrigateBaseModel):
|
class FfmpegConfig(FrigateBaseModel):
|
||||||
@ -878,7 +879,10 @@ class CameraConfig(FrigateBaseModel):
|
|||||||
|
|
||||||
if "record" in ffmpeg_input.roles and self.record.enabled:
|
if "record" in ffmpeg_input.roles and self.record.enabled:
|
||||||
record_args = get_ffmpeg_arg_list(
|
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
|
or self.ffmpeg.output_args.record
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1161,21 +1165,24 @@ class FrigateConfig(FrigateBaseModel):
|
|||||||
if camera_config.ffmpeg.hwaccel_args == "auto":
|
if camera_config.ffmpeg.hwaccel_args == "auto":
|
||||||
camera_config.ffmpeg.hwaccel_args = config.ffmpeg.hwaccel_args
|
camera_config.ffmpeg.hwaccel_args = config.ffmpeg.hwaccel_args
|
||||||
|
|
||||||
if (
|
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
|
camera_config.detect.height is None
|
||||||
or camera_config.detect.width is None
|
or camera_config.detect.width is None
|
||||||
):
|
)
|
||||||
for input in camera_config.ffmpeg.inputs:
|
|
||||||
if "detect" in input.roles:
|
if need_detect_dimensions or need_record_fourcc:
|
||||||
stream_info = {"width": 0, "height": 0}
|
stream_info = {"width": 0, "height": 0, "fourcc": None}
|
||||||
try:
|
try:
|
||||||
stream_info = asyncio.run(get_video_properties(input.path))
|
stream_info = asyncio.run(get_video_properties(input.path))
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.warn(
|
logger.warn(
|
||||||
f"Error detecting stream resolution automatically for {input.path} Applying default values."
|
f"Error detecting stream parameters automatically for {input.path} Applying default values."
|
||||||
)
|
)
|
||||||
stream_info = {"width": 0, "height": 0}
|
stream_info = {"width": 0, "height": 0, "fourcc": None}
|
||||||
|
|
||||||
|
if need_detect_dimensions:
|
||||||
camera_config.detect.width = (
|
camera_config.detect.width = (
|
||||||
stream_info["width"]
|
stream_info["width"]
|
||||||
if stream_info.get("width")
|
if stream_info.get("width")
|
||||||
@ -1187,6 +1194,14 @@ class FrigateConfig(FrigateBaseModel):
|
|||||||
else DEFAULT_DETECT_DIMENSIONS["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
|
# Default min_initialized configuration
|
||||||
min_initialized = camera_config.detect.fps / 2
|
min_initialized = camera_config.detect.fps / 2
|
||||||
if camera_config.detect.min_initialized is None:
|
if camera_config.detect.min_initialized is None:
|
||||||
|
@ -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."""
|
"""Return the correct preset if in preset format otherwise return None."""
|
||||||
if not isinstance(arg, str):
|
if not isinstance(arg, str):
|
||||||
return None
|
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
|
# Get the height of frames in the video stream
|
||||||
height = video.get(cv2.CAP_PROP_FRAME_HEIGHT)
|
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
|
# Release the video stream
|
||||||
video.release()
|
video.release()
|
||||||
|
|
||||||
result["width"] = round(width)
|
result["width"] = round(width)
|
||||||
result["height"] = round(height)
|
result["height"] = round(height)
|
||||||
|
result["fourcc"] = fourcc
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
Loading…
Reference in New Issue
Block a user