@gradio/image 0.23.2-dev.0 → 0.24.0-dev.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,229 +1,265 @@
1
- <script>import { createEventDispatcher, onDestroy, onMount } from "svelte";
2
- import {
3
- Camera,
4
- Circle,
5
- Square,
6
- DropdownArrow,
7
- Spinner
8
- } from "@gradio/icons";
9
- import { StreamingBar } from "@gradio/statustracker";
10
- import { prepare_files } from "@gradio/client";
11
- import WebcamPermissions from "./WebcamPermissions.svelte";
12
- import { fade } from "svelte/transition";
13
- import {
14
- get_devices,
15
- get_video_stream,
16
- set_available_devices
17
- } from "./stream_utils";
18
- let video_source;
19
- let available_video_devices = [];
20
- let selected_device = null;
21
- let time_limit = null;
22
- let stream_state = "closed";
23
- export const modify_stream = (state) => {
24
- if (state === "closed") {
25
- time_limit = null;
26
- stream_state = "closed";
27
- value = null;
28
- } else if (state === "waiting") {
29
- stream_state = "waiting";
30
- } else {
31
- stream_state = "open";
32
- }
33
- };
34
- export const set_time_limit = (time) => {
35
- if (recording) time_limit = time;
36
- };
37
- let canvas;
38
- export let streaming = false;
39
- export let pending = false;
40
- export let root = "";
41
- export let stream_every = 1;
42
- export let mode = "image";
43
- export let mirror_webcam;
44
- export let include_audio;
45
- export let webcam_constraints = null;
46
- export let i18n;
47
- export let upload;
48
- export let value = null;
49
- const dispatch = createEventDispatcher();
50
- onMount(() => {
51
- canvas = document.createElement("canvas");
52
- if (streaming && mode === "image") {
53
- window.setInterval(() => {
54
- if (video_source && !pending) {
55
- take_picture();
56
- }
57
- }, stream_every * 1e3);
58
- }
59
- });
60
- const handle_device_change = async (event) => {
61
- const target = event.target;
62
- const device_id = target.value;
63
- await get_video_stream(
64
- include_audio,
65
- video_source,
66
- webcam_constraints,
67
- device_id
68
- ).then(async (local_stream) => {
69
- stream = local_stream;
70
- selected_device = available_video_devices.find(
71
- (device) => device.deviceId === device_id
72
- ) || null;
73
- options_open = false;
74
- });
75
- };
76
- async function access_webcam() {
77
- try {
78
- get_video_stream(include_audio, video_source, webcam_constraints).then(async (local_stream) => {
79
- webcam_accessed = true;
80
- available_video_devices = await get_devices();
81
- stream = local_stream;
82
- }).then(() => set_available_devices(available_video_devices)).then((devices) => {
83
- available_video_devices = devices;
84
- const used_devices = stream.getTracks().map((track) => track.getSettings()?.deviceId)[0];
85
- selected_device = used_devices ? devices.find((device) => device.deviceId === used_devices) || available_video_devices[0] : available_video_devices[0];
86
- });
87
- if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
88
- dispatch("error", i18n("image.no_webcam_support"));
89
- }
90
- } catch (err) {
91
- if (err instanceof DOMException && err.name == "NotAllowedError") {
92
- dispatch("error", i18n("image.allow_webcam_access"));
93
- } else {
94
- throw err;
95
- }
96
- }
97
- }
98
- function take_picture() {
99
- var context = canvas.getContext("2d");
100
- if ((!streaming || streaming && recording) && video_source.videoWidth && video_source.videoHeight) {
101
- canvas.width = video_source.videoWidth;
102
- canvas.height = video_source.videoHeight;
103
- context.drawImage(
104
- video_source,
105
- 0,
106
- 0,
107
- video_source.videoWidth,
108
- video_source.videoHeight
109
- );
110
- if (mirror_webcam) {
111
- context.scale(-1, 1);
112
- context.drawImage(video_source, -video_source.videoWidth, 0);
113
- }
114
- if (streaming && (!recording || stream_state === "waiting")) {
115
- return;
116
- }
117
- if (streaming) {
118
- const image_data = canvas.toDataURL("image/jpeg");
119
- dispatch("stream", image_data);
120
- return;
121
- }
122
- canvas.toBlob(
123
- (blob) => {
124
- dispatch(streaming ? "stream" : "capture", blob);
125
- },
126
- `image/${streaming ? "jpeg" : "png"}`,
127
- 0.8
128
- );
129
- }
130
- }
131
- let recording = false;
132
- let recorded_blobs = [];
133
- let stream;
134
- let mimeType;
135
- let media_recorder;
136
- function take_recording() {
137
- if (recording) {
138
- media_recorder.stop();
139
- let video_blob = new Blob(recorded_blobs, { type: mimeType });
140
- let ReaderObj = new FileReader();
141
- ReaderObj.onload = async function(e) {
142
- if (e.target) {
143
- let _video_blob = new File(
144
- [video_blob],
145
- "sample." + mimeType.substring(6)
146
- );
147
- const val = await prepare_files([_video_blob]);
148
- let val_ = ((await upload(val, root))?.filter(Boolean))[0];
149
- dispatch("capture", val_);
150
- dispatch("stop_recording");
151
- }
152
- };
153
- ReaderObj.readAsDataURL(video_blob);
154
- } else if (typeof MediaRecorder !== "undefined") {
155
- dispatch("start_recording");
156
- recorded_blobs = [];
157
- let validMimeTypes = ["video/webm", "video/mp4"];
158
- for (let validMimeType of validMimeTypes) {
159
- if (MediaRecorder.isTypeSupported(validMimeType)) {
160
- mimeType = validMimeType;
161
- break;
162
- }
163
- }
164
- if (mimeType === null) {
165
- console.error("No supported MediaRecorder mimeType");
166
- return;
167
- }
168
- media_recorder = new MediaRecorder(stream, {
169
- mimeType
170
- });
171
- media_recorder.addEventListener("dataavailable", function(e) {
172
- recorded_blobs.push(e.data);
173
- });
174
- media_recorder.start(200);
175
- }
176
- recording = !recording;
177
- }
178
- let webcam_accessed = false;
179
- function record_video_or_photo({
180
- destroy
181
- } = {}) {
182
- if (mode === "image" && streaming) {
183
- recording = !recording;
184
- }
185
- if (!destroy) {
186
- if (mode === "image") {
187
- take_picture();
188
- } else {
189
- take_recording();
190
- }
191
- }
192
- if (!recording && stream) {
193
- dispatch("close_stream");
194
- stream.getTracks().forEach((track) => track.stop());
195
- video_source.srcObject = null;
196
- webcam_accessed = false;
197
- window.setTimeout(() => {
198
- value = null;
199
- }, 500);
200
- value = null;
201
- }
202
- }
203
- let options_open = false;
204
- export function click_outside(node, cb) {
205
- const handle_click = (event) => {
206
- if (node && !node.contains(event.target) && !event.defaultPrevented) {
207
- cb(event);
208
- }
209
- };
210
- document.addEventListener("click", handle_click, true);
211
- return {
212
- destroy() {
213
- document.removeEventListener("click", handle_click, true);
214
- }
215
- };
216
- }
217
- function handle_click_outside(event) {
218
- event.preventDefault();
219
- event.stopPropagation();
220
- options_open = false;
221
- }
222
- onDestroy(() => {
223
- if (typeof window === "undefined") return;
224
- record_video_or_photo({ destroy: true });
225
- stream?.getTracks().forEach((track) => track.stop());
226
- });
1
+ <script lang="ts">
2
+ import { createEventDispatcher, onDestroy, onMount } from "svelte";
3
+ import {
4
+ Camera,
5
+ Circle,
6
+ Square,
7
+ DropdownArrow,
8
+ Spinner
9
+ } from "@gradio/icons";
10
+ import type { I18nFormatter } from "@gradio/utils";
11
+ import { StreamingBar } from "@gradio/statustracker";
12
+ import { type FileData, type Client, prepare_files } from "@gradio/client";
13
+ import WebcamPermissions from "./WebcamPermissions.svelte";
14
+ import { fade } from "svelte/transition";
15
+ import {
16
+ get_devices,
17
+ get_video_stream,
18
+ set_available_devices
19
+ } from "./stream_utils";
20
+ import type { Base64File } from "./types";
21
+
22
+ let video_source: HTMLVideoElement;
23
+ let available_video_devices: MediaDeviceInfo[] = [];
24
+ let selected_device: MediaDeviceInfo | null = null;
25
+
26
+ export let stream_state: "open" | "waiting" | "closed" = "closed";
27
+
28
+ let canvas: HTMLCanvasElement;
29
+ export let streaming = false;
30
+ export let pending = false;
31
+ export let root = "";
32
+ export let stream_every = 1;
33
+
34
+ export let mode: "image" | "video" = "image";
35
+ export let mirror_webcam: boolean;
36
+ export let include_audio: boolean;
37
+ export let webcam_constraints: { [key: string]: any } | null = null;
38
+ export let i18n: I18nFormatter;
39
+ export let upload: Client["upload"];
40
+ export let value: FileData | null | Base64File = null;
41
+ export let time_limit: number | null = null;
42
+ const dispatch = createEventDispatcher<{
43
+ stream: Blob | string;
44
+ capture: FileData | Blob | null;
45
+ error: string;
46
+ start_recording: undefined;
47
+ stop_recording: undefined;
48
+ close_stream: undefined;
49
+ }>();
50
+
51
+ onMount(() => {
52
+ canvas = document.createElement("canvas");
53
+ if (streaming && mode === "image") {
54
+ window.setInterval(() => {
55
+ if (video_source && !pending) {
56
+ take_picture();
57
+ }
58
+ }, stream_every * 1000);
59
+ }
60
+ });
61
+
62
+ const handle_device_change = async (event: InputEvent): Promise<void> => {
63
+ const target = event.target as HTMLInputElement;
64
+ const device_id = target.value;
65
+
66
+ await get_video_stream(
67
+ include_audio,
68
+ video_source,
69
+ webcam_constraints,
70
+ device_id
71
+ ).then(async (local_stream) => {
72
+ stream = local_stream;
73
+ selected_device =
74
+ available_video_devices.find(
75
+ (device) => device.deviceId === device_id
76
+ ) || null;
77
+ options_open = false;
78
+ });
79
+ };
80
+
81
+ async function access_webcam(): Promise<void> {
82
+ try {
83
+ get_video_stream(include_audio, video_source, webcam_constraints)
84
+ .then(async (local_stream) => {
85
+ webcam_accessed = true;
86
+ available_video_devices = await get_devices();
87
+ stream = local_stream;
88
+ })
89
+ .then(() => set_available_devices(available_video_devices))
90
+ .then((devices) => {
91
+ available_video_devices = devices;
92
+
93
+ const used_devices = stream
94
+ .getTracks()
95
+ .map((track) => track.getSettings()?.deviceId)[0];
96
+
97
+ selected_device = used_devices
98
+ ? devices.find((device) => device.deviceId === used_devices) ||
99
+ available_video_devices[0]
100
+ : available_video_devices[0];
101
+ });
102
+
103
+ if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
104
+ dispatch("error", i18n("image.no_webcam_support"));
105
+ }
106
+ } catch (err) {
107
+ if (err instanceof DOMException && err.name == "NotAllowedError") {
108
+ dispatch("error", i18n("image.allow_webcam_access"));
109
+ } else {
110
+ throw err;
111
+ }
112
+ }
113
+ }
114
+
115
+ function take_picture(): void {
116
+ if (
117
+ (!streaming || (streaming && recording)) &&
118
+ video_source.videoWidth &&
119
+ video_source.videoHeight
120
+ ) {
121
+ console.log("Taking picture from webcam");
122
+ var context = canvas.getContext("2d")!;
123
+ canvas.width = video_source.videoWidth;
124
+ canvas.height = video_source.videoHeight;
125
+ context.drawImage(
126
+ video_source,
127
+ 0,
128
+ 0,
129
+ video_source.videoWidth,
130
+ video_source.videoHeight
131
+ );
132
+
133
+ if (mirror_webcam) {
134
+ context.scale(-1, 1);
135
+ context.drawImage(video_source, -video_source.videoWidth, 0);
136
+ }
137
+
138
+ if (streaming && (!recording || stream_state === "waiting")) {
139
+ return;
140
+ }
141
+ if (streaming) {
142
+ const image_data = canvas.toDataURL("image/jpeg");
143
+ dispatch("stream", image_data);
144
+ return;
145
+ }
146
+
147
+ canvas.toBlob(
148
+ (blob) => {
149
+ dispatch(streaming ? "stream" : "capture", blob);
150
+ },
151
+ `image/${streaming ? "jpeg" : "png"}`,
152
+ 0.8
153
+ );
154
+ }
155
+ }
156
+
157
+ let recording = false;
158
+ let recorded_blobs: BlobPart[] = [];
159
+ let stream: MediaStream;
160
+ let mimeType: string;
161
+ let media_recorder: MediaRecorder;
162
+
163
+ function take_recording(): void {
164
+ if (recording) {
165
+ media_recorder.stop();
166
+ let video_blob = new Blob(recorded_blobs, { type: mimeType });
167
+ let ReaderObj = new FileReader();
168
+ ReaderObj.onload = async function (e): Promise<void> {
169
+ if (e.target) {
170
+ let _video_blob = new File(
171
+ [video_blob],
172
+ "sample." + mimeType.substring(6)
173
+ );
174
+ const val = await prepare_files([_video_blob]);
175
+ let val_ = (
176
+ (await upload(val, root))?.filter(Boolean) as FileData[]
177
+ )[0];
178
+ dispatch("capture", val_);
179
+ dispatch("stop_recording");
180
+ }
181
+ };
182
+ ReaderObj.readAsDataURL(video_blob);
183
+ } else if (typeof MediaRecorder !== "undefined") {
184
+ dispatch("start_recording");
185
+ recorded_blobs = [];
186
+ let validMimeTypes = ["video/webm", "video/mp4"];
187
+ for (let validMimeType of validMimeTypes) {
188
+ if (MediaRecorder.isTypeSupported(validMimeType)) {
189
+ mimeType = validMimeType;
190
+ break;
191
+ }
192
+ }
193
+ if (mimeType === null) {
194
+ console.error("No supported MediaRecorder mimeType");
195
+ return;
196
+ }
197
+ media_recorder = new MediaRecorder(stream, {
198
+ mimeType: mimeType
199
+ });
200
+ media_recorder.addEventListener("dataavailable", function (e) {
201
+ recorded_blobs.push(e.data);
202
+ });
203
+ media_recorder.start(200);
204
+ }
205
+ recording = !recording;
206
+ }
207
+
208
+ let webcam_accessed = false;
209
+
210
+ function record_video_or_photo({
211
+ destroy
212
+ }: { destroy?: boolean } = {}): void {
213
+ if (mode === "image" && streaming) {
214
+ recording = !recording;
215
+ }
216
+
217
+ if (!destroy) {
218
+ if (mode === "image") {
219
+ take_picture();
220
+ } else {
221
+ take_recording();
222
+ }
223
+ }
224
+
225
+ if (!recording && stream) {
226
+ dispatch("close_stream");
227
+ }
228
+ }
229
+
230
+ let options_open = false;
231
+
232
+ export function click_outside(node: Node, cb: any): any {
233
+ const handle_click = (event: MouseEvent): void => {
234
+ if (
235
+ node &&
236
+ !node.contains(event.target as Node) &&
237
+ !event.defaultPrevented
238
+ ) {
239
+ cb(event);
240
+ }
241
+ };
242
+
243
+ document.addEventListener("click", handle_click, true);
244
+
245
+ return {
246
+ destroy() {
247
+ document.removeEventListener("click", handle_click, true);
248
+ }
249
+ };
250
+ }
251
+
252
+ function handle_click_outside(event: MouseEvent): void {
253
+ event.preventDefault();
254
+ event.stopPropagation();
255
+ options_open = false;
256
+ }
257
+
258
+ onDestroy(() => {
259
+ if (typeof window === "undefined") return;
260
+ record_video_or_photo({ destroy: true });
261
+ stream?.getTracks().forEach((track) => track.stop());
262
+ });
227
263
  </script>
228
264
 
229
265
  <div class="wrap">
@@ -300,12 +336,12 @@ onDestroy(() => {
300
336
  use:click_outside={handle_click_outside}
301
337
  on:change={handle_device_change}
302
338
  >
303
- <button
339
+ <!-- <button
304
340
  class="inset-icon"
305
341
  on:click|stopPropagation={() => (options_open = false)}
306
342
  >
307
343
  <DropdownArrow />
308
- </button>
344
+ </button> -->
309
345
  {#if available_video_devices.length === 0}
310
346
  <option value="">{i18n("common.no_devices")}</option>
311
347
  {:else}
@@ -1,46 +1,47 @@
1
- import { SvelteComponent } from "svelte";
2
1
  import type { I18nFormatter } from "@gradio/utils";
3
2
  import { type FileData, type Client } from "@gradio/client";
4
3
  import type { Base64File } from "./types";
5
- declare const __propDef: {
6
- props: {
7
- modify_stream?: (state: "open" | "closed" | "waiting") => void;
8
- set_time_limit?: (time: number) => void;
9
- streaming?: boolean;
10
- pending?: boolean;
11
- root?: string;
12
- stream_every?: number;
13
- mode?: "image" | "video";
14
- mirror_webcam: boolean;
15
- include_audio: boolean;
16
- webcam_constraints?: {
17
- [key: string]: any;
18
- } | null;
19
- i18n: I18nFormatter;
20
- upload: Client["upload"];
21
- value?: FileData | null | Base64File;
22
- click_outside?: (node: Node, cb: any) => any;
4
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
5
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
6
+ $$bindings?: Bindings;
7
+ } & Exports;
8
+ (internal: unknown, props: Props & {
9
+ $$events?: Events;
10
+ $$slots?: Slots;
11
+ }): Exports & {
12
+ $set?: any;
13
+ $on?: any;
23
14
  };
24
- events: {
25
- stream: CustomEvent<string | Blob>;
26
- capture: CustomEvent<any>;
27
- error: CustomEvent<string>;
28
- start_recording: CustomEvent<undefined>;
29
- stop_recording: CustomEvent<undefined>;
30
- close_stream: CustomEvent<undefined>;
31
- } & {
32
- [evt: string]: CustomEvent<any>;
33
- };
34
- slots: {};
35
- exports?: {} | undefined;
36
- bindings?: string | undefined;
37
- };
38
- export type WebcamProps = typeof __propDef.props;
39
- export type WebcamEvents = typeof __propDef.events;
40
- export type WebcamSlots = typeof __propDef.slots;
41
- export default class Webcam extends SvelteComponent<WebcamProps, WebcamEvents, WebcamSlots> {
42
- get modify_stream(): (state: "open" | "closed" | "waiting") => void;
43
- get set_time_limit(): (time: number) => void;
44
- get click_outside(): (node: Node, cb: any) => any;
15
+ z_$$bindings?: Bindings;
45
16
  }
46
- export {};
17
+ declare const Webcam: $$__sveltets_2_IsomorphicComponent<{
18
+ stream_state?: "open" | "waiting" | "closed";
19
+ streaming?: boolean;
20
+ pending?: boolean;
21
+ root?: string;
22
+ stream_every?: number;
23
+ mode?: "image" | "video";
24
+ mirror_webcam: boolean;
25
+ include_audio: boolean;
26
+ webcam_constraints?: {
27
+ [key: string]: any;
28
+ } | null;
29
+ i18n: I18nFormatter;
30
+ upload: Client["upload"];
31
+ value?: FileData | null | Base64File;
32
+ time_limit?: number | null;
33
+ click_outside?: (node: Node, cb: any) => any;
34
+ }, {
35
+ stream: CustomEvent<string | Blob>;
36
+ capture: CustomEvent<Blob | FileData | null>;
37
+ error: CustomEvent<string>;
38
+ start_recording: CustomEvent<undefined>;
39
+ stop_recording: CustomEvent<undefined>;
40
+ close_stream: CustomEvent<undefined>;
41
+ } & {
42
+ [evt: string]: CustomEvent<any>;
43
+ }, {}, {
44
+ click_outside: (node: Node, cb: any) => any;
45
+ }, string>;
46
+ type Webcam = InstanceType<typeof Webcam>;
47
+ export default Webcam;
@@ -1,6 +1,10 @@
1
- <script>import { Webcam } from "@gradio/icons";
2
- import { createEventDispatcher } from "svelte";
3
- const dispatch = createEventDispatcher();
1
+ <script lang="ts">
2
+ import { Webcam } from "@gradio/icons";
3
+ import { createEventDispatcher } from "svelte";
4
+
5
+ const dispatch = createEventDispatcher<{
6
+ click: undefined;
7
+ }>();
4
8
  </script>
5
9
 
6
10
  <button style:height="100%" on:click={() => dispatch("click")}>
@@ -1,18 +1,20 @@
1
- import { SvelteComponent } from "svelte";
2
- declare const __propDef: {
3
- props: Record<string, never>;
4
- events: {
5
- click: CustomEvent<undefined>;
6
- } & {
7
- [evt: string]: CustomEvent<any>;
1
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
2
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
3
+ $$bindings?: Bindings;
4
+ } & Exports;
5
+ (internal: unknown, props: {
6
+ $$events?: Events;
7
+ $$slots?: Slots;
8
+ }): Exports & {
9
+ $set?: any;
10
+ $on?: any;
8
11
  };
9
- slots: {};
10
- exports?: {} | undefined;
11
- bindings?: string | undefined;
12
- };
13
- export type WebcamPermissionsProps = typeof __propDef.props;
14
- export type WebcamPermissionsEvents = typeof __propDef.events;
15
- export type WebcamPermissionsSlots = typeof __propDef.slots;
16
- export default class WebcamPermissions extends SvelteComponent<WebcamPermissionsProps, WebcamPermissionsEvents, WebcamPermissionsSlots> {
12
+ z_$$bindings?: Bindings;
17
13
  }
18
- export {};
14
+ declare const WebcamPermissions: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
15
+ click: CustomEvent<undefined>;
16
+ } & {
17
+ [evt: string]: CustomEvent<any>;
18
+ }, {}, {}, string>;
19
+ type WebcamPermissions = InstanceType<typeof WebcamPermissions>;
20
+ export default WebcamPermissions;