Skip to content

Commit

Permalink
Merge pull request #123 from rsteckler/image-persist
Browse files Browse the repository at this point in the history
Added option to persist exposed images
  • Loading branch information
valentinfrlch authored Dec 26, 2024
2 parents 32542f9 + b8a359d commit 63eda03
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 3 deletions.
4 changes: 3 additions & 1 deletion custom_components/llmvision/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
TEMPERATURE,
INCLUDE_FILENAME,
EXPOSE_IMAGES,
EXPOSE_IMAGES_PERSIST,
GENERATE_TITLE,
SENSOR_ENTITY,
)
Expand Down Expand Up @@ -251,6 +252,7 @@ def __init__(self, data_call):
self.max_tokens = int(data_call.data.get(MAXTOKENS, 100))
self.include_filename = data_call.data.get(INCLUDE_FILENAME, False)
self.expose_images = data_call.data.get(EXPOSE_IMAGES, False)
self.expose_images_persist = data_call.data.get(EXPOSE_IMAGES_PERSIST, False)
self.generate_title = data_call.data.get(GENERATE_TITLE, False)
self.sensor_entity = data_call.data.get(SENSOR_ENTITY)
# ------------ Added during call ------------
Expand Down Expand Up @@ -308,11 +310,11 @@ async def video_analyzer(data_call):
target_width=call.target_width,
include_filename=call.include_filename,
expose_images=call.expose_images,
expose_images_persist=call.expose_images_persist,
frigate_retry_attempts=call.frigate_retry_attempts,
frigate_retry_seconds=call.frigate_retry_seconds
)
response = await request.call(call)

await _remember(hass, call, start, response)
return response

Expand Down
1 change: 1 addition & 0 deletions custom_components/llmvision/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
TEMPERATURE = 'temperature'
INCLUDE_FILENAME = 'include_filename'
EXPOSE_IMAGES = 'expose_images'
EXPOSE_IMAGES_PERSIST = 'expose_images_persist'
GENERATE_TITLE = 'generate_title'
SENSOR_ENTITY = 'sensor_entity'

Expand Down
11 changes: 9 additions & 2 deletions custom_components/llmvision/media_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,13 +318,14 @@ async def add_images(self, image_entities, image_paths, target_width, include_fi
raise ServiceValidationError(f"Error: {e}")
return self.client

async def add_videos(self, video_paths, event_ids, max_frames, target_width, include_filename, expose_images, frigate_retry_attempts, frigate_retry_seconds):
async def add_videos(self, video_paths, event_ids, max_frames, target_width, include_filename, expose_images, expose_images_persist, frigate_retry_attempts, frigate_retry_seconds):
"""Wrapper for client.add_frame for videos"""
tmp_clips_dir = f"/config/custom_components/{DOMAIN}/tmp_clips"
tmp_frames_dir = f"/config/custom_components/{DOMAIN}/tmp_frames"

if not video_paths:
video_paths = []
processed_event_ids = []
if event_ids:
for event_id in event_ids:
try:
Expand All @@ -348,14 +349,17 @@ async def add_videos(self, video_paths, event_ids, max_frames, target_width, inc
f"Saved frigate clip to {clip_path} (temporarily)")
# append to video_paths
video_paths.append(clip_path)
processed_event_ids.append(event_id)

except AttributeError as e:
raise ServiceValidationError(
f"Failed to fetch frigate clip {event_id}: {e}")
if video_paths:
_LOGGER.debug(f"Processing videos: {video_paths}")
video_count = 0
for video_path in video_paths:
try:
current_event_id = processed_event_ids[video_count]
video_path = video_path.strip()
if os.path.exists(video_path):
# create tmp dir to store extracted frames
Expand Down Expand Up @@ -421,7 +425,10 @@ async def add_videos(self, video_paths, event_ids, max_frames, target_width, inc
for frame_path, _ in sorted_frames:
resized_image = await self.resize_image(image_path=frame_path, target_width=target_width)
if expose_images:
await self._save_clip(image_path="/config/www/llmvision/" + frame_path.split("/")[-1], image_data=resized_image)
persist_filename = f"/config/www/llmvision/" + frame_path.split("/")[-1]
if expose_images_persist:
persist_filename = f"/config/www/llmvision/{current_event_id}-" + frame_path.split("/")[-1]
await self._save_clip(image_data=resized_image, image_path=persist_filename)
self.client.add_frame(
base64_image=resized_image,
filename=video_path.split('/')[-1].split('.')[-2] + " (frame " + str(counter) + ")" if include_filename else "Video frame " + str(counter)
Expand Down
9 changes: 9 additions & 0 deletions custom_components/llmvision/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,15 @@ video_analyzer:
default: false
selector:
boolean:
expose_images_persist:
name: Persist Exposed Images
description: Normally exposed images are re-written with each new event. Setting this to true will include the Frigate eventID, if available, as part of the filename. If there is no
Frigate eventID, a guid will be used instead.
required: false
example: false
default: false
selector:
boolean:

stream_analyzer:
name: Stream Analyzer
Expand Down

0 comments on commit 63eda03

Please sign in to comment.