Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

4549 autoplay #4705

Merged
merged 17 commits into from Jun 28, 2023
Merged

4549 autoplay #4705

merged 17 commits into from Jun 28, 2023

Conversation

pngwn
Copy link
Member

@pngwn pngwn commented Jun 28, 2023

Description

Closes #4549. Closes #4707

Updating the src now triggers autoplay as expected. Tests added to prevent regression.

I also experienced some flake so I have adjusted one of our test utilities a little to prevent that in the future.

@gradio-pr-bot
Copy link
Contributor

gradio-pr-bot commented Jun 28, 2023

🎉 The demo notebooks match the run.py files! 🎉

Comment on lines +23 to +26
beforeAll(() => {
window.HTMLMediaElement.prototype.play = vi.fn();
window.HTMLMediaElement.prototype.pause = vi.fn();
});
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tired to mock this in a slightly more clever way but it didn't work at all, this does work but I'd like to figure out a batter way to do it in the future.

afterEach(() => cleanup());

test("renders provided value and label", async () => {
const { getByTestId, queryAllByText } = render(Audio, {
const { getByTestId, queryAllByText } = await render(Audio, {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

render is now async because it ensure the DOM is updated before resolving. We need to await it to ensure this has all happened.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting - the same function can be be simultaneously async and not async? 🤯

@gradio-pr-bot
Copy link
Contributor

All the demos for this PR have been deployed at https://huggingface.co/spaces/gradio-pr-deploys/pr-4705-all-demos


const startButton = getByTestId<HTMLAudioElement>("dynamic-dynamic-audio");
const fn = spyOn(startButton, "play");
startButton.dispatchEvent(new Event("loadeddata"));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to trigger this even because this is the heuristic we use to start 'autoplaying'. See above about better mocks, i'd like to clean this up in the future.

Comment on lines 220 to 234
async function handle_playback(): Promise<void> {
if (autoplay) {
node.pause();
await node.play();
}
}

node.addEventListener("loadeddata", handle_playback);
node.addEventListener("timeupdate", clamp_playback);

return {
destroy: () => node.removeEventListener("timeupdate", clamp_playback)
destroy(): void {
node.removeEventListener("loadeddata", handle_playback);
node.removeEventListener("timeupdate", clamp_playback);
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is basically the fix.

Comment on lines 54 to 66
function loaded(node: HTMLAudioElement): ActionReturn {
async function handle_playback(): Promise<void> {
if (autoplay) {
await node.play();
}
}

node.addEventListener("loadeddata", handle_playback);

return {
destroy: () => node.removeEventListener("loadeddata", handle_playback)
};
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I'll deupe all of this.

@@ -161,6 +161,8 @@
)
.join(" ");
}

$: console.log(container_element?.tagName);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove

@pngwn
Copy link
Member Author

pngwn commented Jun 28, 2023

Not happy now I've reviewed, will change to wip.

@pngwn pngwn marked this pull request as draft June 28, 2023 10:33
@pngwn
Copy link
Member Author

pngwn commented Jun 28, 2023

This can be tested with the following snippet:

import gradio as gr

TEST_AUDIO_A = "a.mp3"
TEST_AUDIO_B = "b.wav"
audio_files = [TEST_AUDIO_A, TEST_AUDIO_B]
a_idx = 0

TEST_VIDEO_A = "a.mp4"
TEST_VIDEO_B = "b.mp4"
video_files = [TEST_VIDEO_A, TEST_VIDEO_B]
v_idx = 0

def output_audio():
    global a_idx
    file = audio_files[a_idx]
    a_idx = 1 if a_idx == 0 else 0
    return file

def output_video():
    global v_idx
    file = video_files[v_idx]
    v_idx = 1 if v_idx == 0 else 0
    return file

with gr.Blocks() as demo:
    audio = gr.Audio(type="filepath", label="Audio", autoplay=True)
    button = gr.Button(value="play audio")
    button.click(output_audio, outputs=[audio])
    video = gr.Video(type="filepath", label="Video", autoplay=True)
    button_two = gr.Button(value="play video")
    button_two.click(output_video, outputs=[video])
    
demo.launch()

Use some audio files from the demos folder. When swapping between them they should autoplay

@pngwn pngwn marked this pull request as ready for review June 28, 2023 12:30
@pngwn
Copy link
Member Author

pngwn commented Jun 28, 2023

We didn't really have any video tests so i added a few.

@freddyaboulton freddyaboulton mentioned this pull request Jun 28, 2023
Copy link
Collaborator

@freddyaboulton freddyaboulton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the fix @pngwn ! Verified it works. Left some nits - mostly questions for me.

js/app/src/components/Video/Video.test.ts Outdated Show resolved Hide resolved
js/app/src/components/Video/Video.test.ts Show resolved Hide resolved
js/video/src/utils.ts Outdated Show resolved Hide resolved
js/app/src/components/Audio/Audio.test.ts Outdated Show resolved Hide resolved
@pngwn pngwn merged commit 1650e1d into main Jun 28, 2023
9 checks passed
@pngwn pngwn deleted the 4549-autoplay branch June 28, 2023 18:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Video Unit tests autoplay not working when providing new files inside function
3 participants