Download frontend/src/components/SampleClips.jsx from SiliconLanguage/open-asr-model-explorer: direct link, hf CLI and curl.
- Browser
- Download file 2.72 kB
-
https://huggingface.co/spaces/SiliconLanguage/open-asr-model-explorer/resolve/main/frontend/src/components/SampleClips.jsx
- Command line
-
hf download hf://spaces/SiliconLanguage/open-asr-model-explorer/frontend/src/components/SampleClips.jsx
-
curl -L -o SampleClips.jsx https://huggingface.co/spaces/SiliconLanguage/open-asr-model-explorer/resolve/main/frontend/src/components/SampleClips.jsx
2.72 kB
| /** | |
| * SampleClips.jsx | |
| * "Examples" UI โ lets the user click a language button to instantly load | |
| * a sample audio clip, replicating the Hugging Face demo UX. | |
| * Active selection "sticks" with highlighted styling. | |
| */ | |
| import { useState } from 'react'; | |
| const SAMPLES = [ | |
| { name: 'english', label: '๐บ๐ธ English', file: '/samples/english.wav' }, | |
| { name: 'chinese', label: '๐จ๐ณ Chinese', file: '/samples/chinese.wav' }, | |
| { name: 'spanish', label: '๐ช๐ธ Spanish', file: '/samples/spanish.wav' }, | |
| { name: 'french', label: '๐ซ๐ท French', file: '/samples/french.wav' }, | |
| { name: 'german', label: '๐ฉ๐ช German', file: '/samples/german.wav' }, | |
| { name: 'italian', label: '๐ฎ๐น Italian', file: '/samples/italian.wav' }, | |
| { name: 'japanese', label: '๐ฏ๐ต Japanese', file: '/samples/japanese.wav' }, | |
| { name: 'hindi', label: '๐ฎ๐ณ Hindi', file: '/samples/hindi.wav' }, | |
| ]; | |
| export default function SampleClips({ onSampleSelect, disabled }) { | |
| const [loading, setLoading] = useState(null); | |
| const [selected, setSelected] = useState(null); | |
| async function handleClick(sample) { | |
| setLoading(sample.name); | |
| try { | |
| const response = await fetch(sample.file); | |
| if (!response.ok) throw new Error(`Failed to fetch ${sample.file}`); | |
| const blob = await response.blob(); | |
| // Detect actual audio format from magic bytes (servers may return | |
| // application/octet-stream for .wav files, and some samples may be | |
| // OGG-encoded despite the .wav extension). | |
| const header = new Uint8Array(await blob.slice(0, 4).arrayBuffer()); | |
| const magic = String.fromCharCode(...header); | |
| let mimeType = 'audio/wav'; | |
| if (magic === 'OggS') mimeType = 'audio/ogg'; | |
| else if (magic === 'fLaC') mimeType = 'audio/flac'; | |
| else if (magic.startsWith('\xff\xfb') || magic.startsWith('ID3')) mimeType = 'audio/mpeg'; | |
| const file = new File([blob], sample.file.split('/').pop(), { type: mimeType }); | |
| setSelected(sample.name); | |
| onSampleSelect(file, sample.name); | |
| } catch (err) { | |
| console.error('Sample clip load failed:', err); | |
| } finally { | |
| setLoading(null); | |
| } | |
| } | |
| return ( | |
| <div className="sample-clips"> | |
| <p className="sample-clips-hint">Try one of the sample clips.</p> | |
| <div className="sample-clips-row"> | |
| {SAMPLES.map((s) => ( | |
| <button | |
| key={s.name} | |
| className={`btn ${selected === s.name ? 'btn-sample-active' : 'btn-secondary'}`} | |
| onClick={() => handleClick(s)} | |
| disabled={disabled || loading !== null} | |
| > | |
| {loading === s.name ? 'โฆ' : s.label} | |
| </button> | |
| ))} | |
| </div> | |
| </div> | |
| ); | |
| } | |