ensure video resets state correctly when a new src is loaded (#3117)

* improve is playing, remove console error

* add video demo to all_demos

* fix demo

* fix bug

* changelog + notebooks

* cleanup

* fix choppy video resizing

* reduce flashing due to prediction request, video loading + rendering

* fix notebooks

* changelog
This commit is contained in:
pngwn 2023-02-03 17:36:31 +00:00 committed by GitHub
parent 63d5efcfc4
commit a23bc03aeb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 86 additions and 19 deletions

View File

@ -15,6 +15,7 @@ By [@freddyaboulton](https://github.com/freddyaboulton) in [PR 3089](https://git
## Bug Fixes:
- Fixes URL resolution on Windows by [@abidlabs](https://github.com/abidlabs) in [PR 3108](https://github.com/gradio-app/gradio/pull/3108)
- Ensure the Video component correctly resets the UI state whe a new video source is loaded and reduce choppiness of UI by [@pngwn](https://github.com/abidlabs) in [PR 3117](https://github.com/gradio-app/gradio/pull/3117)
## Documentation Changes:
- Added a guide on the 4 kinds of Gradio Interfaces by [@yvrjsharma](https://github.com/yvrjsharma) and [@abidlabs](https://github.com/abidlabs) in [PR 3003](https://github.com/gradio-app/gradio/pull/3003)

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1 +1 @@
{"cells": [{"cell_type": "markdown", "id": 302934307671667531413257853548643485645, "metadata": {}, "source": ["# Gradio Demo: video_component"]}, {"cell_type": "code", "execution_count": null, "id": 272996653310673477252411125948039410165, "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": 288918539441861185822528903084949547379, "metadata": {}, "outputs": [], "source": ["import gradio as gr \n", "\n", "css = \"footer {display: none !important;} .gradio-container {min-height: 0px !important;}\"\n", "\n", "with gr.Blocks(css=css) as demo:\n", " gr.Video()\n", "\n", "demo.launch()"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}
{"cells": [{"cell_type": "markdown", "id": 302934307671667531413257853548643485645, "metadata": {}, "source": ["# Gradio Demo: video_component"]}, {"cell_type": "code", "execution_count": null, "id": 272996653310673477252411125948039410165, "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": 288918539441861185822528903084949547379, "metadata": {}, "outputs": [], "source": ["# Downloading files from the demo repo\n", "import os\n", "os.mkdir('files')\n", "!wget -q -O files/a.mp4 https://github.com/gradio-app/gradio/raw/main/demo/video_component/files/a.mp4\n", "!wget -q -O files/b.mp4 https://github.com/gradio-app/gradio/raw/main/demo/video_component/files/b.mp4\n", "!wget -q -O files/world.mp4 https://github.com/gradio-app/gradio/raw/main/demo/video_component/files/world.mp4"]}, {"cell_type": "code", "execution_count": null, "id": 44380577570523278879349135829904343037, "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "import os\n", "\n", "\n", "a = os.path.join(os.path.abspath(''), \"files/world.mp4\") # Video\n", "b = os.path.join(os.path.abspath(''), \"files/a.mp4\") # Video\n", "c = os.path.join(os.path.abspath(''), \"files/b.mp4\") # Video\n", "\n", "\n", "demo = gr.Interface(\n", " fn=lambda x: x,\n", " inputs=gr.Video(type=\"file\"),\n", " outputs=gr.Video(),\n", " examples=[\n", " [a],\n", " [b],\n", " [c],\n", " ],\n", ")\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}

View File

@ -1,8 +1,22 @@
import gradio as gr
import gradio as gr
import os
css = "footer {display: none !important;} .gradio-container {min-height: 0px !important;}"
with gr.Blocks(css=css) as demo:
gr.Video()
a = os.path.join(os.path.dirname(__file__), "files/world.mp4") # Video
b = os.path.join(os.path.dirname(__file__), "files/a.mp4") # Video
c = os.path.join(os.path.dirname(__file__), "files/b.mp4") # Video
demo.launch()
demo = gr.Interface(
fn=lambda x: x,
inputs=gr.Video(type="file"),
outputs=gr.Video(),
examples=[
[a],
[b],
[c],
],
)
if __name__ == "__main__":
demo.launch()

View File

@ -34,6 +34,7 @@ def copy_all_demos(source_dir: str, dest_dir: str):
"stt_or_tts",
"stream_audio",
"stream_frames",
"video_component",
"zip_files",
]
for demo in demos_to_copy:

View File

@ -8,13 +8,18 @@
export let samples_dir: string;
let video: HTMLVideoElement;
onMount(() => {
async function init() {
video.muted = true;
video.playsInline = true;
video.controls = false;
video.setAttribute("muted", "");
video.play();
await video.play();
video.pause();
}
onMount(() => {
init();
});
</script>

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { tick } from "svelte";
import { onMount, tick } from "svelte";
import { Play, Pause, Maximise, Undo } from "@gradio/icons";
export let src: string;
@ -39,9 +39,16 @@
time = (duration * (clientX - left)) / (right - left);
}
function play_pause() {
if (paused) video.play();
else video.pause();
async function play_pause() {
const isPlaying =
video.currentTime > 0 &&
!video.paused &&
!video.ended &&
video.readyState > video.HAVE_CURRENT_DATA;
if (!isPlaying) {
await video.play();
} else video.pause();
}
function handle_click(e: MouseEvent) {
@ -61,20 +68,53 @@
return `${minutes}:${_seconds}`;
}
async function _load() {
async function checkforVideo() {
transition = "0s";
await tick();
wrap_opacity = 0.8;
opacity = 0;
await tick();
video.currentTime = 9999;
setTimeout(async () => {
video.currentTime = 0.0;
}, 50);
var b = setInterval(async () => {
if (video.readyState >= 1) {
height = (video.videoHeight / video.videoWidth) * width;
}
if (video.readyState >= 3) {
video.currentTime = 9999;
paused = true;
transition = "0.2s";
setTimeout(async () => {
video.currentTime = 0.0;
opacity = 1;
wrap_opacity = 1;
}, 50);
clearInterval(b);
}
}, 15);
}
async function _load() {
checkforVideo();
}
$: src && _load();
let height: number;
let width: number;
let opacity: number = 0;
let wrap_opacity: number = 0;
let transition: string = "0.5s";
</script>
<div>
<div
style:opacity={wrap_opacity}
class="wrap"
style:height={`${src && height}px` || `auto`}
>
<video
bind:clientHeight={height}
bind:clientWidth={width}
{src}
preload="auto"
on:mousemove={video_move}
@ -87,14 +127,17 @@
bind:paused
bind:this={video}
class:mirror
style:opacity
style:transition
>
<track kind="captions" />
</video>
<div
class="controls"
style:opacity={duration && show_controls ? 1 : 0}
style:opacity={opacity === 1 && duration && show_controls ? 1 : 0}
on:mousemove={video_move}
style:transition
>
<div class="inner">
<span class="icon" on:click={play_pause}>
@ -193,4 +236,7 @@
font-size: var(--scale-000);
font-family: var(--font-mono);
}
.wrap {
background-color: var(--color-background-secondary);
}
</style>