mirror of
				https://github.com/blakeblackshear/frigate.git
				synced 2025-10-27 10:52:11 +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