@gradio/video 0.4.0 → 0.5.1

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @gradio/video
2
2
 
3
+ ## 0.5.1
4
+
5
+ ### Features
6
+
7
+ - [#7274](https://github.com/gradio-app/gradio/pull/7274) [`fdd1521`](https://github.com/gradio-app/gradio/commit/fdd15213c24b9cbc58bbc1b6beb4af7c18f48557) - chore: Change time format (thanks @jjshoots for the independent contribution). Thanks [@arian81](https://github.com/arian81)!
8
+
9
+ ### Fixes
10
+
11
+ - [#7192](https://github.com/gradio-app/gradio/pull/7192) [`8dd6f4b`](https://github.com/gradio-app/gradio/commit/8dd6f4bc1901792f05cd59e86df7b1dbab692739) - Handle the case where examples is `null` for all components. Thanks [@abidlabs](https://github.com/abidlabs)!
12
+
13
+ ## 0.5.0
14
+
15
+ ### Features
16
+
17
+ - [#7104](https://github.com/gradio-app/gradio/pull/7104) [`bc2cdc1`](https://github.com/gradio-app/gradio/commit/bc2cdc1df95b38025486cf76df4a494b66d98585) - Allow download button for interactive Audio and Video components. Thanks [@hannahblair](https://github.com/hannahblair)!
18
+
3
19
  ## 0.4.0
4
20
 
5
21
  ### Fixes
package/Example.svelte CHANGED
@@ -20,25 +20,27 @@
20
20
  }
21
21
  </script>
22
22
 
23
- {#if playable()}
24
- <div
25
- class="container"
26
- class:table={type === "table"}
27
- class:gallery={type === "gallery"}
28
- class:selected
29
- >
30
- <Video
31
- muted
32
- playsinline
33
- bind:node={video}
34
- on:loadeddata={init}
35
- on:mouseover={video.play.bind(video)}
36
- on:mouseout={video.pause.bind(video)}
37
- src={samples_dir + value?.video.path}
38
- />
39
- </div>
40
- {:else}
41
- <div>{value}</div>
23
+ {#if value}
24
+ {#if playable()}
25
+ <div
26
+ class="container"
27
+ class:table={type === "table"}
28
+ class:gallery={type === "gallery"}
29
+ class:selected
30
+ >
31
+ <Video
32
+ muted
33
+ playsinline
34
+ bind:node={video}
35
+ on:loadeddata={init}
36
+ on:mouseover={video.play.bind(video)}
37
+ on:mouseout={video.pause.bind(video)}
38
+ src={samples_dir + value?.video.path}
39
+ />
40
+ </div>
41
+ {:else}
42
+ <div>{value}</div>
43
+ {/if}
42
44
  {/if}
43
45
 
44
46
  <style>
package/Index.svelte CHANGED
@@ -35,6 +35,7 @@
35
35
  export let min_width: number | undefined = undefined;
36
36
  export let autoplay = false;
37
37
  export let show_share_button = true;
38
+ export let show_download_button: boolean;
38
39
  export let gradio: Gradio<{
39
40
  change: never;
40
41
  clear: never;
@@ -146,7 +147,7 @@
146
147
  {show_label}
147
148
  {autoplay}
148
149
  {show_share_button}
149
- show_download_button={true}
150
+ {show_download_button}
150
151
  on:play={() => gradio.dispatch("play")}
151
152
  on:pause={() => gradio.dispatch("pause")}
152
153
  on:stop={() => gradio.dispatch("stop")}
@@ -185,6 +186,7 @@
185
186
  on:error={handle_error}
186
187
  {label}
187
188
  {show_label}
189
+ {show_download_button}
188
190
  {sources}
189
191
  {active_source}
190
192
  {mirror_webcam}
@@ -1,12 +1,24 @@
1
- <script>
2
- import { Meta, Template, Story } from "@storybook/addon-svelte-csf";
1
+ <script context="module">
2
+ import { Template, Story } from "@storybook/addon-svelte-csf";
3
3
  import Video from "./Index.svelte";
4
4
  import { format } from "svelte-i18n";
5
5
  import { get } from "svelte/store";
6
6
  import { userEvent, within } from "@storybook/testing-library";
7
- </script>
7
+ import { allModes } from "../storybook/modes";
8
8
 
9
- <Meta title="Components/Video" component={Video} />
9
+ export const meta = {
10
+ title: "Components/Video",
11
+ component: Video,
12
+ parameters: {
13
+ chromatic: {
14
+ modes: {
15
+ desktop: allModes["desktop"],
16
+ mobile: allModes["mobile"]
17
+ }
18
+ }
19
+ }
20
+ };
21
+ </script>
10
22
 
11
23
  <div>
12
24
  <Template let:args>
@@ -38,6 +50,7 @@
38
50
  },
39
51
  label: "world video",
40
52
  show_label: true,
53
+ show_download_button: true,
41
54
  interactive: false,
42
55
  height: 200,
43
56
  width: 400
@@ -55,6 +68,7 @@
55
68
  },
56
69
  label: "world video",
57
70
  show_label: true,
71
+ show_download_button: false,
58
72
  interactive: false,
59
73
  height: 200,
60
74
  width: 400
@@ -74,6 +88,26 @@
74
88
  }}
75
89
  />
76
90
 
91
+ <Story
92
+ name="Upload video with download button"
93
+ args={{
94
+ label: "world video",
95
+ show_label: true,
96
+ interactive: true,
97
+ sources: ["upload", "webcam"],
98
+ show_download_button: true,
99
+ width: 400,
100
+ height: 400,
101
+ value: {
102
+ video: {
103
+ path: "https://gradio-static-files.s3.us-west-2.amazonaws.com/world.mp4",
104
+ url: "https://gradio-static-files.s3.us-west-2.amazonaws.com/world.mp4",
105
+ orig_name: "world.mp4"
106
+ }
107
+ }
108
+ }}
109
+ />
110
+
77
111
  <Story
78
112
  name="Trim video"
79
113
  args={{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gradio/video",
3
- "version": "0.4.0",
3
+ "version": "0.5.1",
4
4
  "description": "Gradio UI packages",
5
5
  "type": "module",
6
6
  "author": "",
@@ -10,14 +10,14 @@
10
10
  "@ffmpeg/ffmpeg": "^0.12.7",
11
11
  "@ffmpeg/util": "^0.12.1",
12
12
  "mrmime": "^2.0.0",
13
- "@gradio/atoms": "^0.4.1",
14
- "@gradio/client": "^0.10.1",
13
+ "@gradio/client": "^0.11.0",
15
14
  "@gradio/icons": "^0.3.2",
16
- "@gradio/image": "^0.7.0",
17
- "@gradio/statustracker": "^0.4.3",
18
- "@gradio/upload": "^0.6.1",
19
- "@gradio/wasm": "^0.5.0",
20
- "@gradio/utils": "^0.2.0"
15
+ "@gradio/image": "^0.8.0",
16
+ "@gradio/statustracker": "^0.4.5",
17
+ "@gradio/upload": "^0.7.1",
18
+ "@gradio/utils": "^0.2.2",
19
+ "@gradio/wasm": "^0.6.0",
20
+ "@gradio/atoms": "^0.5.1"
21
21
  },
22
22
  "exports": {
23
23
  ".": "./index.ts",
@@ -19,6 +19,7 @@
19
19
  | ["webcam", "upload"]
20
20
  | ["upload", "webcam"] = ["webcam", "upload"];
21
21
  export let label: string | undefined = undefined;
22
+ export let show_download_button = false;
22
23
  export let show_label = true;
23
24
  export let mirror_webcam = false;
24
25
  export let include_audio: boolean;
@@ -96,7 +97,11 @@
96
97
  {/if}
97
98
  </div>
98
99
  {:else}
99
- <ModifyUpload {i18n} on:clear={handle_clear} />
100
+ <ModifyUpload
101
+ {i18n}
102
+ on:clear={handle_clear}
103
+ download={show_download_button ? value.url : null}
104
+ />
100
105
  {#if playable()}
101
106
  {#key value?.url}
102
107
  <Player
@@ -5,6 +5,7 @@
5
5
  import VideoControls from "./VideoControls.svelte";
6
6
  import type { FileData } from "@gradio/client";
7
7
  import { prepare_files, upload } from "@gradio/client";
8
+ import { format_time } from "@gradio/utils";
8
9
 
9
10
  export let root = "";
10
11
  export let src: string;
@@ -70,16 +71,6 @@
70
71
  time = (duration * (e.clientX - left)) / (right - left);
71
72
  }
72
73
 
73
- function format(seconds: number): string {
74
- if (isNaN(seconds) || !isFinite(seconds)) return "...";
75
-
76
- const minutes = Math.floor(seconds / 60);
77
- let _seconds: number | string = Math.floor(seconds % 60);
78
- if (_seconds < 10) _seconds = `0${_seconds}`;
79
-
80
- return `${minutes}:${_seconds}`;
81
- }
82
-
83
74
  function handle_end(): void {
84
75
  dispatch("stop");
85
76
  dispatch("end");
@@ -138,7 +129,7 @@
138
129
  {/if}
139
130
  </span>
140
131
 
141
- <span class="time">{format(time)} / {format(duration)}</span>
132
+ <span class="time">{format_time(time)} / {format_time(duration)}</span>
142
133
 
143
134
  <!-- TODO: implement accessible video timeline for 4.0 -->
144
135
  <!-- svelte-ignore a11y-click-events-have-key-events -->
@@ -5,6 +5,7 @@
5
5
  import { FFmpeg } from "@ffmpeg/ffmpeg";
6
6
  import loadFfmpeg from "./utils";
7
7
  import { onMount } from "svelte";
8
+ import { format_time } from "@gradio/utils";
8
9
 
9
10
  export let videoElement: HTMLVideoElement;
10
11
 
@@ -24,18 +25,6 @@
24
25
  $: if (mode === "edit" && trimmedDuration === null && videoElement)
25
26
  trimmedDuration = videoElement.duration;
26
27
 
27
- const formatTime = (seconds: number): string => {
28
- const minutes = Math.floor(seconds / 60);
29
- const secondsRemainder = Math.round(seconds) % 60;
30
- const paddedSeconds = `0${secondsRemainder}`.slice(-2);
31
-
32
- if (Number.isNaN(minutes) || Number.isNaN(secondsRemainder)) {
33
- return "00:00";
34
- }
35
-
36
- return `${minutes}:${paddedSeconds}`;
37
- };
38
-
39
28
  let trimmedDuration: number | null = null;
40
29
  let dragStart = 0;
41
30
  let dragEnd = 0;
@@ -69,7 +58,7 @@
69
58
  {#if mode === "edit" && trimmedDuration !== null}
70
59
  <time
71
60
  aria-label="duration of selected region in seconds"
72
- class:hidden={loadingTimeline}>{formatTime(trimmedDuration)}</time
61
+ class:hidden={loadingTimeline}>{format_time(trimmedDuration)}</time
73
62
  >
74
63
  {:else}
75
64
  <div />