mirror of
				https://github.com/blakeblackshear/frigate.git
				synced 2025-10-27 10:52:11 +01:00 
			
		
		
		
	Handle in progress previews export and fix time check bug (#14930)
* Handle in progress previews and fix time check bug * Formatting
This commit is contained in:
		
							parent
							
								
									6c86827d3a
								
							
						
					
					
						commit
						9c20cd5f7b
					
				| @ -19,6 +19,7 @@ from frigate.record.export import ( | ||||
|     PlaybackSourceEnum, | ||||
|     RecordingExporter, | ||||
| ) | ||||
| from frigate.util.builtin import is_current_hour | ||||
| 
 | ||||
| logger = logging.getLogger(__name__) | ||||
| 
 | ||||
| @ -86,7 +87,7 @@ def export_recording( | ||||
|             .count() | ||||
|         ) | ||||
| 
 | ||||
|         if previews_count <= 0: | ||||
|         if not is_current_hour(start_time) and previews_count <= 0: | ||||
|             return JSONResponse( | ||||
|                 content=( | ||||
|                     {"success": False, "message": "No previews found for time range"} | ||||
|  | ||||
| @ -144,6 +144,9 @@ def output_frames( | ||||
|         # check for any cameras that are currently offline | ||||
|         # and need to generate a preview | ||||
|         if generated_preview: | ||||
|             logger.debug( | ||||
|                 "Checking for offline cameras because another camera generated a preview." | ||||
|             ) | ||||
|             for camera, time in preview_write_times.copy().items(): | ||||
|                 if time != 0 and frame_time - time > 10: | ||||
|                     preview_recorders[camera].flag_offline(frame_time) | ||||
|  | ||||
| @ -27,6 +27,7 @@ from frigate.ffmpeg_presets import ( | ||||
|     parse_preset_hardware_acceleration_encode, | ||||
| ) | ||||
| from frigate.models import Export, Previews, Recordings | ||||
| from frigate.util.builtin import is_current_hour | ||||
| 
 | ||||
| logger = logging.getLogger(__name__) | ||||
| 
 | ||||
| @ -235,6 +236,32 @@ class RecordingExporter(threading.Thread): | ||||
| 
 | ||||
|     def get_preview_export_command(self, video_path: str) -> list[str]: | ||||
|         playlist_lines = [] | ||||
|         codec = "-c copy" | ||||
| 
 | ||||
|         if is_current_hour(self.start_time): | ||||
|             # get list of current preview frames | ||||
|             preview_dir = os.path.join(CACHE_DIR, "preview_frames") | ||||
|             file_start = f"preview_{self.camera}" | ||||
|             start_file = f"{file_start}-{self.start_time}.{PREVIEW_FRAME_TYPE}" | ||||
|             end_file = f"{file_start}-{self.end_time}.{PREVIEW_FRAME_TYPE}" | ||||
| 
 | ||||
|             for file in sorted(os.listdir(preview_dir)): | ||||
|                 if not file.startswith(file_start): | ||||
|                     continue | ||||
| 
 | ||||
|                 if file < start_file: | ||||
|                     continue | ||||
| 
 | ||||
|                 if file > end_file: | ||||
|                     break | ||||
| 
 | ||||
|                 playlist_lines.append(f"file '{os.path.join(preview_dir, file)}'") | ||||
|                 playlist_lines.append("duration 0.12") | ||||
| 
 | ||||
|             if playlist_lines: | ||||
|                 last_file = playlist_lines[-2] | ||||
|                 playlist_lines.append(last_file) | ||||
|                 codec = "-c:v libx264" | ||||
| 
 | ||||
|         # get full set of previews | ||||
|         export_previews = ( | ||||
| @ -277,7 +304,7 @@ class RecordingExporter(threading.Thread): | ||||
| 
 | ||||
|         if self.playback_factor == PlaybackFactorEnum.realtime: | ||||
|             ffmpeg_cmd = ( | ||||
|                 f"{self.config.ffmpeg.ffmpeg_path} -hide_banner {ffmpeg_input} -c copy -movflags +faststart {video_path}" | ||||
|                 f"{self.config.ffmpeg.ffmpeg_path} -hide_banner {ffmpeg_input} {codec} -movflags +faststart {video_path}" | ||||
|             ).split(" ") | ||||
|         elif self.playback_factor == PlaybackFactorEnum.timelapse_25x: | ||||
|             ffmpeg_cmd = ( | ||||
|  | ||||
| @ -282,6 +282,17 @@ def get_tomorrow_at_time(hour: int) -> datetime.datetime: | ||||
|     ) | ||||
| 
 | ||||
| 
 | ||||
| def is_current_hour(timestamp: int) -> bool: | ||||
|     """Returns if timestamp is in the current UTC hour.""" | ||||
|     start_of_next_hour = ( | ||||
|         datetime.datetime.now(datetime.timezone.utc).replace( | ||||
|             minute=0, second=0, microsecond=0 | ||||
|         ) | ||||
|         + datetime.timedelta(hours=1) | ||||
|     ).timestamp() | ||||
|     return timestamp < start_of_next_hour | ||||
| 
 | ||||
| 
 | ||||
| def clear_and_unlink(file: Path, missing_ok: bool = True) -> None: | ||||
|     """clear file then unlink to avoid space retained by file descriptors.""" | ||||
|     if not missing_ok and not file.exists(): | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user