Use Start/Stop button to record live audio using Gradio app

Hi All,

I need help with a problem. I want to add a button in my Gradio app to start/stop audio recording. Basically, what I am trying to do is place a button on the UI. When a user clicks on the this button(let’s say “Speak”), then audio recoding starts and the button text changes to “Stop”. When user clicks on the button again(which now says “Stop”) then audio recording stops.

I want something like this:

Hi All,

I figured out a solution to this problem. Here is the code, hope it helps!

import gradio as gr


def click_js():
    return """function audioRecord() {
    var xPathRes = document.evaluate ('//*[@id="audio"]//button', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); 
    xPathRes.singleNodeValue.click();}"""


def action(btn):
    """Changes button text on click"""
    if btn == 'Speak': return 'Stop'
    else: return 'Speak'


def check_btn(btn):
    """Checks for correct button text before invoking transcribe()"""
    if btn != 'Speak': raise Exception('Recording...')


def transcribe():
    return 'Success'


with gr.Blocks() as demo:
    msg = gr.Textbox()
    audio_box = gr.Audio(label="Audio", source="microphone", type="filepath", elem_id='audio')

    with gr.Row():
        audio_btn = gr.Button('Speak')
        clear = gr.Button("Clear")

    audio_btn.click(fn=action, inputs=audio_btn, outputs=audio_btn).\
              then(fn=lambda: None, _js=click_js()).\
              then(fn=check_btn, inputs=audio_btn).\
              success(fn=transcribe, outputs=msg)

    clear.click(lambda: None, None, msg, queue=False)

demo.queue().launch(debug=True)

For Gradio 4 users:

import gradio as gr


def click_js():
    return """function audioRecord() {
    var xPathRes = document.evaluate ('//*[contains(@class, "record")]', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); 
    xPathRes.singleNodeValue.click();}"""


def action(btn):
    """Changes button text on click"""
    if btn == 'Speak': return 'Stop'
    else: return 'Speak'


def check_btn(btn):
    """Checks for correct button text before invoking transcribe()"""
    if btn != 'Speak': raise Exception('Recording...')


def transcribe():
    return 'Success'

with gr.Blocks() as demo:
    msg = gr.Textbox()
    audio_box = gr.Audio(label="Audio", sources="microphone", type="filepath", elem_id='audio')

    with gr.Row():
        audio_btn = gr.Button('Speak')
        clear = gr.Button("Clear")

    audio_btn.click(fn=action, inputs=audio_btn, outputs=audio_btn).\
              then(fn=lambda: None, js=click_js()).\
              then(fn=check_btn, inputs=audio_btn).\
              success(fn=transcribe, outputs=msg)

    clear.click(lambda: None, None, msg, queue=False)

demo.queue().launch(debug=True)