Zum Inhalt
Anmelden

/showcases · Brand

Hero-Motion-Loop: vom Text-Prompt zum 460 KB großen Production-Asset

Wie wir das Hero-Video von AudioLab.tools generiert, encodiert und integriert haben: eine dezente, atmende 5-Sekunden-Loop mit einem cyanfarbenen Lichtband. End-to-End-Pipeline inklusive Generierung mit Higgsfield seedance, ffmpeg-WebM- + H.264-Encoding, Bild-Fallback und Handhabung von prefers-reduced-motion.

4. Juni 2026 10 min read
Higgsfield seedance 2.0 ffmpeg libvpx-vp9 libx264 Astro Image

Outcome

460 KB insgesamt ausgeliefert (WebM + MP4). 5 Sekunden dezente Bewegung. Statischer Bild-Fallback für langsame Netzwerke. Vollständig entfernt für Nutzer mit prefers-reduced-motion.


Ein bewegter Hero auf einer Tech-Website ist ein riskanter Schachzug. Macht man es falsch, ist es eine ablenkende, automatisch abspielende Werbung; macht man es richtig, ist es der Unterschied zwischen „noch einer Entwickler-Website“ und „Premium-Marke“. Die Vorgaben, die wir uns gesetzt haben:

  • Dezent. Die Bewegung ist Atmung, keine Aktion. Nichts soll die Aufmerksamkeit vom Text-Overlay ablenken.
  • Winzig. Unter 500 KB Gesamttransport, Punkt.
  • Fallback-first. Die Seite soll auch ganz ohne Video großartig aussehen.
  • Reduced-Motion-respektierend. Nutzer, die sich abgemeldet haben, bekommen nichts Animiertes.

So haben wir das in etwa 20 Minuten tatsächlicher Arbeit erreicht.

Schritt 1: Die Bewegung generieren (Higgsfield seedance 2.0)

Seedance ist hierfür das richtige Modell, Image-to-Video, identitätserhaltend, mit starker Unterstützung für dezente Bewegung. Wir verwendeten dasselbe 21:9-Bild mit cyanfarbenem Lichtband, das wir für den statischen Hero gebaut haben (siehe Brand-Imagery-Pipeline), als Referenzframe.

{
  model: 'seedance_2_0',
  prompt: `The luminous cyan ribbon of light breathes and slowly rotates
           in pitch-black space, with subtle volumetric particles drifting
           through the frame. Very slow, gentle motion — the ribbon appears
           to inhale and exhale, with soft glow pulses. Camera completely
           static. The lighting and composition match the reference image
           exactly. Premium, calm, atmospheric, ambient. No camera movement,
           no cuts, just subtle organic motion of the light ribbon itself.`,
  duration: 5,
  resolution: '720p',
  aspect_ratio: '21:9',
  mode: 'std',
  medias: [{ value: heroImageUrl, role: 'image' }],
}

Zwei Prompt-Vorgaben, die die Ausgabe brauchbar machten:

  1. „Camera completely static.“ Ohne dies fällt seedance auf einen langsamen Hineinschwenk zurück, der wie jedes andere Tech-Video aussieht.
  2. „No camera movement, no cuts, just subtle organic motion.“ Verstärkt Punkt 1 und verhindert, dass das Modell stilistische Schnitte hinzufügt.

Kosten: 22 Credits. Renderzeit: ~70 Sekunden.

Schritt 2: Das Audio entfernen

Seedance gibt eine MP4 mit Audio aus. Das brauchen wir nicht: der Hero ist stumm, und jegliches Audio würde ohnehin bedeuten, dass wir in den meisten Browsern nicht autoplayen könnten.

ffmpeg -i hero.mp4 -an -c:v copy hero-noaudio.mp4

Das -an-Flag entfernt das Audio; -c:v copy überspringt das erneute Encodieren des Videos. Schneller Durchlauf, kein Qualitätsverlust. Wir verwenden diese Ausgabe als Quelle für beide nachfolgenden Encodes.

Schritt 3: VP9 WebM encodieren (moderne Browser)

VP9 in einem WebM-Container komprimiert besser als H.264 und ist die richtige Wahl für Browser, die es unterstützen (~90 % des Traffics).

ffmpeg -i hero.mp4 -an \
  -c:v libvpx-vp9 \
  -b:v 800k -crf 36 \
  -row-mt 1 -tile-columns 2 -threads 4 \
  -deadline good -cpu-used 2 \
  hero.webm

Erwähnenswerte Einstellungen:

  • -crf 36: Qualitätsziel. 36 ist eher aggressiv; das Quellmaterial (ein sich langsam bewegendes, abstraktes Lichtband auf Schwarz) komprimiert außergewöhnlich gut, also können wir es uns leisten.
  • -b:v 800k: Bitraten-Obergrenze. Verhindert, dass VP9 den wenigen Frames mit Bewegung zu viel zuweist.
  • -row-mt 1 -tile-columns 2 -threads 4: Multi-Thread-Encoding. Schnelleres lokales Encodieren ohne Auswirkung auf die Ausgabequalität.
  • -deadline good -cpu-used 2: Abwägung zwischen Qualität und Geschwindigkeit. good/2 ist der Sweetspot für einmalige Assets.

Ausgabe: 252 KB für 5 Sekunden bei 720p.

Schritt 4: H.264 MP4 encodieren (Safari-Fallback)

Safari (und einige ältere Browser) unterstützt VP9 nicht. Wir brauchen eine H.264 MP4 als Fallback.

ffmpeg -i hero-noaudio.mp4 -an \
  -c:v libx264 -crf 28 -preset slow \
  -movflags +faststart -pix_fmt yuv420p \
  hero.mp4

Einstellungen:

  • -crf 28: etwas konservativer als die WebM-crf, weil H.264 dieses Material nicht so effizient komprimiert.
  • -preset slow: bessere Kompression. Wir encodieren einmal, nicht in Echtzeit.
  • -movflags +faststart: verschiebt das MP4-Metadaten-Atom nach vorne, sodass der Browser die Wiedergabe starten kann, bevor die gesamte Datei heruntergeladen ist.
  • -pix_fmt yuv420p: erforderlich für die Safari-Kompatibilität unter iOS.

Ausgabe: 209 KB für 5 Sekunden bei 720p.

Schritt 5: Das Markup einrichten

<section class="relative isolate overflow-hidden">
  {/* Static image fallback — renders first, hidden when video plays */}
  <Image
    src={heroWideImg}
    alt=""
    widths={[1280, 1920, 2560, 3168]}
    sizes="100vw"
    loading="eager"
    fetchpriority="high"
    class="absolute inset-0 -z-10 h-full w-full object-cover"
  />

  {/* Motion video — slow ambient loop */}
  <video
    class="absolute inset-0 -z-10 h-full w-full object-cover opacity-0
           transition-opacity duration-700 motion-reduce:hidden"
    id="hero-video"
    autoplay loop muted playsinline
    preload="metadata"
    aria-hidden="true"
  >
    <source src="/media/hero.webm" type="video/webm" />
    <source src="/media/hero.mp4" type="video/mp4" />
  </video>

  {/* Contrast overlays + text layer */}
  ...
</section>

<script is:inline>
  // Fade the video in once it actually starts playing
  const v = document.getElementById('hero-video');
  v?.addEventListener('playing', () => { v.style.opacity = '1'; });
  if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) v?.remove();
</script>

Drei erwähnenswerte Muster:

  1. Das Bild wird zuerst gerendert, das Video blendet sich ein. Der Nutzer sieht sofort einen wunderschönen statischen Hero. Erst wenn das Video einen Frame decodiert hat und mit der Wiedergabe begonnen hat, blendet es sich über dem Bild ein. Kein ruckeliger schwarzer Blitz, keine wahrgenommene Ladezeit.
  2. motion-reduce:hidden Tailwind-Klasse: deklarative Handhabung von Reduced Motion.
  3. Imperatives Entfernen im Inline-Skript: wenn der Nutzer Reduced Motion aktiviert hat, wird das <video>-Element vollständig aus dem DOM entfernt. Kein Netzwerkrequest, kein Decoding, kein Stromverbrauch.

Was (kurz) schiefging

  • Der erste WebM-Encode war 800 KB. Zu groß. -crf von 30 auf 36 und -cpu-used von 4 auf 2 angehoben; damit auf 252 KB gekommen.
  • Anfängliche Autoplay-Probleme unter iOS. playsinline vergessen. iOS verlangt es für Inline-Video; ohne versucht das Video bei der Wiedergabe, in den Vollbildmodus zu gehen.
  • Die MP4 war vor dem erneuten Encodieren 1,2 MB groß. Die Ausgabe von seedance ist originalgetreu, aber größer als für das Web nötig. Der Re-Encode-Durchlauf mit -crf 28 reduzierte sie auf 209 KB.

Ergebnis

Gesamttransport: 460 KB im schlimmsten Fall (beide Dateien nach dem ersten Laden gecacht). Visuelle Signatur: ein leuchtendes, atmendes cyanfarbenes Lichtband, das die gesamte Homepage aufwertet. Zeit von der Idee bis zur Produktion: ~20 Minuten.

Das allgemeine Prinzip: Wenn du Bewegung auf einem Marken-Hero ausspielst, mach die Encoding-Arbeit. Die Modellausgabe ist das Quell-Asset, nicht das Production-Asset.

Verwandt