This commit is contained in:
pngwn 2022-03-07 13:36:49 +00:00
parent 0044c243db
commit ddbd121a03
55 changed files with 108 additions and 290 deletions

View File

@ -12,19 +12,24 @@
"vite": "^2.7.13"
},
"dependencies": {
"@types/d3-dsv": "^3.0.0",
"@types/d3-scale": "^4.0.2",
"@types/d3-shape": "^3.0.2",
"@gradio/audio": "workspace:^0.0.1",
"@gradio/button": "workspace:^0.0.1",
"@gradio/carousel": "workspace:^0.0.1",
"@gradio/chart": "workspace:^0.0.1",
"@gradio/chatbot": "workspace:^0.0.1",
"@gradio/file": "workspace:^0.0.1",
"@gradio/form": "workspace:^0.0.1",
"@gradio/highlighted-text": "workspace:^0.0.1",
"@gradio/html": "workspace:^0.0.1",
"@gradio/image": "workspace:^0.0.1",
"@gradio/json": "workspace:^0.0.1",
"@gradio/label": "workspace:^0.0.1",
"@gradio/table": "workspace:^0.0.1",
"@gradio/theme": "workspace:^0.0.1",
"@gradio/upload": "workspace:^0.0.1",
"@gradio/video": "workspace:^0.0.1",
"autoprefixer": "^9.8.8",
"cropperjs": "^1.5.12",
"d3-dsv": "^3.0.1",
"d3-scale": "^4.0.2",
"d3-shape": "^3.1.0",
"lazy-brush": "^1.0.1",
"mime-types": "^2.1.34",
"resize-observer-polyfill": "^1.5.1",
"svelte-i18n": "^3.3.13",
"svelte-range-slider-pips": "^2.0.1",
"tui-image-editor": "^3.15.2"
"svelte-i18n": "^3.3.13"
}
}

View File

@ -0,0 +1,23 @@
<script lang="ts">
import { Audio } from "@gradio/audio";
import type { FileData } from "@gradio/upload";
export let mode: "static" | "dynamic";
export let value: null | FileData;
export let theme: string;
export let name: string;
export let source: "microphone" | "upload";
let _source: "none" | "microphone" | "upload" =
mode === "static" ? "none" : source;
</script>
<Audio
{value}
{theme}
{name}
source={_source}
on:change={({ detail }) => (value = detail)}
/>

View File

@ -1,7 +1,7 @@
<script lang="ts">
import type { Value } from "./types";
import type { AudioData } from "@gradio/upload";
import { getSaliencyColor } from "../../utils/helpers";
import { getSaliencyColor } from "../utils/helpers";
export let value: Value;
export let interpretation: Array<number>;
export let theme: string;

View File

@ -1,7 +1,7 @@
import Component from "./Audio.svelte";
import Component from "./_Audio.svelte";
import ExampleComponent from "./Example.svelte";
import Interpretation from "./Interpretation.svelte";
import { loadAsFile } from "../../utils/example_processors";
import { loadAsFile } from "../utils/example_processors";
export default {
component: Component,

View File

@ -1,176 +0,0 @@
<script lang="ts">
import type { Value } from "./types";
import { onDestroy } from "svelte";
import Upload from "../../utils/Upload.svelte";
import ModifyUpload from "../../utils/ModifyUpload.svelte";
//@ts-ignore
import Range from "svelte-range-slider-pips";
import { _ } from "svelte-i18n";
export let value: null | Value;
export let setValue: (val: typeof value) => typeof value;
export let theme: string;
export let name: string;
export let static_src: string;
export let is_example: boolean = false;
export let source: "microphone" | "upload";
let recording = false;
let recorder: MediaRecorder;
let mode = "";
let audio_chunks: Array<Blob> = [];
let audio_blob;
let player;
let inited = false;
let crop_values = [0, 100];
function blob_to_data_url(blob: Blob): Promise<string> {
return new Promise((fulfill, reject) => {
let reader = new FileReader();
reader.onerror = reject;
reader.onload = (e) => fulfill(reader.result as string);
reader.readAsDataURL(blob);
});
}
async function prepare_audio() {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
recorder = new MediaRecorder(stream);
recorder.addEventListener("dataavailable", (event) => {
audio_chunks.push(event.data);
});
recorder.addEventListener("stop", async () => {
recording = false;
audio_blob = new Blob(audio_chunks, { type: "audio/wav" });
setValue({
data: await blob_to_data_url(audio_blob),
name,
is_example
});
});
}
async function record() {
recording = true;
audio_chunks = [];
if (!inited) await prepare_audio();
recorder.start();
}
onDestroy(() => {
if (recorder) {
recorder.stop();
}
});
const stop = () => {
recorder.stop();
};
function clear() {
setValue(null);
mode = "";
}
function loaded(node: HTMLAudioElement) {
function clamp_playback() {
const start_time = (crop_values[0] / 100) * node.duration;
const end_time = (crop_values[1] / 100) * node.duration;
if (node.currentTime < start_time) {
node.currentTime = start_time;
}
if (node.currentTime > end_time) {
node.currentTime = start_time;
node.pause();
}
}
node.addEventListener("timeupdate", clamp_playback);
return {
destroy: () => node.removeEventListener("timeupdate", clamp_playback)
};
}
function handle_change({
detail: { values }
}: {
detail: { values: [number, number] };
}) {
if (!value?.data) return;
setValue({
data: value.data,
name,
is_example,
crop_min: values[0],
crop_max: values[1]
});
}
</script>
<div class="input-audio">
{#if value === null}
{#if source === "microphone"}
{#if recording}
<button
class="p-2 rounded font-semibold bg-red-200 text-red-500 dark:bg-red-600 dark:text-red-100 shadow transition hover:shadow-md"
on:click={stop}
>
Stop Recording
</button>
{:else}
<button
class="p-2 rounded font-semibold shadow transition hover:shadow-md bg-white dark:bg-gray-800"
on:click={record}
>
Record
</button>
{/if}
{:else if source === "upload"}
<Upload filetype="audio/*" load={setValue} {theme}>
{$_("interface.drop_audio")}
<br />- {$_("interface.or")} -<br />
{$_("interface.click_to_upload")}
</Upload>
{/if}
{:else}
<ModifyUpload
{clear}
edit={() => (mode = "edit")}
absolute={false}
{theme}
{static_src}
/>
<audio
use:loaded
class="w-full"
controls
bind:this={player}
preload="metadata"
src={value.data}
/>
{#if mode === "edit" && player?.duration}
<Range
bind:values={crop_values}
range
min={0}
max={100}
step={1}
on:change={handle_change}
/>
{/if}
{/if}
</div>
<style lang="postcss">
</style>

View File

@ -1,6 +1,12 @@
<script lang="ts">
import type { Value } from "./types";
<script context="module" lang="ts">
import type { FileData } from "@gradio/upload";
export interface AudioData extends FileData {
crop_min?: number;
crop_max?: number;
}
</script>
<script lang="ts">
import { onDestroy, createEventDispatcher } from "svelte";
import { Upload, ModifyUpload } from "@gradio/upload";
//@ts-ignore
@ -9,7 +15,7 @@
export let value: null | { name: string; data: string } = null;
export let theme: string;
export let name: string;
export let source: "microphone" | "upload";
export let source: "microphone" | "upload" | "none";
export let drop_text: string = "Drop an audio file";
export let or_text: string = "or";
export let upload_text: string = "click to upload";
@ -23,7 +29,9 @@
let inited = false;
let crop_values = [0, 100];
const dispatch = createEventDispatcher<{ change: Value }>();
const dispatch = createEventDispatcher<{
change: AudioData;
}>();
function blob_to_data_url(blob: Blob): Promise<string> {
return new Promise((fulfill, reject) => {

View File

@ -1 +1,2 @@
export { default as Audio } from "./Audio.svelte";
export type { AudioData } from "./Audio.svelte";

View File

@ -1,6 +0,0 @@
export interface Value {
data: string;
name: string;
crop_min?: number;
crop_max?: number;
}

View File

@ -36,8 +36,7 @@
? {
name: f.name,
size: f.size,
data: this.result as string,
is_example: false
data: this.result as string
}
: (this.result as string);
if (all_file_data.length === files.length) {

View File

@ -1,6 +1,5 @@
export interface FileData {
name: string;
size: number;
size?: number;
data: string;
is_example: false;
}

View File

@ -30,37 +30,47 @@ importers:
packages/app:
specifiers:
'@gradio/audio': workspace:^0.0.1
'@gradio/button': workspace:^0.0.1
'@gradio/carousel': workspace:^0.0.1
'@gradio/chart': workspace:^0.0.1
'@gradio/chatbot': workspace:^0.0.1
'@gradio/file': workspace:^0.0.1
'@gradio/form': workspace:^0.0.1
'@gradio/highlighted-text': workspace:^0.0.1
'@gradio/html': workspace:^0.0.1
'@gradio/image': workspace:^0.0.1
'@gradio/json': workspace:^0.0.1
'@gradio/label': workspace:^0.0.1
'@gradio/table': workspace:^0.0.1
'@gradio/theme': workspace:^0.0.1
'@gradio/upload': workspace:^0.0.1
'@gradio/video': workspace:^0.0.1
'@sveltejs/vite-plugin-svelte': ^1.0.0-next.36
'@types/d3-dsv': ^3.0.0
'@types/d3-scale': ^4.0.2
'@types/d3-shape': ^3.0.2
autoprefixer: ^9.8.8
cropperjs: ^1.5.12
d3-dsv: ^3.0.1
d3-scale: ^4.0.2
d3-shape: ^3.1.0
lazy-brush: ^1.0.1
mime-types: ^2.1.34
resize-observer-polyfill: ^1.5.1
svelte-i18n: ^3.3.13
svelte-range-slider-pips: ^2.0.1
tui-image-editor: ^3.15.2
vite: ^2.7.13
dependencies:
'@types/d3-dsv': 3.0.0
'@types/d3-scale': 4.0.2
'@types/d3-shape': 3.0.2
'@gradio/audio': link:../audio
'@gradio/button': link:../button
'@gradio/carousel': link:../carousel
'@gradio/chart': link:../chart
'@gradio/chatbot': link:../chatbot
'@gradio/file': link:../file
'@gradio/form': link:../form
'@gradio/highlighted-text': link:../highlighted-text
'@gradio/html': link:../html
'@gradio/image': link:../image
'@gradio/json': link:../json
'@gradio/label': link:../label
'@gradio/table': link:../table
'@gradio/theme': link:../theme
'@gradio/upload': link:../upload
'@gradio/video': link:../video
autoprefixer: 9.8.8
cropperjs: 1.5.12
d3-dsv: 3.0.1
d3-scale: 4.0.2
d3-shape: 3.1.0
lazy-brush: 1.0.1
mime-types: 2.1.34
resize-observer-polyfill: 1.5.1
svelte-i18n: 3.3.13_svelte@3.46.3
svelte-range-slider-pips: 2.0.2
tui-image-editor: 3.15.2
devDependencies:
'@sveltejs/vite-plugin-svelte': 1.0.0-next.36_svelte@3.46.3+vite@2.7.13
vite: 2.7.13
@ -74,16 +84,10 @@ importers:
svelte-range-slider-pips: 2.0.2
packages/button:
specifiers:
'@gradio/upload': workspace:^0.0.1
dependencies:
'@gradio/upload': link:../upload
specifiers: {}
packages/carousel:
specifiers:
'@gradio/upload': workspace:^0.0.1
dependencies:
'@gradio/upload': link:../upload
specifiers: {}
packages/chart:
specifiers:
@ -100,9 +104,6 @@ importers:
packages/chatbot:
specifiers: {}
packages/components:
specifiers: {}
packages/file:
specifiers:
'@gradio/upload': workspace:^0.0.1
@ -110,22 +111,13 @@ importers:
'@gradio/upload': link:../upload
packages/form:
specifiers:
'@gradio/upload': workspace:^0.0.1
dependencies:
'@gradio/upload': link:../upload
specifiers: {}
packages/highlighted-text:
specifiers:
'@gradio/upload': workspace:^0.0.1
dependencies:
'@gradio/upload': link:../upload
specifiers: {}
packages/html:
specifiers:
'@gradio/upload': workspace:^0.0.1
dependencies:
'@gradio/upload': link:../upload
specifiers: {}
packages/image:
specifiers:
@ -141,23 +133,20 @@ importers:
resize-observer-polyfill: 1.5.1
tui-image-editor: 3.15.2
packages/json:
specifiers: {}
packages/label:
specifiers: {}
packages/table:
specifiers:
'@gradio/upload': workspace:^0.0.1
dependencies:
'@gradio/upload': link:../upload
specifiers: {}
packages/theme:
specifiers:
'@gradio/upload': workspace:^0.0.1
dependencies:
'@gradio/upload': link:../upload
specifiers: {}
packages/tooltip:
specifiers:
'@gradio/upload': workspace:^0.0.1
dependencies:
'@gradio/upload': link:../upload
specifiers: {}
packages/upload:
specifiers: {}
@ -216,7 +205,7 @@ importers:
'@gradio/video': link:../video
devDependencies:
'@sveltejs/adapter-auto': 1.0.0-next.30
'@sveltejs/kit': 1.0.0-next.288_svelte@3.46.3
'@sveltejs/kit': 1.0.0-next.291_svelte@3.46.3
autoprefixer: 10.4.2_postcss@8.4.6
postcss: 8.4.6
postcss-load-config: 3.1.1
@ -358,8 +347,8 @@ packages:
esbuild: 0.14.23
dev: true
/@sveltejs/kit/1.0.0-next.288_svelte@3.46.3:
resolution: {integrity: sha512-6ky4CUFNGKoU1QV+fY2LOIB7atHdUCIMRx3pX21B2g9yZzQzkot0zHBrMMBSKF0/4Wx19PLEWrlGxlhakYmi8Q==}
/@sveltejs/kit/1.0.0-next.291_svelte@3.46.3:
resolution: {integrity: sha512-mFd1EJbxoyPGiomYwYhZnjNLPYahCC2gHfKvPetguL/7BCHcyUjjYQbwTTmjVxtgBs0oLzKVA9bt45gpr9JqBQ==}
engines: {node: '>=14.13'}
hasBin: true
peerDependencies:
@ -431,30 +420,6 @@ packages:
resolution: {integrity: sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw==}
dev: false
/@types/d3-dsv/3.0.0:
resolution: {integrity: sha512-o0/7RlMl9p5n6FQDptuJVMxDf/7EDEv2SYEO/CwdG2tr1hTfUVi0Iavkk2ax+VpaQ/1jVhpnj5rq1nj8vwhn2A==}
dev: false
/@types/d3-path/3.0.0:
resolution: {integrity: sha512-0g/A+mZXgFkQxN3HniRDbXMN79K3CdTpLsevj+PXiTcb2hVyvkZUBg37StmgCQkaD84cUJ4uaDAWq7UJOQy2Tg==}
dev: false
/@types/d3-scale/4.0.2:
resolution: {integrity: sha512-Yk4htunhPAwN0XGlIwArRomOjdoBFXC3+kCxK2Ubg7I9shQlVSJy/pG/Ht5ASN+gdMIalpk8TJ5xV74jFsetLA==}
dependencies:
'@types/d3-time': 3.0.0
dev: false
/@types/d3-shape/3.0.2:
resolution: {integrity: sha512-5+ButCmIfNX8id5seZ7jKj3igdcxx+S9IDBiT35fQGTLZUfkFgTv+oBH34xgeoWDKpWcMITSzBILWQtBoN5Piw==}
dependencies:
'@types/d3-path': 3.0.0
dev: false
/@types/d3-time/3.0.0:
resolution: {integrity: sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==}
dev: false
/@types/node/17.0.14:
resolution: {integrity: sha512-SbjLmERksKOGzWzPNuW7fJM7fk3YXVTFiZWB/Hs99gwhk+/dnrQRPBQjPW9aO+fi1tAffi9PrwFvsmOKmDTyng==}