Tutorial: Audioclips mit Transloadit & Uppy loopen
In letzter Zeit habe ich mich gefragt, welcher unserer Robots mehr Aufmerksamkeit verdient. Einer unserer wahren unbesungenen Helden, ein zuverlässiges Arbeitstier, das gerne übersehen wird, ist der Robot /audio/loop.
Heute rücken wir den Robot /audio/loop ins Rampenlicht und bauen eine Website, die einen Audioclip für eine festgelegte Dauer loopt. Dabei nutzen wir außerdem den mächtigen Dateiuploader Uppy.

Unsere Assembly Instructions
Bevor wir ins Detail der Website-Erstellung gehen, sehen wir uns die Assembly Instructions an, mit denen wir unser Audio loopen.
{
"steps": {
"encode": {
"robot": "/audio/encode",
"use": ":original"
},
"loop": {
"robot": "/audio/loop",
"use": "encode",
"duration": "${fields.duration}"
},
"export": {
"robot": "/s3/store",
"use": "loop",
"credentials": "S3_CREDENTIALS",
"result": true
}
}
}
Zuerst codieren wir die Audiodatei, um unsere Ausgabedatei auf MP3 zu standardisieren. Anschließend
geben wir diese Ergebnisdatei an den Robot /audio/loop weiter. Beim Senden der
Assembly Instructions liefert das Feld duration die vom Nutzer gewählte Anzahl an
Sekunden, wobei im Formular zunächst 60 ausgewählt ist. Schließlich speichern wir das Ergebnis in
einem S3-Bucket, damit wir diese Datei dem Nutzer präsentieren können. Wenn Sie möchten, können Sie
auch einen der anderen Exportdienste, die wir integrieren, verwenden.
Ersetzen Sie S3_CREDENTIALS durch den Namen Ihrer gespeicherten
Template-Zugangsdaten; fügen Sie keine S3-Secrets in das Beispiel ein.
Speichern Sie diese Instructions als Template und verwenden Sie dessen ID im JavaScript unten. Der Browser sendet die Dauer als Feld, sodass wir keine zweite Kopie der Instructions in unserem JavaScript benötigen. Legen Sie niemals ein Auth Secret in Browser-Code ab. Verwenden Sie vor einer öffentlichen Bereitstellung serverseitig erzeugte Signaturen und validieren Sie die angeforderte Dauer auf Ihrem Server; eine Validierung allein im Browser autorisiert die Verarbeitung nicht.
Das HTML-Grundgerüst
Nachdem wir nun unsere Assembly Instructions haben, beginnen wir mit dem Grundgerüst. Zunächst fügen wir ein wenig HTML für unsere Website hinzu.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="https://releases.transloadit.com/uppy/v3.3.1/uppy.min.css" rel="stylesheet" />
<title>Audio Looper</title>
</head>
<body>
<div class="banner">
<a href="https://uppy.io/"
><img src="https://transloadit.com/assets/images/artwork/logos-uppy-default-glyph.svg" alt="Uppy" width="48" height="48"
/></a>
<span id="cross">x</span>
<a href="https://transloadit.com/"
><img src="https://transloadit.com/assets/images/artwork/logos-transloadit-default-glyph.svg" alt="Transloadit" width="48" height="48"
/></a>
</div>
<h1 class="title">Audio Looper</h1>
<div class="input-container">
<label for="duration">Duration:</label>
<input type="number" id="duration" name="duration" min="1" max="300" step="1" value="60" required />
</div>
<div id="dashboard"></div>
<p class="label">Only accepts audio</p>
<div class="result-container">
<audio id="player" controls>
<source id="result" type="audio/mpeg" />
Your browser does not support the audio element.
</audio>
</div>
<p id="status" role="status"></p>
</body>
</html>
Das sieht dann so aus:

Wie Sie sehen, ist es eine recht einfache Website. Das Standard-Styling ist allerdings etwas schwer zu ertragen, also fügen wir eine Prise CSS hinzu, um das Ganze aufzuhübschen.
Fügen Sie das folgende CSS innerhalb von zwei Tags vom Typ <style> ein:
.title {
text-align: center;
font-size: 2rem;
font-weight: 600;
margin-top: 2rem;
font-family: 'Courier New', Courier, monospace;
}
.label {
text-align: center;
font-size: 1rem;
font-weight: 100;
font-style: italic;
margin-top: 1rem;
font-family: 'Segoe UI', sans-serif;
}
.banner {
display: flex;
justify-content: center;
align-items: center;
gap: 1rem;
margin-top: 2rem;
}
.result-container {
display: flex;
justify-content: center;
margin-top: 2rem;
}
.input-container {
display: flex;
justify-content: center;
padding: 1rem;
font-family: 'Segoe UI', sans-serif;
}
input {
border: none;
border-bottom: 2px solid #bcbcbc;
text-align: end;
}
input:focus {
outline: 2px solid currentColor;
outline-offset: 2px;
}
#cross {
font-family: 'Courier New', monospace;
font-size: 2rem;
font-weight: 600;
}
#dashboard {
display: flex;
justify-content: center;
}
Das sieht doch gleich viel besser aus!

Das Uppy-Dashboard
Nachdem HTML und CSS eingerichtet sind, können wir uns dem Uppy-Dashboard zuwenden.
Fügen Sie nach dem HTML das folgende JavaScript innerhalb eines Tags vom Typ <script type="module"> ein:
import {
Uppy,
Dashboard,
Transloadit,
} from 'https://releases.transloadit.com/uppy/v3.3.1/uppy.min.mjs'
const durationInput = document.getElementById('duration')
const status = document.getElementById('status')
const uppy = new Uppy({
restrictions: {
maxNumberOfFiles: 1,
allowedFileTypes: ['audio/*'],
},
onBeforeUpload: () => durationInput.reportValidity(),
})
.use(Dashboard, {
inline: true,
target: '#dashboard',
})
.use(Transloadit, {
waitForEncoding: true,
getAssemblyOptions: () => ({
params: {
auth: { key: 'YOUR_AUTH_KEY' },
template_id: 'YOUR_TEMPLATE_ID',
},
fields: { duration: durationInput.valueAsNumber },
}),
})
uppy.on('transloadit:complete', (assembly) => {
const url = assembly.results.export?.[0]?.ssl_url
if (typeof url !== 'string') {
status.textContent = 'No audio was returned. Please try again.'
return
}
const source = document.getElementById('result')
source.src = url
document.getElementById('player').load()
status.textContent = 'Your looped audio is ready.'
})
uppy.on('upload', () => {
status.textContent = 'Processing audio.'
})
uppy.on('error', () => {
status.textContent = 'Audio processing failed. Please try again.'
})
Hier fügen wir die Uppy-Plugins Dashboard und
Transloadit hinzu und setzen das Ziel unserer Dashboard-Komponente
auf das div #dashboard.
Außerdem übergeben wir unsere Template-ID an das Transloadit-Plugin und setzen die Option
waitForEncoding auf true, damit wir die Ergebnisdatei aus dem JSON der
Assembly auslesen können, nachdem unsere Assembly das Encoding abgeschlossen hat (und nicht
schon, wenn unser Upload fertig ist).
Die gepinnte Uppy-Version verwendet getAssemblyOptions, um beim Start des Uploads die aktuelle Dauer auszulesen.
Das native Eingabefeld erfordert eine ganze Zahl zwischen 1 und 300 Sekunden. Der Completion-Handler
liest die exportierte Datei, nicht den zwischengeschalteten Step loop, und behandelt ein fehlendes Ergebnis, ohne eine Exception zu werfen.
Das Ergebnis
Kombinieren Sie HTML, CSS und das Modul-Skript, konfigurieren Sie Ihr eigenes Template und öffnen Sie die Seite über einen lokalen HTTP-Server. Die Screenshots oben zeigen den ursprünglichen Prototyp; der Code hier enthält die aktualisierte Eingabe- und Ergebnisbehandlung.
Wenn Sie eine Audiodatei hochladen und die Dauer festlegen, sollten Sie die Ergebnisdatei im Audio-Element der Ausgabe sehen, wobei die Dauer dem angegebenen Wert entspricht.
Hoffentlich hat Sie das dazu angeregt, dem Robot /audio/loop noch einmal Beachtung zu schenken, ebenso wie dem besten Dateiuploader der Welt. Wenn Sie über künftige Blogbeiträge (und andere relevante Tech-News!) informiert werden möchten, melden Sie sich unten für unseren Newsletter an (English).
