上传文件

把本地文件转成 FFHub 能读的公网 URL。

FFHub 的处理 worker 跑在云上,只能读公网 URL。如果你的文件在本地、手机里、或者私有云存储里,先上传到 FFHub Storage 拿一个公网链接,再塞进 ffmpeg 命令。

上传是怎么走的

两步搞定,文件不经过我们的服务器。客户端拿一个一次性签名 URL,直接 PUT 到 R2。

  1. 签名。 POST /v1/uploads/sign 返回一个 15 分钟内有效的预签名 URL。
  2. PUT。curlfetch 或者任何 HTTP 客户端把字节传到那个 URL。

这样单文件能传到 5 GB,且数据链路不经过我们的服务器。

第 1 步 —— 拿签名 URL

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"
  }'

响应:

{
  "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"
}

第 2 步 —— 上传文件

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

Content-Type必须和第 1 步传的 content_type 一模一样 —— 不然 R2 直接拒签名。

PUT 返回 200/204 后,第 1 步给的 public_url 立刻就能访问。

完整示例

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

# 1. 签名
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. 直接 PUT 到 R2
curl -X PUT "$UPLOAD_URL" \
  -H "Content-Type: video/mp4" \
  --data-binary "@$FILE"

# 3. 用 public_url 作为输入提交任务
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\"}"

CLI 帮你把整套流程自动跑了 —— 见 CLI

限制

  • 大小上限:单次上传 5 GB(R2 单次 PUT 上限)
  • 签名有效期:从 expires_at 起 15 分钟,过期就再签一次
  • 文件保留:7 天,到期 R2 自动删

要保存超过 7 天的话,任务跑完后立刻复制到你自己的 bucket。

已经有公网 URL?

那就跳过这套流程。任务 API 的 -i 输入接受任意公网 URL:

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"}'

你的 S3、你的 CDN、我们的存储 —— 对任务模块来说都一样,字节在哪儿无所谓。

上传文件 — FFHub Docs