Spaces:
Sleeping
Sleeping
updates
Browse files
app.py
CHANGED
|
@@ -58,7 +58,7 @@ class VideoAnnotator:
|
|
| 58 |
annotated_files = self.api.list_repo_files(
|
| 59 |
repo_id=self.annotation_repo_id,
|
| 60 |
repo_type=self.annotation_repo_type,
|
| 61 |
-
path_in_repo="annotations"
|
| 62 |
)
|
| 63 |
# Extract base video names from annotation filenames
|
| 64 |
# e.g., "annotations/video1.mp4.jsonl" -> "video1.mp4"
|
|
@@ -80,12 +80,10 @@ class VideoAnnotator:
|
|
| 80 |
except Exception as e:
|
| 81 |
# Log error and fallback to using all videos if the check fails
|
| 82 |
logger.error(f"Could not list or process annotation files: {e}. Proceeding with all videos, but conflicts may occur.")
|
| 83 |
-
self.video_files = all_video_files
|
| 84 |
-
# --- End Edit ---
|
| 85 |
|
| 86 |
if not self.video_files:
|
| 87 |
logger.warning("No videos left to annotate!")
|
| 88 |
-
# Optionally, display a message in the UI here if possible
|
| 89 |
|
| 90 |
return len(self.video_files) > 0
|
| 91 |
except Exception as e:
|
|
@@ -198,9 +196,7 @@ class VideoAnnotator:
|
|
| 198 |
# --- End Edit ---
|
| 199 |
else:
|
| 200 |
logger.info("Already at the last video")
|
| 201 |
-
# --- Start Edit: Return only the save status as the last element ---
|
| 202 |
return self.get_current_video(), *[None] * len(ANNOTATION_CATEGORIES), "Already at the last video. " + save_status
|
| 203 |
-
# --- End Edit ---
|
| 204 |
|
| 205 |
def prev_video(self, *current_annotations):
|
| 206 |
# Save current annotations before moving to previous video
|
|
@@ -233,17 +229,14 @@ def create_interface():
|
|
| 233 |
|
| 234 |
if not success:
|
| 235 |
logger.error("Failed to load videos. Interface might not function correctly.")
|
| 236 |
-
# Handle the error appropriately, maybe show a message in the UI
|
| 237 |
|
| 238 |
with gr.Blocks() as demo:
|
| 239 |
gr.Markdown("# Cricket Video Annotation Tool")
|
| 240 |
|
| 241 |
-
# --- Start Edit: Define progress update function ---
|
| 242 |
total_categories = len(ANNOTATION_CATEGORIES)
|
| 243 |
def update_progress(*annotation_values):
|
| 244 |
filled_count = sum(1 for val in annotation_values if val is not None)
|
| 245 |
return f"**Progress:** {filled_count} / {total_categories} categories selected"
|
| 246 |
-
# --- End Edit ---
|
| 247 |
|
| 248 |
with gr.Row(): # Main row to hold video and controls side-by-side
|
| 249 |
with gr.Column(scale=2): # Column for Video Player and Nav Buttons
|
|
@@ -252,9 +245,7 @@ def create_interface():
|
|
| 252 |
label="Current Video",
|
| 253 |
height=350
|
| 254 |
)
|
| 255 |
-
# --- Start Edit: Rename status_textbox to status_display ---
|
| 256 |
status_display = gr.Textbox(label="Status", interactive=False) # For save/nav messages
|
| 257 |
-
# --- End Edit ---
|
| 258 |
with gr.Row():
|
| 259 |
prev_btn = gr.Button("Previous Video")
|
| 260 |
next_btn = gr.Button("Next Video")
|
|
@@ -287,15 +278,10 @@ def create_interface():
|
|
| 287 |
current_video = annotator.get_current_video()
|
| 288 |
if current_video:
|
| 289 |
logger.info(f"Setting initial video player value: {current_video}")
|
| 290 |
-
# The video_player will call annotator.get_current_video on load,
|
| 291 |
-
# so explicitly setting value might be redundant unless get_current_video changes state.
|
| 292 |
-
# video_player.value = current_video # Let's rely on the function loader
|
| 293 |
|
| 294 |
existing_annotations = annotator.load_existing_annotation()
|
| 295 |
if existing_annotations:
|
| 296 |
logger.info(f"Loading existing annotations: {existing_annotations}")
|
| 297 |
-
# Need to return initial values for components if loading annotations
|
| 298 |
-
# This part is tricky with function loading. Let's adjust.
|
| 299 |
|
| 300 |
# We might need a separate function to load initial state
|
| 301 |
# Or adjust how initial values are set.
|
|
@@ -307,32 +293,25 @@ def create_interface():
|
|
| 307 |
save_btn.click(
|
| 308 |
fn=annotator.save_annotation,
|
| 309 |
inputs=annotation_components,
|
| 310 |
-
# --- Start Edit: Output to status_display ---
|
| 311 |
outputs=status_display
|
| 312 |
-
# --- End Edit ---
|
| 313 |
)
|
| 314 |
|
| 315 |
next_btn.click(
|
| 316 |
fn=annotator.next_video,
|
| 317 |
inputs=annotation_components,
|
| 318 |
-
# --- Start Edit: Output status to status_display. Progress updates via radio changes. ---
|
| 319 |
# Outputs: video, clear all radios, update status_display
|
| 320 |
outputs=[video_player] + annotation_components + [status_display]
|
| 321 |
-
# --- End Edit ---
|
| 322 |
)
|
| 323 |
|
| 324 |
prev_btn.click(
|
| 325 |
fn=annotator.prev_video,
|
| 326 |
inputs=annotation_components,
|
| 327 |
-
# --- Start Edit: Output status to status_display. Progress updates via radio changes. ---
|
| 328 |
# Outputs: video, clear all radios, update status_display
|
| 329 |
outputs=[video_player] + annotation_components + [status_display]
|
| 330 |
-
# --- End Edit ---
|
| 331 |
)
|
| 332 |
|
| 333 |
return demo
|
| 334 |
|
| 335 |
if __name__ == "__main__":
|
| 336 |
demo = create_interface()
|
| 337 |
-
# Consider adding share=True for easier testing if needed
|
| 338 |
demo.launch(allowed_paths=["/"])
|
|
|
|
| 58 |
annotated_files = self.api.list_repo_files(
|
| 59 |
repo_id=self.annotation_repo_id,
|
| 60 |
repo_type=self.annotation_repo_type,
|
| 61 |
+
path_in_repo="annotations"
|
| 62 |
)
|
| 63 |
# Extract base video names from annotation filenames
|
| 64 |
# e.g., "annotations/video1.mp4.jsonl" -> "video1.mp4"
|
|
|
|
| 80 |
except Exception as e:
|
| 81 |
# Log error and fallback to using all videos if the check fails
|
| 82 |
logger.error(f"Could not list or process annotation files: {e}. Proceeding with all videos, but conflicts may occur.")
|
| 83 |
+
self.video_files = all_video_files
|
|
|
|
| 84 |
|
| 85 |
if not self.video_files:
|
| 86 |
logger.warning("No videos left to annotate!")
|
|
|
|
| 87 |
|
| 88 |
return len(self.video_files) > 0
|
| 89 |
except Exception as e:
|
|
|
|
| 196 |
# --- End Edit ---
|
| 197 |
else:
|
| 198 |
logger.info("Already at the last video")
|
|
|
|
| 199 |
return self.get_current_video(), *[None] * len(ANNOTATION_CATEGORIES), "Already at the last video. " + save_status
|
|
|
|
| 200 |
|
| 201 |
def prev_video(self, *current_annotations):
|
| 202 |
# Save current annotations before moving to previous video
|
|
|
|
| 229 |
|
| 230 |
if not success:
|
| 231 |
logger.error("Failed to load videos. Interface might not function correctly.")
|
|
|
|
| 232 |
|
| 233 |
with gr.Blocks() as demo:
|
| 234 |
gr.Markdown("# Cricket Video Annotation Tool")
|
| 235 |
|
|
|
|
| 236 |
total_categories = len(ANNOTATION_CATEGORIES)
|
| 237 |
def update_progress(*annotation_values):
|
| 238 |
filled_count = sum(1 for val in annotation_values if val is not None)
|
| 239 |
return f"**Progress:** {filled_count} / {total_categories} categories selected"
|
|
|
|
| 240 |
|
| 241 |
with gr.Row(): # Main row to hold video and controls side-by-side
|
| 242 |
with gr.Column(scale=2): # Column for Video Player and Nav Buttons
|
|
|
|
| 245 |
label="Current Video",
|
| 246 |
height=350
|
| 247 |
)
|
|
|
|
| 248 |
status_display = gr.Textbox(label="Status", interactive=False) # For save/nav messages
|
|
|
|
| 249 |
with gr.Row():
|
| 250 |
prev_btn = gr.Button("Previous Video")
|
| 251 |
next_btn = gr.Button("Next Video")
|
|
|
|
| 278 |
current_video = annotator.get_current_video()
|
| 279 |
if current_video:
|
| 280 |
logger.info(f"Setting initial video player value: {current_video}")
|
|
|
|
|
|
|
|
|
|
| 281 |
|
| 282 |
existing_annotations = annotator.load_existing_annotation()
|
| 283 |
if existing_annotations:
|
| 284 |
logger.info(f"Loading existing annotations: {existing_annotations}")
|
|
|
|
|
|
|
| 285 |
|
| 286 |
# We might need a separate function to load initial state
|
| 287 |
# Or adjust how initial values are set.
|
|
|
|
| 293 |
save_btn.click(
|
| 294 |
fn=annotator.save_annotation,
|
| 295 |
inputs=annotation_components,
|
|
|
|
| 296 |
outputs=status_display
|
|
|
|
| 297 |
)
|
| 298 |
|
| 299 |
next_btn.click(
|
| 300 |
fn=annotator.next_video,
|
| 301 |
inputs=annotation_components,
|
|
|
|
| 302 |
# Outputs: video, clear all radios, update status_display
|
| 303 |
outputs=[video_player] + annotation_components + [status_display]
|
|
|
|
| 304 |
)
|
| 305 |
|
| 306 |
prev_btn.click(
|
| 307 |
fn=annotator.prev_video,
|
| 308 |
inputs=annotation_components,
|
|
|
|
| 309 |
# Outputs: video, clear all radios, update status_display
|
| 310 |
outputs=[video_player] + annotation_components + [status_display]
|
|
|
|
| 311 |
)
|
| 312 |
|
| 313 |
return demo
|
| 314 |
|
| 315 |
if __name__ == "__main__":
|
| 316 |
demo = create_interface()
|
|
|
|
| 317 |
demo.launch(allowed_paths=["/"])
|