dawood's picture
dawood HF staff
Upload folder using huggingface_hub
74ba51d verified
<script lang="ts">
import { uploadToHuggingFace } from "@gradio/utils";
import { Empty } from "@gradio/atoms";
import { ShareButton, IconButton, BlockLabel } from "@gradio/atoms";
import { Music } from "@gradio/icons";
import type { I18nFormatter } from "@gradio/utils";
import AudioPlayer from "../player/AudioPlayer.svelte";
import { get_fetchable_url_or_file } from "@gradio/client";
import { createEventDispatcher, onMount } from "svelte";
import { FileData } from "@gradio/client";
export let value: null | FileData = null;
export let image: null | string | FileData = null;
export let label: string;
export let show_label = true;
export let show_download_button = true;
export let show_share_button = false;
export let i18n: I18nFormatter;
export let waveform_settings = {};
export let root = "";
export let proxy_url: string | null = null;
let image_path: string;
$: {
if (image instanceof FileData) {
image_path = image.path;
} else {
image_path = get_fetchable_url_or_file(image, root, proxy_url);
}
}
const dispatch = createEventDispatcher<{
change: FileData;
play: undefined;
pause: undefined;
end: undefined;
stop: undefined;
clear: undefined;
}>();
$: value && dispatch("change", value);
let audioElement;
let isPlaying = false;
function play_audio() {
if (isPlaying) {
audioElement.pause();
isPlaying = false;
return;
} else {
audioElement.play();
isPlaying = true;
}
}
function handle_audio_end(): void {
dispatch("end");
}
</script>
{#if value !== null}
<div class="icon-buttons">
{#if show_share_button}
<ShareButton
{i18n}
on:error
on:share
formatter={async (value) => {
if (!value) return "";
let url = await uploadToHuggingFace(value.url, "url");
return `<audio controls src="${url}"></audio>`;
}}
{value}
/>
{/if}
</div>
<audio src={value.url} controls bind:this={audioElement} on:ended={handle_audio_end}/>
{#if image}
<div class="image-container" on:click={play_audio} role="button" tabindex="0" aria-hidden="true">
<img class="image-player" src={image_path} alt="test" />
{#if !isPlaying}
<!-- Play button -->
<svg class="play-icon" viewBox="0 0 24 24">
<polygon points="5,3 19,12 5,21" fill="currentColor" />
</svg>
{:else}
<!-- Pause button -->
<svg class="pause-icon" viewBox="0 0 24 24">
<rect x="6" y="4" width="4" height="16" fill="currentColor" />
<rect x="14" y="4" width="4" height="16" fill="currentColor" />
</svg>
{/if}
<div class="circle-container waveform-image">
{#each Array(15) as _, i (i)}
<div class={`waveform-bar ${isPlaying ? `waveform-animation-${i % 5}` : ''}`} style={`height: ${20 + (i % 5) * 10}%`}></div>
{/each}
</div>
</div>
{:else}
<div class="circle-container" on:click={play_audio} role="button" tabindex="0" aria-hidden="true">
{#each Array(15) as _, i (i)}
<div class={`waveform-bar ${isPlaying ? `waveform-animation-${i % 5}` : ''}`} style={`height: ${20 + (i % 5) * 10}%`}></div>
{/each}
{#if !isPlaying}
<!-- Play button -->
<svg class="play-icon" viewBox="0 0 24 24" style="pointer-events: none;">
<polygon points="5,3 19,12 5,21" fill="currentColor" />
</svg>
{:else}
<!-- Pause button -->
<svg class="pause-icon" viewBox="0 0 24 24" style="pointer-events: none;">
<rect x="6" y="4" width="4" height="16" fill="currentColor" />
<rect x="14" y="4" width="4" height="16" fill="currentColor" />
</svg>
{/if}
</div>
{/if}
{:else}
<Empty size="small">
<Music />
</Empty>
{/if}
<style>
audio {
display: none;
}
.image-container {
position: relative;
width: 350px;
height: 350px;
margin: auto;
}
.image-player {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 50%;
object-fit: cover;
}
.play-icon, .pause-icon {
color: white;
pointer-events: none;
position: absolute;
top: 50%;
left: 50%;
width: 75px;
height: 75px;
transform: translate(-50%, -50%);
}
.circle-container:hover .play-icon {
width: 90px;
height: 90px;
}
.pause-icon {
opacity: 0;
transition: opacity 0.3s;
}
.image-container:hover .pause-icon, .circle-container:hover .pause-icon {
opacity: 1;
}
.circle-container:hover .waveform-bar {
opacity: 0.5;
}
.circle-container {
position: relative;
width: 350px;
height: 350px;
margin: auto;
border-radius: 50%;
background: var(--button-secondary-background-fill);
position: relative;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
}
.waveform-image {
opacity: 0.5;
}
.waveform-bar {
background: black;
width: 2%;
height: 20%;
margin: 0 1%;
border-radius: 5px;
opacity: 0.5;
transform-origin: bottom;
}
.waveform-animation-0 {
animation: waveAnimation0 1s infinite ease-in-out;
opacity: 1;
}
.waveform-animation-1 {
animation: waveAnimation1 1.5s infinite ease-in-out;
opacity: 1;
}
.waveform-animation-2 {
animation: waveAnimation2 3s infinite ease-in-out;
opacity: 1;
}
.waveform-animation-3 {
animation: waveAnimation3 2s infinite ease-in-out;
opacity: 1;
}
.waveform-animation-4 {
animation: waveAnimation4 2.5s infinite ease-in-out;
opacity: 1;
}
.waveform-animation-5 {
animation: waveAnimation5 3.5s infinite ease-in-out;
opacity: 1;
}
@keyframes waveAnimation0 {
0%, 100% { height: 50%; }
50% { height: 15%; }
}
@keyframes waveAnimation1 {
0%, 100% { height: 45%; }
50% { height: 25%; }
}
@keyframes waveAnimation2 {
0%, 100% { height: 40%; }
50% { height: 60%; }
}
@keyframes waveAnimation3 {
0%, 100% { height: 70%; }
50% { height: 25%; }
}
@keyframes waveAnimation4 {
0%, 100% { height: 25%; }
50% { height: 70%; }
}
@keyframes waveAnimation5 {
0%, 100% { height: 60%; }
50% { height: 15%; }
}
</style>