I want to display a different video in the gr.components.Video() after the button is clicked.
def update_video(input_video):
video = input_video.replace('.mp4', '_out.mp4')
return [gr.components.Video.update(value=video)]
with gr.Blocks(theme=gr.themes.Soft()) as interface:
inputs = gr.components.Video()
update = gr.Button('Update')
update.click(update_video, inputs=inputs, outputs=[inputs])
interface.launch(height=700)
Tried the code above it results in an empty video box.
Running your code, uploading an .mp4
video file and clicking on the Update
button results in the following exception:
AttributeError: type object 'Video' has no attribute 'update'
This is most likely because you are using a recent version of Gradio. In Gradio 4.0, the update()
method was removed (see Gradio 4.0 changelog)
The recommended way for updating components is now to have your event listener function return the updated value of the corresponding output Component. This might not really be necessary for your use case though. For the full details, check out the Passing Input Into a Component Normally
section of this answer.
Modifying your code to accomodate the reccomended method of updating Gradio components:
import shutil
import gradio as gr
def update_video(input_video):
old_video_path = input_video
new_video_path = input_video.replace('.mp4', '_out.mp4')
# Replace shutil.copyfile with whatever processing you are doing
shutil.copyfile(old_video_path, new_video_path)
# Return the updated video component.
# You only need to specify in the arguments the things you wish to
# change. In this case we're only interested in the `value` but
# it can also be `label`, `scale`, `visibility` et cetera
return gr.Video(value=new_video_path)
with gr.Blocks(theme=gr.themes.Soft()) as interface:
# gr.components.Video is equivalent to gr.Video
inputs = gr.Video()
update = gr.Button('Update')
update.click(update_video, inputs=inputs, outputs=[inputs])
interface.launch(height=700)
Just make sure that as you're modifying the path of the video file, the new path points to a valid video file that can be played.
However, in the first place, you don't actually need to explicitly update the gr.Video
component.
In the update.click
event listener, you are already passing the output of the update_video
event listener function into the inputs
gr.Video
component.
update.click(
update_video, # The event listener function
inputs=inputs, # Where inputs into `update_video` come from
outputs=[inputs] # Where output from `update_video` will go.
# It can be either be what the `inputs` `gr.Video`
# component expects as input, or it can be an
# update for the `inputs` `gr.Video` component
)
Because of that, you'll be able to replicate the same behaviour as above by just retuning the modified filepath in your update_video
event listener function like so:
import shutil
import gradio as gr
def update_video(input_video):
old_video_path = input_video
new_video_path = input_video.replace('.mp4', '_out.mp4')
# Replace shutil.copyfile with whatever processing you are doing
shutil.copyfile(old_video_path, new_video_path)
# Simply return the new video path
return new_video_path
with gr.Blocks(theme=gr.themes.Soft()) as interface:
# gr.components.Video is equivalent to gr.Video
inputs = gr.Video()
update = gr.Button('Update')
update.click(update_video, inputs=inputs, outputs=[inputs])
interface.launch(height=700)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With