Gå til hovedinnhold

VOD-pipeline fra A til Å — lagring, transkoding og distribusjon av stream-opptak

· 9 min lesetid
GeekTech
GeekTech-teamet

En live-strøm er over på sekundet du går av lufta. En VOD (Video On Demand) lever videre, blir søkbar, gjenbrukes på YouTube og kan klippes til TikTok eller Shorts. For seriøse streamere er VOD-arkivet ofte mer verdifullt enn selve live-økten — men bare hvis pipelinen er bygget riktig fra starten. Denne guiden går gjennom hvordan du setter opp en komplett VOD-arbeidsflyt med StreamAdmin: hvordan du fanger råopptak, transkoder til distribusjonsklare formater med FFmpeg, og distribuerer videre til YouTube, egen CDN eller dedikerte arkivtjenere.

Hva er en VOD-pipeline, egentlig?

Begrepet "VOD-pipeline" høres komplisert ut, men er bare en kjede av automatiserte steg som tar et live-opptak og gjør det klart for konsum etter at strømmen er avsluttet. En typisk pipeline ser slik ut:

  1. Opptak — Live-strømmen fanges opp samtidig som den sendes til seere, og lagres som en flat fil (TS, FLV eller MP4)
  2. Segmentering — Lange opptak deles i håndterbare biter (timesvis eller per scene)
  3. Transkoding — Råfilen kjøres gjennom FFmpeg for å produsere distribusjonsklare formater (H.264 MP4 i ulike oppløsninger, eventuelt HLS-segmenter)
  4. Generering av metadata — Thumbnails, varighet, sceneskift-indeks
  5. Distribusjon — Filene flyttes til CDN, lastes opp til YouTube via API, eller publiseres på egen webserver
  6. Arkivering — Råfilen flyttes til kald lagring (S3 Glacier, Backblaze B2 eller eget NAS)

Uten en pipeline ender du med en mappe full av navnløse .flv-filer som du må manuelt konvertere hver gang du skal bruke dem. Med en pipeline er dette automatisk fra det øyeblikket du klikker "End Stream" i OBS.

Innspillingsformater og kvalitet

Hvilket format bør du ta opp i?

For live-streaming-opptak er det tre hovedformater som er aktuelle:

FLV (Flash Video) — Dette er det "native" RTMP-formatet og brukes av OBS og MediaMTX som standard. Fordeler: lite overhead, robust mot brå avbrudd (filen blir spillbar selv om du krasjer midt i opptaket). Ulemper: dårlig kompatibilitet med moderne videoredigeringsprogrammer.

MPEG-TS (Transport Stream) — Brukt for HLS og kringkastingsformater. Fordel: håndterer pakketap og avbrudd bedre enn nesten noe annet format, og er trivielt å segmentere. Ulempe: krever ofte transkoding før det kan redigeres.

MP4 (med fragmentert moov-atom) — Det moderne valget. Bruker -movflags +frag_keyframe+empty_moov i FFmpeg slik at filen blir spillbar selv om opptaket avbrytes uventet. Fordel: direkte avspillbar, redigerbar, distribusjonsklar. Ulempe: marginalt mer overhead enn FLV/TS.

For StreamAdmin-pipelines anbefaler vi MP4 med fragmenterte atomer som standard, og fall-back til TS hvis du har spesielt ustabile innspillingstjenere.

Bitrate og oppløsning for opptak

Et viktig prinsipp: opptak skal ALDRI ha lavere bitrate enn det du sender til live. Hvis du sender 6000 kbps til Twitch og tar opp på 4000 kbps lokalt, har du destruert 33% av kvaliteten på arkivet ditt for å spare diskplass. Diskplass er billig — gjenopptak er umulig.

For seriøse arkiver bør du faktisk ta opp i høyere kvalitet enn live-strømmen. Hvis live-strømmen er begrenset til 6000 kbps for Twitch, ta opp lokalt på 12000-15000 kbps med samme oppløsning. Når du så transkoder for distribusjon kan du senke til ønsket nivå, men du har den høykvalitets-mesteren liggende.

Automatisk opptak med StreamAdmin

StreamAdmin sin streaming-profil har innebygd opptak via MediaMTX. Når du oppretter en profil, kan du sette:

recording:
enabled: true
format: mp4
segment_duration: 3600 # ny fil hver time
output_path: "/var/streamadmin/recordings/{stream_name}/{date}/{time}.mp4"
delete_after_processing: false
max_disk_usage_gb: 500

segment_duration på 3600 sekunder (én time) er en god default. Det gir håndterbare filstørrelser (cirka 4-8 GB per time ved 1080p60), og hvis disken fylles eller MediaMTX kræsjer, mister du maks én time.

Filene navngis automatisk med tidsstempel, og StreamAdmin lagrer metadata (start-tid, varighet, peak-viewers, peak-bitrate) i vod_recordings-tabellen. Dette gjør at du kan finne et spesifikt opptak via panelet uten å lete i filsystemet manuelt.

Trigger transkoding ved end-of-stream

Når en live-økt avsluttes, sender MediaMTX et webhook-kall til StreamAdmin sin API. Dette webhook-et trigger en kø-jobb (Laravel Queue) som starter transkodings-pipelinen. Den asynkrone modellen er viktig: transkoding av en 4-timers økt kan ta 30-60 minutter, og det skal ikke holde på MediaMTX sin tråd.

// StreamAdmin job som trigges ved end-of-stream
class TranscodeVodJob implements ShouldQueue
{
public function handle(): void
{
$this->transcodeToMp4(); // hovedfil i 1080p
$this->generateThumbnails(); // 10 thumbnails per time
$this->generateHlsManifest(); // for direkte avspilling
$this->uploadToStorage(); // S3, B2, eller egen tjener
$this->notifyWebhooks(); // varsle om at VOD er klar
}
}

Transkoding til ulike oppløsninger med FFmpeg

FFmpeg er hjernen i enhver VOD-pipeline. Den kommandoen du velger her bestemmer kvalitet, filstørrelse og kompatibilitet på sluttbruker-siden.

Standard transkode-kommando for VOD

ffmpeg -i input.mp4 \
-c:v libx264 \
-preset slow \
-crf 21 \
-pix_fmt yuv420p \
-profile:v high \
-level 4.1 \
-movflags +faststart \
-c:a aac \
-b:a 160k \
-ar 48000 \
output_1080p.mp4

Nøkkelparametere å forstå:

  • -preset slow — Tar lengre tid å enkode, men gir bedre kvalitet per byte. For VOD (asynkron) er slow eller slower riktig valg. Aldri bruk ultrafast eller veryfast for arkiv-kvalitet.
  • -crf 21 — Constant Rate Factor. Lavere tall = bedre kvalitet og større filer. 18-23 er normalt området; 21 er en god default for 1080p.
  • -movflags +faststart — Flytter moov-atomet til starten av filen. Dette gjør at videoen kan starte avspilling før den er fullstendig nedlastet — kritisk for web-streaming.
  • -pix_fmt yuv420p — Sikrer kompatibilitet med eldre nettlesere og mobile enheter. Uten dette risikerer du at videoen ikke spiller på iPhone.

Multi-bitrate transkoding for adaptiv strømming

Hvis du vil tilby HLS adaptiv strømming på egen tjener, må du produsere flere oppløsninger samtidig:

ffmpeg -i input.mp4 \
-filter_complex "[0:v]split=3[v1][v2][v3]; \
[v1]scale=1920:1080[v1080]; \
[v2]scale=1280:720[v720]; \
[v3]scale=854:480[v480]" \
-map "[v1080]" -c:v:0 libx264 -b:v:0 5000k -preset slow \
-map "[v720]" -c:v:1 libx264 -b:v:1 2800k -preset slow \
-map "[v480]" -c:v:2 libx264 -b:v:2 1400k -preset slow \
-map 0:a:0 -map 0:a:0 -map 0:a:0 \
-c:a aac -b:a 128k \
-f hls \
-hls_time 6 \
-hls_playlist_type vod \
-hls_segment_filename "v%v/segment_%03d.ts" \
-master_pl_name master.m3u8 \
-var_stream_map "v:0,a:0 v:1,a:1 v:2,a:2" \
"v%v/playlist.m3u8"

Dette produserer tre kvalitetsnivåer (1080p, 720p, 480p) i HLS-format, klare for direkte avspilling i en HTML5-spiller eller via en CDN.

Lyd: ikke gå på akkord

Lyd er det første publikum klager på, og det er gratis å gjøre riktig. Bruk alltid AAC i -b:a 160k eller høyere, samplingrate 48 kHz. Hvis kildematerialet er stereo, behold stereo. Ikke down-mix til mono "for å spare plass" — det merkes umiddelbart.

Distribusjon: YouTube, egen CDN, eller dedikerte arkiv-tjenere

YouTube via Data API v3

Mange streamere klipper hovedhøydepunkter manuelt og laster opp til YouTube. Dette skalerer dårlig hvis du streamer 4-5 økter per uke. YouTube Data API v3 lar deg laste opp programatisk, og StreamAdmin kan integrere mot dette via OAuth:

# Pseudo-flow:
# 1. Bruker autentiserer med YouTube OAuth i StreamAdmin
# 2. StreamAdmin lagrer refresh token kryptert
# 3. Etter VOD-transkoding: laster opp via API
# 4. Setter tittel, beskrivelse, thumbnail, kategori, taggene fra stream-metadata

Vær oppmerksom på YouTube sine kvotegrenser — Data API v3 har en daglig kvote på 10 000 enheter, og hver upload koster 1600 enheter. I praksis betyr dette omtrent 6 uploads per dag før du må be om kvote-økning.

Egen CDN: Cloudflare R2 eller Backblaze B2

Hvis du vil hoste VOD-arkivet selv (kontroll, ingen YouTube-monetiseringsregler, lavere kostnader på lang sikt), er Cloudflare R2 og Backblaze B2 de to beste alternativene. Begge tilbyr S3-kompatible APIer, og begge har gratis egress når du serverer via Cloudflare.

# Eksempel: last opp til Cloudflare R2 med rclone
rclone copy /var/streamadmin/recordings/processed/2026-05-02_episode-87.mp4 \
r2:streamadmin-vods/2026/05/ \
--progress \
--transfers 4

Cloudflare Stream er et alternativ til "ren" R2 hvis du vil ha innebygd HLS adaptiv strømming uten å selv segmentere. Det koster mer per minutt video, men sparer deg for FFmpeg-arbeidet.

Dedikert arkiv-tjener med Nginx

For den som vil ha full kontroll: en VPS med stor disk (Hetzner sitt SX-line, OVH eller eget hardware) og Nginx med mp4-modulen aktivert gir deg en personlig YouTube. Pseudo-konfig:

location /vod/ {
mp4;
mp4_buffer_size 1m;
mp4_max_buffer_size 5m;
add_header Accept-Ranges bytes;
root /var/vods;
}

Med dette serveres MP4-filer med byte-range support, slik at sluttbrukere kan hoppe frem og tilbake i videoen uten å laste den helt ned.

Lagringsstrategi og kostnader

Her er hvor mange streamere undervurderer kompleksiteten. La oss regne på en realistisk produksjonsstreamer som streamer 4 ganger i uka, 4 timer per økt:

  • 16 timer/uke live-tid
  • 1080p60 ved 6 Mbit/s = ca 2,7 GB/time
  • Live-arkiv: 16 × 2.7 = ~43 GB/uke = ~2,2 TB/år

Hvis du i tillegg lagrer et høykvalitets-master på 12 Mbit/s, dobles dette til ~4,4 TB/år. Etter tre år snakker vi 13 TB ren videodata. Dette er ikke "litt diskplass" lenger — det er en datasenter-investering.

Tre-nivå lagringsstrategi

Den profesjonelle løsningen er tiered storage:

  1. Hot tier (siste 30 dager): SSD eller raskt NVMe på selve transkode-tjeneren. Brukes til umiddelbare klipping/distribusjon. Pris: høy per GB.
  2. Warm tier (30 dager - 1 år): Spinning rust på samme tjener, eller B2/R2 standard. Sjelden tilgang, men rimelig hentbar. Pris: lav per GB.
  3. Cold archive (>1 år): S3 Glacier Deep Archive eller eget NAS-system uten online-tilgjengelighet. Pris: nesten ingenting per GB, men dyrt å hente ut.

StreamAdmin sin VOD-modul kan automatisk flytte filer mellom disse nivåene basert på alder via en kø-jobb som kjører nattlig.

Avslutning

En VOD-pipeline er ikke noe du setter opp på 30 minutter mellom to streams. Det er infrastruktur som krever planlegging av lagring, encoding-kvalitet, distribusjon og arkivering — men det er også infrastruktur som lønner seg eksponensielt over tid. En streamer med tre års velorganisert VOD-arkiv har en innholdsbase som er nesten umulig å kopiere; en streamer uten arkiv starter på null hver gang.

Vil du komme i gang? Les den fullstendige dokumentasjonen på doc.geektech.no/streamadmin eller opprett en konto direkte på streamadmin.no. Hvis du har spørsmål om FFmpeg-parametere, transkode-strategier eller har funnet en bedre kombinasjon enn det vi anbefaler her, snakk med oss i Discord — vi sitter ofte og diskuterer encoding-tradeoffs sent på kveld der.