File size: 2,780 Bytes
88fe4e7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import gradio as gr

def wire_events(demo, components, assistant):
    c = components

    def handle_describe(webcam_img, upload_img, task, voice):
        is_webcam = webcam_img is not None
        img = webcam_img if is_webcam else upload_img
        if img is None:
            return gr.update(), gr.update(), f'<div id="sightline-status">Please provide an image.</div>'
            
        import numpy as np
        import cv2
        # If the image came from the webcam, it is likely horizontally mirrored by Gradio.
        # We must un-mirror it so text and spatial relationships are correct!
        if is_webcam and isinstance(img, np.ndarray):
            img = cv2.flip(img, 1)
            
        text, audio, status = assistant.process_image(img, task, voice, force=True)
        return text or gr.update(), audio or gr.update(), f'<div id="sightline-status">{status}</div>'

    c["describe_btn"].click(
        handle_describe,
        inputs=[c["webcam"], c["upload"], c["task_radio"], c["voice_dropdown"]],
        outputs=[c["caption_box"], c["audio_player"], c["status_bar"]]
    )

    def toggle_rt(is_active):
        new_state = not is_active
        btn_text = "⚫ Stop Realtime (R)" if new_state else "⚫ Start Realtime (R)"
        status_msg = "Realtime Started" if new_state else "Realtime Paused"
        return new_state, gr.update(value=btn_text), f'<div id="sightline-status">{status_msg}</div>'

    c["realtime_btn"].click(
        toggle_rt,
        inputs=[c["rt_state"]],
        outputs=[c["rt_state"], c["realtime_btn"], c["status_bar"]]
    )

    def handle_rt_stream(image, task, voice, is_active):
        print(f"DEBUG stream: is_active={is_active}, task={task}, voice={voice}")
        if is_active is False:
            return gr.update(), gr.update(), f'<div id="sightline-status">Realtime Paused</div>'
        if not is_active:
            # Fallback if None
            is_active = True
            
        if image is None:
            return gr.update(), gr.update(), f'<div id="sightline-status">No Camera</div>'
            
        import numpy as np
        import cv2
        # Un-mirror the webcam feed for backend processing
        if isinstance(image, np.ndarray):
            image = cv2.flip(image, 1)
            
        text, audio, status = assistant.process_image(image, task, voice, force=False)
        return text or gr.update(), audio or gr.update(), f'<div id="sightline-status">{status}</div>'

    c["webcam"].stream(
        handle_rt_stream,
        inputs=[c["webcam"], c["task_radio"], c["voice_dropdown"], c["rt_state"]],
        outputs=[c["caption_box"], c["audio_player"], c["status_bar"]],
        stream_every=3.0
    )