mirror of
https://github.com/gradio-app/gradio.git
synced 2024-12-27 02:30:17 +08:00
e450674ce4
* add webcam_height and webcam_width * update * A dictionary that allows developers to specify custom media constraints for the webcam stream. This parameter provides flexibility to control the video stream's properties, such as resolution, frame rate, and facing mode (e.g., front or rear camera on mobile devices). Overrides the default height and width settings when provided. * add changeset * add code * Add code * add changeset * Fix tests --------- Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com> Co-authored-by: freddyaboulton <alfonsoboulton@gmail.com>
176 lines
4.0 KiB
Svelte
176 lines
4.0 KiB
Svelte
<script lang="ts">
|
|
import { createEventDispatcher } from "svelte";
|
|
import { Upload, ModifyUpload } from "@gradio/upload";
|
|
import type { FileData, Client } from "@gradio/client";
|
|
import { BlockLabel } from "@gradio/atoms";
|
|
import { Webcam } from "@gradio/image";
|
|
import { Video } from "@gradio/icons";
|
|
|
|
import { prettyBytes, playable } from "./utils";
|
|
import Player from "./Player.svelte";
|
|
import type { I18nFormatter } from "@gradio/utils";
|
|
import { SelectSource } from "@gradio/atoms";
|
|
|
|
export let value: FileData | null = null;
|
|
export let subtitle: FileData | null = null;
|
|
export let sources:
|
|
| ["webcam"]
|
|
| ["upload"]
|
|
| ["webcam", "upload"]
|
|
| ["upload", "webcam"] = ["webcam", "upload"];
|
|
export let label: string | undefined = undefined;
|
|
export let show_download_button = false;
|
|
export let show_label = true;
|
|
export let mirror_webcam = false;
|
|
export let include_audio: boolean;
|
|
export let autoplay: boolean;
|
|
export let root: string;
|
|
export let i18n: I18nFormatter;
|
|
export let active_source: "webcam" | "upload" = "webcam";
|
|
export let handle_reset_value: () => void = () => {};
|
|
export let max_file_size: number | null = null;
|
|
export let upload: Client["upload"];
|
|
export let stream_handler: Client["stream"];
|
|
export let loop: boolean;
|
|
export let uploading = false;
|
|
export let webcam_constraints: { [key: string]: any } | null = null;
|
|
|
|
let has_change_history = false;
|
|
|
|
const dispatch = createEventDispatcher<{
|
|
change: FileData | null;
|
|
clear?: never;
|
|
play?: never;
|
|
pause?: never;
|
|
end?: never;
|
|
drag: boolean;
|
|
error: string;
|
|
upload: FileData;
|
|
start_recording?: never;
|
|
stop_recording?: never;
|
|
}>();
|
|
|
|
function handle_load({ detail }: CustomEvent<FileData | null>): void {
|
|
value = detail;
|
|
dispatch("change", detail);
|
|
dispatch("upload", detail!);
|
|
}
|
|
|
|
function handle_clear(): void {
|
|
value = null;
|
|
dispatch("change", null);
|
|
dispatch("clear");
|
|
}
|
|
|
|
function handle_change(video: FileData): void {
|
|
has_change_history = true;
|
|
dispatch("change", video);
|
|
}
|
|
|
|
function handle_capture({
|
|
detail
|
|
}: CustomEvent<FileData | any | null>): void {
|
|
dispatch("change", detail);
|
|
}
|
|
|
|
let dragging = false;
|
|
$: dispatch("drag", dragging);
|
|
</script>
|
|
|
|
<BlockLabel {show_label} Icon={Video} label={label || "Video"} />
|
|
<div data-testid="video" class="video-container">
|
|
{#if value === null || value.url === undefined}
|
|
<div class="upload-container">
|
|
{#if active_source === "upload"}
|
|
<Upload
|
|
bind:dragging
|
|
bind:uploading
|
|
filetype="video/x-m4v,video/*"
|
|
on:load={handle_load}
|
|
{max_file_size}
|
|
on:error={({ detail }) => dispatch("error", detail)}
|
|
{root}
|
|
{upload}
|
|
{stream_handler}
|
|
>
|
|
<slot />
|
|
</Upload>
|
|
{:else if active_source === "webcam"}
|
|
<Webcam
|
|
{root}
|
|
{mirror_webcam}
|
|
{include_audio}
|
|
{webcam_constraints}
|
|
mode="video"
|
|
on:error
|
|
on:capture={handle_capture}
|
|
on:start_recording
|
|
on:stop_recording
|
|
{i18n}
|
|
{upload}
|
|
stream_every={1}
|
|
/>
|
|
{/if}
|
|
</div>
|
|
{:else if playable()}
|
|
{#key value?.url}
|
|
<Player
|
|
{upload}
|
|
{root}
|
|
interactive
|
|
{autoplay}
|
|
src={value.url}
|
|
subtitle={subtitle?.url}
|
|
is_stream={false}
|
|
on:play
|
|
on:pause
|
|
on:stop
|
|
on:end
|
|
mirror={mirror_webcam && active_source === "webcam"}
|
|
{label}
|
|
{handle_change}
|
|
{handle_reset_value}
|
|
{loop}
|
|
{value}
|
|
{i18n}
|
|
{show_download_button}
|
|
{handle_clear}
|
|
{has_change_history}
|
|
/>
|
|
{/key}
|
|
{:else if value.size}
|
|
<div class="file-name">{value.orig_name || value.url}</div>
|
|
<div class="file-size">
|
|
{prettyBytes(value.size)}
|
|
</div>
|
|
{/if}
|
|
|
|
<SelectSource {sources} bind:active_source {handle_clear} />
|
|
</div>
|
|
|
|
<style>
|
|
.file-name {
|
|
padding: var(--size-6);
|
|
font-size: var(--text-xxl);
|
|
word-break: break-all;
|
|
}
|
|
|
|
.file-size {
|
|
padding: var(--size-2);
|
|
font-size: var(--text-xl);
|
|
}
|
|
|
|
.upload-container {
|
|
height: 100%;
|
|
width: 100%;
|
|
}
|
|
|
|
.video-container {
|
|
display: flex;
|
|
height: 100%;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
align-items: center;
|
|
}
|
|
</style>
|