Dateien hochladen

Lokale Dateien in öffentliche URLs verwandeln, die FFHub lesen kann.

FFHub-Worker laufen in der Cloud und akzeptieren nur öffentliche URLs als Eingabe. Wenn deine Datei lokal, auf dem Handy oder in einem privaten Bucket liegt, lade sie zuerst in den FFHub-Storage hoch und übergib die zurückgegebene URL deinem ffmpeg-Befehl.

Wie der Upload läuft

Zwei Schritte, und die Datei landet nie auf unserem Server. Dein Client holt sich eine einmalige signierte URL und PUTtet die Bytes direkt zu R2.

  1. Signieren. POST /v1/uploads/sign liefert eine signierte URL, die 15 Minuten gültig ist.
  2. PUT. Lade die Bytes mit curl, fetch oder einem beliebigen HTTP-Client an diese URL.

So lassen sich Dateien bis 5 GB hochladen, ohne dass unsere Server im Datenpfad sitzen.

Schritt 1 — Signierte URL holen

curl -X POST https://api.ffhub.io/v1/uploads/sign \
  -H "Authorization: Bearer $FFHUB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filename": "input.mp4",
    "size": 12345678,
    "content_type": "video/mp4"
  }'

Antwort:

{
  "upload_url": "https://...r2.cloudflarestorage.com/...?X-Amz-Signature=...",
  "public_url": "https://storage.ffhub.io/tmp/uploads/<user>/<rand>.mp4",
  "key": "tmp/uploads/<user>/<rand>.mp4",
  "content_type": "video/mp4",
  "expires_at": "2026-05-12T05:30:00Z"
}

Schritt 2 — Datei hochladen

curl -X PUT "$UPLOAD_URL" \
  -H "Content-Type: video/mp4" \
  --data-binary "@./input.mp4"

Der Content-Type-Header muss exakt mit dem content_type aus Schritt 1 übereinstimmen — sonst lehnt R2 die Signatur ab.

Sobald der PUT 200/204 zurückgibt, ist die public_url aus Schritt 1 sofort lesbar.

End-to-End-Beispiel

FILE=./input.mp4
SIZE=$(stat -f%z "$FILE" 2>/dev/null || stat -c%s "$FILE")

# 1. Signieren
SIGNED=$(curl -s -X POST https://api.ffhub.io/v1/uploads/sign \
  -H "Authorization: Bearer $FFHUB_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"filename\":\"input.mp4\",\"size\":$SIZE,\"content_type\":\"video/mp4\"}")

UPLOAD_URL=$(echo "$SIGNED" | jq -r '.upload_url')
PUBLIC_URL=$(echo "$SIGNED" | jq -r '.public_url')

# 2. Direkt zu R2 hochladen
curl -X PUT "$UPLOAD_URL" \
  -H "Content-Type: video/mp4" \
  --data-binary "@$FILE"

# 3. Task mit public_url als Eingabe einreichen
curl -X POST https://api.ffhub.io/v1/tasks \
  -H "Authorization: Bearer $FFHUB_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"command\":\"-i $PUBLIC_URL -c:v libx264 -crf 28 output.mp4\"}"

Die CLI macht den ganzen Tanz automatisch — siehe CLI.

Limits

  • Maximalgröße: 5 GB pro Upload (R2-Limit für einen einzelnen PUT)
  • Lebensdauer der signierten URL: 15 Minuten ab expires_at; danach einfach neu signieren
  • Lebensdauer der Datei: 7 Tage, danach wird sie aus R2 gelöscht

Wenn du Dateien länger als 7 Tage behalten willst, kopier sie direkt nach dem Job in deinen eigenen Bucket.

Schon eine öffentliche URL?

Dann spar dir den ganzen Flow. Die Task-API akzeptiert jede öffentliche URL als -i-Eingabe:

curl -X POST https://api.ffhub.io/v1/tasks \
  -H "Authorization: Bearer $FFHUB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"command":"-i https://example.com/clip.mp4 -c:v libx264 output.mp4"}'

Dein S3, dein CDN, unser Storage — alles gleichwertig. Dem Task-Modul ist es egal, wo die Bytes liegen.

Dateien hochladen — FFHub Docs