上传文件
把本地文件转成 FFHub 能读的公网 URL。
FFHub 的处理 worker 跑在云上,只能读公网 URL。如果你的文件在本地、手机里、或者私有云存储里,先上传到 FFHub Storage 拿一个公网链接,再塞进 ffmpeg 命令。
上传是怎么走的
两步搞定,文件不经过我们的服务器。客户端拿一个一次性签名 URL,直接 PUT 到 R2。
- 签名。
POST /v1/uploads/sign返回一个 15 分钟内有效的预签名 URL。 - PUT。 用
curl、fetch或者任何 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、我们的存储 —— 对任务模块来说都一样,字节在哪儿无所谓。