Search code examples
pythongradio

Gradio 5.0.2 Image: how to dispatch the start_recording event


On my WSL with Ubuntu 22.04 and Python 3.10 and Node 20.10, I would like to receive the "start_recording" event from gr.Image, running in "webcam" mode. Since the event is dispatched in the WebCam.svelte frontend, how can I get it in my Python backend? I have tried building a custom component, templated from gr.Image:

class MyImage(StreamingInput, Component):

    EVENTS = [
        Events.clear,
        Events.change,
        Events.stream,
        Events.select,
        Events.upload,
        Events.input,
        Events.start_recording, # Added
    ]

and then

import gradio as gr
from gradio_myimage import MyImage

def recording_started():
    print('Yipee')

with gr.Blocks() as demo:
    cam = MyImage(sources=['webcam'], streaming=True, interactive=True)
    cam.start_recording(recording_started)
demo.launch()

But I get an AttributeError: 'tuple' object has no attribute 'start_recording'

Can anyone please give me a hint, what's missing? Thank you in advance..


Solution

  • I have faced this problem. Actually, basic Events (from gradio.events import Events, EventListener) class does not have your defined event start_recording, so you need to create a child class like CustomEvents to add your new event.

    class CustomEvents(Events):
        calibrated = EventListener(
            "start_recording",
            doc="...",
        )
    

    then in your component's class, use CustomEvents instead.

    class MyImage(StreamingInput, Component):
    
        EVENTS = [
            CustomEvents.clear,
            CustomEvents.change,
            CustomEvents.stream,
            CustomEvents.select,
            CustomEvents.upload,
            CustomEvents.input,
            CustomEvents.start_recording, # Added
        ]
    

    After that, you need to pip install -e . so that your package is updated, and you can import to run it. The newly added event will be generated a function in the .pyi file, hence your custom element can be use it.