API v1/服务器到服务器生产

只需几分钟即可交付您的第一份媒体工作。

向 MediaRuntime 提供可访问的媒体 URL,准确请求所需输出,并接收已签名的终态 Webhook。只有在没有现成源 URL 时,才使用可选上传端点。

快速入门

创建作业、等待完成,然后下载 ZIP 包。

CLI 接受相对或绝对本地文件路径,并自动上传文件字节。MediaRuntime 也可直接接受公共 HTTP(S) URL 或限时签名读取 URL。首次运行时,使用 CLI 的 --download 选项或 SDK 的 job.wait() helper 获取规范 ZIP 包。在生产环境中,应保存 job_id 并处理已签名的账户 Webhook,而不是轮询。

cURL
提交现有媒体 URL
# Submit a public or time-limited HTTPS source directly.
# Keep the URL fetchable until MediaRuntime has downloaded the input.
curl -sS -X POST "https://mediaruntime.com/v1/jobs" \
  -H "X-API-Key: $MEDIARUNTIME_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "source": "https://cdn.example.com/media/launch-trailer.mp4",
    "metadata": { "asset_id": "asset_0426", "media_type": "video" },
    "outputs": ["video.web"]
  }'

克隆完整的快速入门项目

一个公开仓库集中提供可运行的 Node.js 和 Python SDK 项目、Go 和 PHP HTTP 示例、签名 Webhook 接收器以及 Postman 指南。

在 GitHub 查看快速入门
带上您现有的媒体 URL
将 `source` 设置为公共 HTTP(S) URL,或来自现有存储的短期签名读取 URL。在排队和工作进程下载源文件期间,该 URL 必须保持可访问。旧字段 `file_url` 将继续受支持。MediaRuntime 无需成为源文件的记录系统。
生产环境:使用账户 Webhook
使用 `job.wait()` 完成本地验证后,将 `job.id` 与业务实体 ID 一起保存,并处理发送到账户 → Webhooks 中所配置目标的已签名终态事件。提交的 metadata 会原样返回,用于对账。
Bash
本地字节的可选上传
# Optional: use this when you have local bytes but no fetchable source URL.
UPLOAD=$(curl -sS -X POST "https://mediaruntime.com/v1/upload-url" \
  -H "X-API-Key: $MEDIARUNTIME_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"filename":"launch-trailer.mp4","content_type":"video/mp4"}')

UPLOAD_URL=$(printf '%s' "$UPLOAD" | jq -r .upload_url)
FILE_URI=$(printf '%s' "$UPLOAD" | jq -r .file_uri)
UPLOAD_CONTENT_TYPE=$(printf '%s' "$UPLOAD" | jq -r '.upload_headers["Content-Type"]')
UPLOAD_AUTH=$(printf '%s' "$UPLOAD" | jq -r '.upload_headers.Authorization // empty')

UPLOAD_ARGS=(-H "Content-Type: $UPLOAD_CONTENT_TYPE")
if [[ -n "$UPLOAD_AUTH" ]]; then
  UPLOAD_ARGS+=(-H "Authorization: $UPLOAD_AUTH")
fi
curl -sS -X PUT "$UPLOAD_URL" "${UPLOAD_ARGS[@]}" \
  --upload-file ./launch-trailer.mp4

# Then use "$FILE_URI" as source in POST /v1/jobs.
JSON
立即响应
{
  "job_id": "job_1320c28b72104811b075a26a99496cf6",
  "status": "QUEUED",
  "tier": "standard",
  "required_tier": "standard",
  "outputs": [{
    "alias": "video.web",
    "type": "mp4",
    "preset": "mp4_720p_h264_aac"
  }],
  "msg": "accepted"
}
命令行

在终端中运行并检查媒体作业。

官方 CLI 是处理本地文件、诊断生产问题、下载输出包以及测试本地 webhook 接收器的最快方式。CLI、Node SDK 和 Python SDK 均为稳定的 1.x 软件包,其文档化接口遵循语义化版本控制。它们使用相同的公开作业契约,并保持 ZIP 输出包为规范结果。

Bash
安装并授权一次
npm install --global @mediaruntime/cli
mediaruntime login
mediaruntime jobs list --limit 3
浏览器登录或环境密钥
`mediaruntime login` 会创建专用且可撤销的 CLI 凭据,并存入操作系统安全凭据库。`MEDIARUNTIME_API_KEY` 将永久受到支持,并在设置后始终优先。

提交本地文件并下载完整输出包

传入如 ./launch.mp4 的相对路径或绝对本地文件路径,CLI 会在创建任务前自动上传。在交互式终端中,进度指示器会显示上传、等待和验证下载阶段。--download 会等待终态并以原子方式发布规范 ZIP。除非显式使用 --force,否则不会覆盖现有文件。

Bash
运行一个幂等作业
# The CLI uploads this local file before creating the job.
# Relative paths such as ./launch.mp4 work too.
mediaruntime run "/Users/you/Videos/launch.mp4" \
  -o video.streaming \
  -o audio.transcription \
  --metadata '{"asset_id":"launch-01"}' \
  --idempotency-key 'asset:launch-01:v1' \
  --download ./launch-01.zip

查看实时公开目录

mediaruntime capabilities 汇总别名和功能,mediaruntime presets list 返回有序的公开 preset 目录。这些只读命令无需浏览器登录或 MEDIARUNTIME_API_KEY。

Bash
检查能力和 preset
# Public discovery commands do not require login or an API key.
mediaruntime capabilities
mediaruntime presets list

# Use JSON when another tool will consume the catalog.
mediaruntime presets list --json

运行精确的公开 preset

对 DASH 或 VP9 等精确目录项可重复使用 --preset。CLI 会在创建作业前根据实时公开目录验证每个名称;别名和精确 preset 可按请求顺序组合使用。

Bash
请求 DASH 和 VP9 输出
# Preset names are validated against the live public catalog.
mediaruntime run ./launch.mp4 \
  --preset dash_ladder_v1 \
  --preset webm_vp9_1080p \
  --download ./adaptive-and-vp9.zip

检查和获取作业

列出一页账户作业、按状态筛选、检查单个作业,或下载其保留期内的 ZIP 输出包。使用 jobs list 输出的不透明游标请求下一页。

Bash
列出、检查和下载
mediaruntime jobs list --status COMPLETED --limit 20
mediaruntime jobs get job_123
mediaruntime jobs get job_123 --download ./job_123.zip

自动化使用 API 密钥

CI、服务器和容器应从密钥管理器注入 MEDIARUNTIME_API_KEY。不要把凭据放入命令参数、源代码管理、日志或明文配置文件。

Bash
非交互式身份验证
# Permanently supported for CI, servers, and containers.
export MEDIARUNTIME_API_KEY="sk_..."
mediaruntime jobs list --limit 3
能力
输出别名
命令契约
--output video.web
说明
支持全部六个固定别名;重复 --output 可请求多个交付物。
能力
机器输出
命令契约
--json
说明
为脚本和 CI 输出一条紧凑且移除签名 URL 的 JSON 结果。
能力
安全重试
命令契约
--idempotency-key
说明
进程重启后,同一逻辑作业仍应复用同一个业务密钥。
能力
输出包安全
命令契约
--download / --force
说明
只下载终态输出包,校验公布的完整性,并防止意外覆盖。
能力
退出状态
命令契约
0–9, 130
说明
身份验证、API 拒绝、终态失败、超时、trigger 和输出包错误使用不同的非零代码。
Bash
发送签名的本地终态事件
export MEDIARUNTIME_WEBHOOK_SECRET="whsec_..."

mediaruntime trigger job.completed \
  --to http://127.0.0.1:3000/webhooks/mediaruntime
无需中继即可测试本地 webhook 代码
`mediaruntime trigger` 会对准确的 JSON 字节签名,并直接发送到显式的 loopback URL。它支持 `job.completed`、`job.failed` 和 `job.rejected`;不会注册或替代在账户 → Webhooks 中配置的生产 webhook。
认证

将 API 密钥保留在您的服务器上。

从帐户 → 开发者设置 → API 密钥创建密钥。原始密钥仅显示一次并属于您的秘密管理器,而不是浏览器代码、移动二进制文件、日志或源代码控制。

标头

在每个 /v1 请求上发送 X-API-Key。

存储

将 MEDIARUNTIME_API_KEY 存储在服务器端秘密管理器中。

旋转

创建替换密钥,部署它,验证流量,然后撤销旧密钥。

X-API-Key: sk_live_…
Bash
CLI:通过浏览器登录
npm install --global @mediaruntime/cli
mediaruntime login
mediaruntime jobs list --limit 3
自动化仍使用 API 密钥
`mediaruntime login` 会将专用且可撤销的凭据存入操作系统安全凭据库。CI、服务器、SDK 和容器应继续从密钥管理器使用 `MEDIARUNTIME_API_KEY`;显式环境变量密钥的优先级高于 CLI 登录。
创造就业机会

让元数据完成集成关联。

wMedia 使用的生产模式有意保持简单:提交输入、输出配方以及足够的不透明元数据,以便将终态事件关联回您自己的数据库记录。

JSON
生产式要求
{
  "source": "https://cdn.example.com/media/source.mp4",
  "metadata": {
    "producer": "my-api",
    "entity_id": "video_01J8Y4",
    "owner_id": "user_482",
    "media_type": "video",
    "trace_id": "req_f839"
  },
  "moderation": {
    "enabled": true,
    "mode": "report",
    "checks": ["sexual", "violence", "dangerous"]
  },
  "watermark": { "enabled": true },
  "outputs": [
    {
      "type": "mp4",
      "preset": "mp4_720p_h264_aac",
      "path_suffix": "web",
      "poster_time_sec": 2,
      "gif_preview": {
        "enabled": true,
        "width": 320,
        "fps": 8,
        "start_time": 2,
        "duration": 2.5
      }
    },
    {
      "type": "image",
      "preset": "image_multi_v1",
      "path_suffix": "covers",
      "images": [
        { "width": 1280, "height": 720, "mode": "fit", "format": "webp", "quality": 84 },
        { "width": 480, "height": 480, "mode": "cover", "format": "webp", "quality": 80 }
      ]
    }
  ]
}
领域
source
类型
字符串或对象
注释
规范的单一输入:公共 HTTP(S)、限时签名 HTTP(S)、可访问的 gs:// URL,或仅包含 url 的对象。
领域
file_url
类型
字符串
注释
标量 source 的永久兼容字段。请勿同时提交 source 和 file_url。
领域
inputs
类型
数组
注释
1–25 个输入的批量扇出。每项使用标准 source;旧版 file_url 仍按项兼容。请勿与任一单一输入字段同时提交。
领域
outputs
类型
数组
注释
1–10 个输出配方。每个都需要类型;强烈推荐预设。
领域
metadata
类型
对象
注释
JSON 高达 32 KiB。在meta.request_metadata 上坚持并回应。
领域
moderation
类型
对象
注释
Premium 视觉媒体 检查:性、暴力、危险。
领域
watermark
类型
对象
注释
Premium 视觉媒体叠加。该帐户必须已有 PNG 徽标。

批量扇出

当每个输入需要相同的 输出 时,请使用批处理。每个输入 元数据 合并到每个子作业中;父作业将成为您的批次参考。

JSON
2个输入,1个输出配方
{
  "inputs": [
    {
      "source": "https://cdn.example.com/a.mp4",
      "input_id": "asset-a",
      "metadata": { "position": 0 }
    },
    {
      "source": "https://cdn.example.com/b.mp4",
      "input_id": "asset-b",
      "metadata": { "position": 1 }
    }
  ],
  "metadata": { "batch_id": "import_2026_08_09" },
  "outputs": [{ "type": "mp4", "preset": "mp4_720p_h264_aac" }]
}

使用 Idempotency-Key 安全重试

超时请求是不明确的:作业可能已排队,但仅丢失了响应。发送 Idempotency-Key 标头并重试是安全的 - 相同的密钥返回原始作业,而不是排队并为第二个作业收费。如果没有标头,行为不会改变,并且每个 POST 都会创建一个新作业。

Bash
安全地重试相同的提交
# One key per logical job. Generate it in your client, not inside the retry loop.
KEY=$(uuidgen)   # or a deterministic id you can regenerate: asset_0426:mp4_720p:v1

curl -sS -X POST "https://mediaruntime.com/v1/jobs" \
  -H "X-API-Key: $MEDIARUNTIME_API_KEY" \
  -H "Idempotency-Key: $KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "source": "https://example.com/source.mp4",
    "metadata": { "asset_id": "asset_0426" },
    "outputs": [{ "type": "mp4", "preset": "mp4_720p_h264_aac" }]
  }'

# Timed out? Send the exact same request again with the SAME key.
# You get the original job_id back - no second job, no second charge.
您生成密钥,而不是我们
MediaRuntime 无法自行区分两个请求 - 只有您的客户端知道第二次调用是重试而不是新工作。每个逻辑作业生成一个密钥,并在该作业的每次重试中重复使用它。在重试循环内生成密钥将为每次尝试提供一个新密钥并完全消除保护。

关键规则

  • UUID 有效;像 asset_0426:mp4_720p:v1 这样的确定性 ID 更好,因为您可以在崩溃后重新生成它。
  • 密钥的范围仅限于您的帐户,并且 24 小时内有效。
  • 重复使用具有不同主体的密钥会返回 422 — 通常在循环中重复使用一个密钥。
  • 当第一个仍在运行时发送的重试返回 409;短暂退避后重试。
  • 故意提交同一个文件两次?使用两个不同的键。
输出预设

选择您希望引擎生成的工件。

常见作业应优先使用固定输出别名。需要自定义配方时再使用明确的 `type` 和 `preset`;不匹配的组合可能被拒绝或错误路由。

固定输出别名

别名是网关保证的稳定契约。它们会在验证、估算、计费和持久化之前解析,并且可以在同一个 outputs 数组中与明确的输出对象混用。

别名
video.web
解析为
mp4 / mp4_720p_h264_aac, JPG poster at 2s
产物
720p H.264/AAC MP4 和 JPG 海报
层级
Standard
别名
video.streaming
解析为
hls / hls_ladder_v1
产物
HLS 主播放列表、1080p/720p 变体和分段
层级
Standard
别名
video.social
解析为
social / social_vertical_blur
产物
带模糊 9:16 填充的 1080×1920 MP4
层级
Premium
别名
audio.web
解析为
audio / audio_aac_128k
产物
128 kbps AAC/M4A
层级
Standard
别名
audio.transcription
解析为
audio / audio_aac_128k with base subtitles
产物
AAC/M4A 以及 SRT 和 WebVTT 字幕
层级
Standard
别名
image.web
解析为
image / image_multi_v1 with two WebP renditions
产物
1200×630 和 320×320 WebP 衍生图
层级
Premium
JSON
垂直社交视频
{
  "source": "https://cdn.example.com/landscape-interview.mp4",
  "outputs": ["video.social"]
}
社交执行什么
social_vertical_blur 创建 1080×1920 H.264/AAC MP4。源被缩放以适应而不裁剪;其后面的 9:16 画布上充满了模糊的副本。将其用于 Reels、TikTok 和 Shorts。它是 Premium 配方,因为垂直输出高为 1920 像素。

视频文件和海报

预设
video_clip_v1 (type: mp4)
发送
视频
作业执行
将精确源时间范围渲染为 H.264/AAC MP4,支持原始或竖屏模糊背景以及可选的转录字幕。使用 Standard 处理,无需重复转录。 clip.mp4, clip.srt and clip.vtt when transcript is supplied.
基础层
Standard
预设
mp4_720p_h264_aac (type: mp4)
发送
视频
作业执行
720p H.264/AAC MP4 具有快速启动功能,可进行网络播放。 MP4 video.
基础层
Standard
预设
mp4_ladder_v1 (type: mp4)
发送
视频
作业执行
三个 MP4 版本(1080p、720p 和 480p),以及每个版本的海报。 1080p MP4, 720p MP4, 480p MP4.
基础层
Standard
预设
transmux_mp4_fast (type: mp4)
发送
视频
作业执行
将现有流复制到快速启动 MP4 中,无需重新编码。如果复制失败并且启用了回退,引擎将使用 720p H.264 预设 重新编码。 MP4 video.
基础层
Standard
预设
poster_frame_v1 (type: mp4)
发送
视频
作业执行
在 poster_time_sec 处捕获的一张 720p JPG。请求类型仍然是mp4。 JPG poster.
基础层
Standard
预设
mp4_hevc_1080p (type: mp4)
发送
视频
作业执行
1080p HEVC/H.265 + AAC MP4 带有适用于 Apple 播放的 hvc1 标签。 HEVC MP4.
基础层
Premium
预设
mp4_av1_smart (type: mp4)
发送
视频
作业执行
1080p AV1 + Opus MP4 针对压缩效率进行了优化;编码是 CPU 密集型的。 AV1 MP4.
基础层
Premium
预设
mov_prores_422 (type: mp4)
发送
视频
作业执行
ProRes 422 HQ + PCM MOV 编辑大师。保留源尺寸并生成大的夹层文件。 ProRes MOV.
基础层
Premium

社交视频

预设
audiogram_v1 (type: social)
发送
音频或带音频的视频
作业执行
使用适配封面、高对比度波形和安全区域内的可选字幕,将音频合成为 Premium H.264/AAC 社交 MP4,并生成无字幕海报。 H.264/AAC audiogram MP4, caption-free poster JPEG, audiogram.json, audiogram.waveform.json.
基础层
Premium
预设
social_vertical_blur (type: social)
发送
视频
作业执行
1080×1920 H.264/AAC MP4。适合 Reels、TikTok 和 Shorts 的模糊 9:16 背景。 vertical MP4.
基础层
Premium

动画 GIF

预设
gif_hq (type: gif)
发送
图像或视频
作业执行
使用调色板生成以 480 像素宽度和 15 fps 制作动画 GIF,以获得更好的颜色质量。 animated GIF.
基础层
Standard

帧提取

预设
clip_candidates_v1 (type: frames)
发送
音频或带音频的视频
作业执行
使用现有 Whisper 或提供的源时间转录、语音边界和关键词建议剪辑。Premium 分析;分数不预测热度。 clip_candidates.json with candidates and reusable source-timed transcript.
基础层
Premium
预设
contact_sheet_v1 (type: frames)
发送
视频
作业执行
生成编号视频联系表图像和 contact_sheet.json,并将每个图块映射到源时间戳。 numbered contact-sheet images, contact_sheet.json.
基础层
Standard
预设
extract_frames_1 (type: frames)
发送
视频
作业执行
编号为 JPG 的帧序列以每秒 1 帧的速度采样。 JPG frames at 1 fps.
基础层
Standard
预设
extract_frames_5 (type: frames)
发送
视频
作业执行
编号为 JPG 的帧序列以每秒 5 帧的速度采样。 JPG frames at 5 fps.
基础层
Standard
预设
scene_detect_v1 (type: frames)
发送
视频
作业执行
检测镜头边界,为每个镜头导出一张 JPG 关键帧,并生成包含时间戳和分数的 scenes.txt 索引。 scene JPGs, scene timeline.
基础层
Standard
预设
perceptual_hash_v1 (type: frames)
发送
视频
作业执行
对视频进行采样,并将 64 位感知指纹写入 phash.json,用于检测重新上传和近似重复内容。 phash.json.
基础层
Standard

流媒体

预设
hls_ladder_v1 (type: hls)
发送
视频
作业执行
HLS VOD 包,包含 1080p 和 720p H.264/AAC 变体、主播放列表和 6 秒片段。 HLS master playlist, variant playlists, media segments.
基础层
Standard
预设
transmux_hls_fast (type: hls)
发送
视频
作业执行
无需重新编码即可将兼容流复制到 HLS 包。启用回退后,不兼容的流会使用 hls_ladder_v1 编码。 HLS master playlist, variant playlist, media segments.
基础层
Standard

MPEG-DASH 流媒体

预设
dash_ladder_v1 (type: dash)
发送
视频
作业执行
MPEG-DASH 包,包含 1080p 和 720p H.264/AAC 表示、标准 manifest.mpd 和分段 MP4 片段。 DASH MPD, initialization segments, media segments.
基础层
Standard
预设
transmux_dash_fast (type: dash)
发送
视频
作业执行
无需重新编码即可将兼容流复制到 MPEG-DASH。启用回退后,不兼容的流会使用 dash_ladder_v1 编码。 DASH MPD, initialization segments, media segments.
基础层
Standard

WebM 视频

预设
webm_vp9_1080p (type: webm)
发送
视频
作业执行
面向现代浏览器的 1080p VP9 + Opus WebM。这是真正的 VP9 编码,而不是 MP4 标签。 VP9 WebM.
基础层
Premium

音频

预设
audio_copy_fast (type: audio)
发送
音频或带音频的视频
作业执行
复制源音频流而不重新编码。如果复制失败并且启用了回退,引擎将改为写入 128 kbps AAC。 audio file.
基础层
Standard
预设
audio_aac_128k (type: audio)
发送
音频或带音频的视频
作业执行
快速启动 M4A 文件中的 128 kbps AAC。 M4A audio.
基础层
Standard
预设
audio_mp3_128k (type: audio)
发送
音频或带音频的视频
作业执行
128 kbps MP3 文件。 MP3 audio.
基础层
Standard
预设
audio_opus_96k (type: audio)
发送
音频或带音频的视频
作业执行
96 kbps Opus 文件,非常适合语音传送。 Opus audio.
基础层
Standard
预设
audio_loudnorm_aac_128k (type: audio)
发送
音频或带音频的视频
作业执行
标准化为 -16 LUFS,然后写入 128 kbps AAC。 normalized M4A audio, loudness metrics.
基础层
Standard
预设
audio_trim_silence_aac_128k (type: audio)
发送
音频或带音频的视频
作业执行
删除前导和尾随静音,然后写入 128 kbps AAC。 trimmed M4A audio.
基础层
Premium
预设
audio_loudnorm_trim_aac_128k (type: audio)
发送
音频或带音频的视频
作业执行
修剪边界静默,标准化为 -16 LUFS,然后写入 128 kbps AAC。 trimmed and normalized M4A audio, loudness metrics.
基础层
Premium
预设
audio_whisper_prep (type: audio)
发送
音频或带音频的视频
作业执行
16 kHz 单声道 PCM WAV 为 Whisper、ASR 或其他语音管道准备。 WAV audio.
基础层
Standard

图像衍生品

预设
image_multi_v1 (type: image)
发送
图像或视频
作业执行
使用 fit、fill、cover 或 contain 创建请求的图像。JPG 和 WebP 输出可通过 max_bytes 设置经验证的严格上限,并生成 image_size_limits.json。层级取决于格式、大小、数量、智能裁剪和背景去除。 image renditions, image_size_limits.json when max_bytes is used, smart_crop.json when enabled.
基础层
Standard
预设
image_animated_webp_v1 (type: image)
发送
视频
作业执行
从视频创建有边界的动画 WebP,可配置宽度、帧率、开始时间、时长、质量和循环次数。 animated WebP.
基础层
Premium
预设
image_animated_apng_v1 (type: image)
发送
视频
作业执行
从视频创建无损动画 PNG,可配置宽度、帧率、开始时间、时长和循环次数。 animated PNG.
基础层
Premium
预设
image_placeholders_v1 (type: image)
发送
图像或视频
作业执行
从图像或视频帧生成标准兼容的 BlurHash、ThumbHash、源与占位尺寸、支持透明度的主色,以及有字节上限的 WebP LQIP。 placeholders.json, lqip.webp.
基础层
Standard

分析与报告

预设
compatibility_report_v1 (type: image)
发送
视频
作业执行
根据五个版本化的 Web、移动端、社交上传和编辑配置评估视频,并提供逐条规则证据和修正 preset。 compatibility_report.json.
基础层
Standard
预设
media_report_v1 (type: image)
发送
音频、图像或视频
作业执行
无需转码即可检查音频、视频或图像元数据,并写入容器和流详情,以及存在时的 GOP、EXIF 和 GPS 数据。 media_report.json.
基础层
Standard
预设
code_detect_v1 (type: frames)
发送
图像或视频
作业执行
在有限的开头窗口中扫描图像、视频、动画和音频内嵌封面中的二维码与条形码;检测到代码时生成 codes.json 和证据帧。 codes.json, evidence frames when codes are found.
基础层
Standard
流复制兼容性
当源流与 MP4、HLS 或 DASH 兼容时,transmux_*_fast presets 可避免改变质量的编码。如果复制失败且启用了回退,引擎会使用相应的编码 preset。
等级可以随着覆盖而上升
该表显示 Workspace 的基础层级。额外的图像输出、WebP/AVIF、大型图像集、智能裁剪、背景移除、水印、内容审核、高级字幕或 GIF 预览可能需要 Premium。
格式转换

使用一个来源。生成您的产品所需的格式和边车工件。

源扩展不选择输出。 类型 和 预设 选择可执行配方,因此上传的视频可以在同一异步作业中成为播放视频、纯音频媒体、脚本、GIF 预览、海报或帧序列。

来源
JPG、PNG 或 WebP
可交付成果
JPG、PNG、WebP 或 AVIF 衍生物
食谱
图像 + image_multi_v1;选择 images[].format、尺寸、mode 和 quality。JPG/WebP 可通过 max_bytes 和 min_quality 设置经验证的严格上限。
来源
视频
可交付成果
Web MP4、HLS、社交视频或编辑大师
食谱
选择匹配的 mp4、hls 或社交 预设。
来源
视频
可交付成果
动画 GIF、海报或 JPG 帧序列
食谱
使用 gif_hq、poster_frame_v1、extract_frames_1/5 或将 gif_preview 连接到视频输出。
来源
视频或音频
可交付成果
M4A、MP3、Opus 或语音 WAV
食谱
选择对应的audio_* 预设;视频 输入 已提取其音频流。
来源
视频或音频演讲
可交付成果
SRT、WebVTT 或两者
食谱
将字幕添加到音频或视频输出并选择 srt、vtt 或两者。
JSON
PNG → JPG + WebP
{
  "source": "https://cdn.example.com/media/product-photo.png",
  "metadata": {
    "media_type": "image",
    "asset_id": "product-photo-0426"
  },
  "outputs": [{
    "type": "image",
    "preset": "image_multi_v1",
    "path_suffix": "converted",
    "images": [
      { "width": 1600, "height": 1200, "mode": "fit", "format": "jpg", "quality": 88 },
      { "width": 1600, "height": 1200, "mode": "fit", "format": "webp", "quality": 82 }
    ]
  }]
}
JSON
一个视频 → MP4 + MP3
{
  "source": "https://cdn.example.com/media/interview.mov",
  "outputs": [
    { "type": "mp4", "preset": "mp4_720p_h264_aac", "path_suffix": "web-video" },
    { "type": "audio", "preset": "audio_mp3_128k", "path_suffix": "audio-only" }
  ]
}
JSON
视频 → M4A + SRT + WebVTT
{
  "source": "https://cdn.example.com/media/interview.mp4",
  "metadata": { "media_type": "video", "asset_id": "interview-0426" },
  "outputs": [{
    "type": "audio",
    "preset": "audio_aac_128k",
    "path_suffix": "audio-and-transcript",
    "subtitles": {
      "enabled": true,
      "languages": ["auto"],
      "format": "both",
      "model": "ggml-base.bin",
      "translate_to_english": false
    }
  }]
}
JSON
视频 → MP4 + 海报 + GIF 预览
{
  "source": "https://cdn.example.com/media/trailer.mp4",
  "metadata": { "media_type": "video", "asset_id": "trailer-0426" },
  "outputs": [{
    "type": "mp4",
    "preset": "mp4_720p_h264_aac",
    "path_suffix": "web",
    "poster_time_sec": 4,
    "poster_format": "jpg",
    "gif_preview": {
      "enabled": true,
      "width": 480,
      "fps": 10,
      "start_time": 4,
      "duration": 3
    }
  }]
}
JSON
视频 → HLS 自适应流媒体包
{
  "source": "https://cdn.example.com/media/feature-film.mp4",
  "metadata": { "media_type": "video", "asset_id": "stream-0426" },
  "outputs": [{
    "type": "hls",
    "preset": "hls_ladder_v1",
    "path_suffix": "stream"
  }]
}
JSON
视频 → 独立 GIF + JPG 帧序列
{
  "source": "https://cdn.example.com/media/clip.mp4",
  "metadata": { "media_type": "video", "asset_id": "clip-0426" },
  "outputs": [
    { "type": "gif", "preset": "gif_hq", "path_suffix": "animated-preview" },
    { "type": "frames", "preset": "extract_frames_1", "path_suffix": "sampled-frames" }
  ]
}
HLS 是一个包,而不是一个视频文件
hls_ladder_v1 创建主播放列表、1080p 和 720p H.264/AAC 变体播放列表以及 6 秒媒体片段。使用报告的主播放列表 URL,或将整个捆绑包一起移动。
专用 GIF 与附加预览
gif_hq 创建完整的 480px、15 fps 主 GIF。 gif_preview 将更短、明确定时的 GIF 添加到另一个视频输出。帧预设以每秒一帧或五帧的速度返回编号为 JPG 的序列。
每个工件都与工作相关
阅读已完成作业的输出清单或使用其品牌捆绑包 URL。音频、文字记录、海报、预览和播放文件均包含在内,无需再次上传源。不要构造文件名或存储路径。
估计完整的输出集
MediaRuntime 在执行之前估计每个请求的输出和功能。 GIF 预览、WebP/AVIF 衍生品、高级字幕和多输出作业可能需要 Premium; API 并没有默默地忽略它们。

有用的开关

audio_aac_128k 返回 M4A,audio_mp3_128k 返回 MP3,audio_opus_96k 返回 Opus,audio_whisper_prep 返回 16 kHz 单声道 WAV。将 subtitles.format 设置为 srt、vtt 或 both。仅针对一张海报图像,发送 type: mp4 以及 preset: poster_frame_v1 和所需的 poster_time_sec。

视频剪辑

分析、审阅并生成片段

用 video_clip_v1 指定精确区间,或先用 clip_candidates_v1 推荐片段。两者都使用标准异步任务 API。

手动剪辑不需要模型

video_clip_v1 使用 type: mp4 和 Standard 处理。起点必须为有限值且 ≥ 0,时长 0.1–300 秒,整个区间必须在源文件内。original 保持宽高比,长边最大 1920 px、最高 30 fps;vertical_blur 为 720 × 1280、最高 30 fps。渲染(包括烧录提供的字幕)不会调用 Whisper。

JSON
手动渲染请求
{
  "source": "https://cdn.example.com/interview.mp4",
  "outputs": [{
    "type": "mp4",
    "preset": "video_clip_v1",
    "clip": {
      "start_time_sec": 0,
      "duration_sec": 30,
      "layout": "original",
      "burn_captions": false
    }
  }]
}

可选的候选片段分析

clip_candidates_v1 使用 type: frames 和 Premium,即使提供文本也一样。clip_analysis.transcript 缺失或为空时运行现有 Whisper;非空转录会跳过它。上传文本是可选的。最小/最大时长为 1–300 秒,max_candidates 为 1–20。最小时长不能超过最大值或源文件的精确时长。每个任务仅允许一个分析输出,分析源最长六小时。分数表示语音边界和关键词匹配,不预测传播热度。

JSON
候选分析请求
{
  "source": "https://cdn.example.com/interview.mp4",
  "outputs": [{
    "type": "frames",
    "preset": "clip_candidates_v1",
    "clip_analysis": {
      "min_duration_sec": 15,
      "max_duration_sec": 60,
      "max_candidates": 5,
      "keywords": ["deployment"]
    }
  }]
}

渲染前先审阅

COMPLETED 后,GET /v1/jobs/{job_id}/clip-candidates 返回转录和可编辑的候选区间。分析生成 clip_candidates.json,而不是视频或 JavaScript。用相同源文件将选定区间提交为新的 video_clip_v1 任务。candidates 为空是有效结果:empty_reason 可以是 no_speech、no_keyword_match、no_matching_ranges 或 source_too_short(为报告读取器保留)。有候选时为 null,旧报告可能没有此字段。即使没有建议,也能复用非空转录。

附加并烧录源时间轴字幕

REST/Python 的 clip.transcript 使用 {start_time_sec, end_time_sec, text};Node SDK 使用 {startTimeSec, endTimeSec, text}。请提供片段数组,而不是文件 URL。保留完整源文件的时间戳,引擎会裁剪并转换到片段时间轴。burn_captions: true 要求文本与片段重叠。Studio 支持本地或云端 SRT、VTT、JSON(≤ 1 MiB);下拉选择后立即附加。有效且重叠的转录会启用复选框。匿名 Sandbox 支持本地转录,云端读取需登录。分析的转录附件位于可选的复用现有转录控件中。ZIP 包含 MP4、海报和重叠的 SRT/VTT。

JSON
使用提供的字幕渲染
{
  "source": "https://cdn.example.com/interview.mp4",
  "outputs": [{
    "type": "mp4",
    "preset": "video_clip_v1",
    "clip": {
      "start_time_sec": 20,
      "duration_sec": 15,
      "layout": "vertical_blur",
      "burn_captions": true,
      "transcript": [
        {"start_time_sec": 20, "end_time_sec": 35, "text": "Example speech."}
      ]
    }
  }]
}

限制与可用范围

转录:最多 2,000 段,每段最多 2,000 UTF-8 字节,文本总量 ≤ 256 KiB;起点有限且有序,终点 > 起点,均在源文件内。关键词最多 20 个,每个 ≤ 100 UTF-8 字节。合并剪辑参数 ≤ 512 KiB。渲染拒绝独立 subtitles、watermark 及不相关覆盖项。最终处理层级以获准的估算为准。公开 Sandbox 只允许配置的示例和 Standard;Premium 分析需要符合条件的 Workspace。

SDK 和 CLI 1.4.0 发布准备

这些示例需要对应的 1.4.0 包发布并安装后使用,目前尚待发布。Node 提供 jobs.getClipCandidates() 和 emptyReason;Python 提供 jobs.get_clip_candidates() 和 empty_reason。CLI 通过 --clip-transcript 接受本地 SRT、VTT、JSON(≤ 1 MiB)。不带此参数或 --clip-captions 的手动剪辑不需要转录。

Bash
CLI:分析、审阅、渲染
# Automatic transcription and candidate suggestions (Premium).
mediaruntime run ./interview.mp4 --preset clip_candidates_v1 \
  --clip-min-duration 15 --clip-max-duration 60 --clip-count 5 \
  --clip-keyword deployment --download ./analysis.zip

# Inspect clip_candidates.json in the downloaded ZIP and choose a range.
# A supplied source-timed transcript burns captions without invoking Whisper.
mediaruntime run ./interview.mp4 --preset video_clip_v1 \
  --clip-start 20 --clip-duration 15 --clip-layout vertical_blur \
  --clip-transcript ./source.srt --clip-captions --download ./clip.zip

# Manual clipping without captions or any transcription model.
mediaruntime run ./interview.mp4 --preset video_clip_v1 \
  --clip-start 0 --clip-duration 10 --download ./manual.zip
Node
Node.js
import { MediaRuntime } from "@mediaruntime/node";

const media = new MediaRuntime({ apiKey: process.env.MEDIARUNTIME_API_KEY });
// Retain this stable source reference with the plan. Do not save an expiring URL.
const source = "https://your-cdn.example/episode.mp4";
const analysis = await media.jobs.create({ source, outputs: [{
  type: "frames", preset: "clip_candidates_v1",
  clipAnalysis: { minDurationSec: 15, maxDurationSec: 60, maxCandidates: 5 },
}] });
const analyzed = await analysis.wait();
if (analyzed.status !== "COMPLETED") throw new Error(`Analysis ${analyzed.status}`);
const plan = await media.jobs.getClipCandidates(analysis.id);
// Present candidates for human review. A score is a heuristic, not predicted engagement.
const selected = plan.candidates[0];
if (!selected) {
  console.log("No suggestions:", plan.emptyReason ?? "No reason in this older report");
  // Stop this automatic render path; plan.transcript remains usable for manual clips.
  process.exit(0);
}

const render = await media.jobs.create({ source, outputs: [{
  type: "mp4", preset: "video_clip_v1", clip: {
    startTimeSec: selected.startTimeSec,
    durationSec: selected.durationSec,
    layout: "vertical_blur", // or original
    burnCaptions: true,
    // Keep SOURCE timestamps. The engine intersects and rebases cues for this render.
    transcript: plan.transcript.filter((segment) =>
      segment.endTimeSec > selected.startTimeSec &&
      segment.startTimeSec < selected.startTimeSec + selected.durationSec),
  },
}] });
const rendered = await render.wait();
if (rendered.status !== "COMPLETED") throw new Error(`Render ${rendered.status}`);
console.log(rendered.bundle.downloadUrl); // Short-lived URL for the complete ZIP.
食谱

从预设开始;仅覆盖重要的内容。

预设使请求保持可读性并为引擎提供稳定的基线。仅当产品需要时才添加显式再现、字幕、预览、编解码器或比特率选项。

video.web → mp4_720p_h264_aac

Web MP4

Standard
Source
Video with a decodable video stream; audio is optional
Artifacts
720p H.264/AAC MP4 and a JPG poster
Node
Web MP4
// Source: Video with a decodable video stream; audio is optional
// Alias: video.web
// Preset: mp4_720p_h264_aac
// Artifacts: 720p H.264/AAC MP4 and a JPG poster
// Tier: Standard
// Testing: use job.wait(); production: persist job.id and consume the signed webhook
// npm install @mediaruntime/node
import { MediaRuntime } from "@mediaruntime/node";

const media = new MediaRuntime();
const job = await media.jobs.create({
  "source": "https://cdn.example.com/media/source.mov",
  "metadata": {
    "asset_id": "asset_0426",
    "recipe": "web-mp4"
  },
  "outputs": [
    "video.web"
  ],
  "idempotencyKey": "asset:web-mp4:v1"
});

console.log(job.id, job.status);
video.streaming → hls_ladder_v1

HLS streaming

Standard
Source
Video with a decodable video stream; audio is optional
Artifacts
Master playlist, 1080p/720p variants, and six-second media segments
Node
HLS streaming
// Source: Video with a decodable video stream; audio is optional
// Alias: video.streaming
// Preset: hls_ladder_v1
// Artifacts: Master playlist, 1080p/720p variants, and six-second media segments
// Tier: Standard
// Testing: use job.wait(); production: persist job.id and consume the signed webhook
// npm install @mediaruntime/node
import { MediaRuntime } from "@mediaruntime/node";

const media = new MediaRuntime();
const job = await media.jobs.create({
  "source": "https://cdn.example.com/media/feature.mp4",
  "metadata": {
    "asset_id": "asset_0426",
    "recipe": "hls-streaming"
  },
  "outputs": [
    "video.streaming"
  ],
  "idempotencyKey": "asset:hls:v1"
});

console.log(job.id, job.status);
video.social → social_vertical_blur

Vertical social video

Premium
Source
Landscape, square, or portrait video
Artifacts
1080×1920 H.264/AAC MP4 with a blurred 9:16 fill
Node
Vertical social video
// Source: Landscape, square, or portrait video
// Alias: video.social
// Preset: social_vertical_blur
// Artifacts: 1080×1920 H.264/AAC MP4 with a blurred 9:16 fill
// Tier: Premium
// Testing: use job.wait(); production: persist job.id and consume the signed webhook
// npm install @mediaruntime/node
import { MediaRuntime } from "@mediaruntime/node";

const media = new MediaRuntime();
const job = await media.jobs.create({
  "source": "https://cdn.example.com/media/interview.mp4",
  "metadata": {
    "asset_id": "asset_0426",
    "recipe": "vertical-social"
  },
  "outputs": [
    "video.social"
  ],
  "idempotencyKey": "asset:social:v1"
});

console.log(job.id, job.status);
image.web → image_multi_v1

Responsive image derivatives

Premium
Source
JPG, PNG, WebP, or another supported still image
Artifacts
1200×630 and 320×320 metadata-stripped WebP renditions
Node
Responsive image derivatives
// Source: JPG, PNG, WebP, or another supported still image
// Alias: image.web
// Preset: image_multi_v1
// Artifacts: 1200×630 and 320×320 metadata-stripped WebP renditions
// Tier: Premium
// Testing: use job.wait(); production: persist job.id and consume the signed webhook
// npm install @mediaruntime/node
import { MediaRuntime } from "@mediaruntime/node";

const media = new MediaRuntime();
const job = await media.jobs.create({
  "source": "https://cdn.example.com/media/product.png",
  "metadata": {
    "asset_id": "asset_0426",
    "recipe": "image-derivatives"
  },
  "outputs": [
    "image.web"
  ],
  "idempotencyKey": "asset:image-derivatives:v1"
});

console.log(job.id, job.status);
audio.transcription → audio_aac_128k

Audio plus transcript

Standard
Source
Audio, or video containing a decodable audio stream
Artifacts
128 kbps AAC/M4A plus SRT and WebVTT transcripts
Node
Audio plus transcript
// Source: Audio, or video containing a decodable audio stream
// Alias: audio.transcription
// Preset: audio_aac_128k
// Artifacts: 128 kbps AAC/M4A plus SRT and WebVTT transcripts
// Tier: Standard
// Testing: use job.wait(); production: persist job.id and consume the signed webhook
// npm install @mediaruntime/node
import { MediaRuntime } from "@mediaruntime/node";

const media = new MediaRuntime();
const job = await media.jobs.create({
  "source": "https://cdn.example.com/media/interview.mp4",
  "metadata": {
    "asset_id": "asset_0426",
    "recipe": "audio-transcript"
  },
  "outputs": [
    "audio.transcription"
  ],
  "idempotencyKey": "asset:audio-transcript:v1"
});

console.log(job.id, job.status);
video.web → mp4_720p_h264_aac

Moderation plus watermarking

Premium
Source
One image or video; this example uses video
Artifacts
Watermarked 720p MP4, JPG poster, and moderation evidence report
Node
Moderation plus watermarking
// Source: One image or video; this example uses video
// Alias: video.web
// Preset: mp4_720p_h264_aac
// Artifacts: Watermarked 720p MP4, JPG poster, and moderation evidence report
// Tier: Premium
// Testing: use job.wait(); production: persist job.id and consume the signed webhook
// npm install @mediaruntime/node
import { MediaRuntime } from "@mediaruntime/node";

const media = new MediaRuntime();
const job = await media.jobs.create({
  "source": "https://cdn.example.com/media/upload.mp4",
  "metadata": {
    "asset_id": "asset_0426",
    "recipe": "moderation-watermark"
  },
  "moderation": {
    "enabled": true,
    "mode": "report",
    "checks": [
      "sexual",
      "violence",
      "dangerous"
    ]
  },
  "watermark": {
    "enabled": true
  },
  "outputs": [
    "video.web"
  ],
  "idempotencyKey": "asset:moderation-watermark:v1"
});

console.log(job.id, job.status);
Premium 功能路由
审核、水印、高级编解码器、多个 输出、GIF 预览以及某些字幕功能可能需要 Premium。 API 拒绝您的帐户无法运行的工作,而不是默默地删除功能。
水印设置
从帐户页面上传并确认一个帐户 PNG。然后只发送{ "watermark": { "enabled": true } }; MediaRuntime 解析服务器拥有的徽标。
可复用的账户策略

对完整处理策略进行版本管理,而不是复制请求 JSON。

托管配方是账户范围内不可变的 outputs、moderation 和 watermark 策略版本。使用名称选择最新有效版本;部署必须固定时使用 `name@version`。

Bash
发现并提交托管配方
# Discover the built-in and account recipes available to this key.
mediaruntime recipes list

# A hosted recipe may be pinned to one immutable version.
mediaruntime run ./launch.mp4 \
  --recipe team-video@3 \
  --download ./launch.zip

# The raw API accepts the same reference.
curl -sS -X POST "https://mediaruntime.com/v1/jobs" \
  -H "X-API-Key: $MEDIARUNTIME_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "source": "https://cdn.example.com/media/launch.mp4",
    "recipe": "web-video@1",
    "metadata": { "asset_id": "launch-01" }
  }'
在计费和执行前解析
网关会在验证、估算、余额预留、幂等和调度前具体化准确版本。提交响应、轮询和终态 webhook 都包含相同的 recipe 确认信息和 SHA-256。
团队安全管理
所有者和管理员通过乐观锁创建不可变版本。归档会阻止新任务选择,同时保留现有任务和固定历史。内置配方为 web-video@1、social-video@1 和 ai-transcription@1。
适度

在工作中添加分层视觉安全分析。

审核对一幅图像或视频使用分层管道。report 模式返回证据并继续处理。block 模式是引擎运行前的 fail-closed 门控:block 或 review 判定会拒绝作业,只有 allow 会继续。

JSON
请求所有视觉 检查
{
  "source": "https://cdn.example.com/upload.mp4",
  "metadata": { "media_type": "video", "asset_id": "asset_0426" },
  "moderation": {
    "enabled": true,
    "mode": "report",
    "checks": ["sexual", "violence", "dangerous"]
  },
  "outputs": [{
    "type": "mp4",
    "preset": "mp4_720p_h264_aac"
  }]
}
JSON
已完成作业和 Webhook 的结果
{
  "moderation": {
    "requested": {
      "enabled": true,
      "mode": "report",
      "checks": ["sexual", "violence", "dangerous"],
      "media_type": "video",
      "phase": "phase1_video_report"
    },
    "result": {
      "ok": true,
      "media_type": "video",
      "verdict": "review",
      "flagged_checks": ["violence"],
      "scores": {
        "violence": { "yes": 0.82, "no": 0.18 }
      },
      "decisions": {
        "violence": { "decision": "review", "raw_decision": "review" }
      },
      "evidence": {
        "frames_sampled": 8,
        "frames_flagged": [{
          "frame_index": 3,
          "timestamp_sec": 20,
          "verdict": "review",
          "flagged_checks": ["violence"]
        }]
      },
      "video": {
        "frame_interval_sec": 10,
        "max_frames": 24
      }
    }
  },
  "meta": {
    "moderation_result": {
      "url": "https://storage.googleapis.com/.../moderation_result.json"
    }
  },
  "usage": {
    "breakdown": { "moderation_units": 120 }
  }
}
合同
计划
价值
Premium
注释
API 返回 403,除非帐户是 Premium 或允许自动升级。
合同
模式
价值
report 或 block
注释
report 仅用于观察;block 会在引擎启动前拒绝 block/review 判定。
合同
支票
价值
性、暴力、危险
注释
发送一到三个检查。省略 检查 将选择所有三个。
合同
输入
价值
一张图片或视频
注释
不支持纯音频输入、批次以及 Sandbox 内容审核。
合同
视频采样
价值
固定间隔、有界帧
注释
服务选择间隔和上限;从 result.video 和 result.evidence 读取实际值。
合同
决定
价值
允许、审查或阻止信号
注释
report 不会阻止执行。block 为 fail-closed:allow 继续;review 或 block 以 REJECTED 结束。
合同
神器
价值
元/moderation_result.json
注释
包含在输出 ZIP 中,并在可用时通过 meta.moderation_result.url 公开。
合同
计费
价值
每个分析帧
注释
每帧一次推理:图像为 1 帧,视频采样上限为 24。由 result.evidence.frames_sampled 和 use.breakdown.moderation_units 结算。
合同
独立式
价值
输出 可能为空
注释
发送 `outputs: []` 可仅审核文件而不进行转码。此时只对内容审核计费。
选择观察型或强制型审核
当应用自行决定是否发布时使用 report。需要在转码前拒绝时使用 block;被拒绝的作业没有输出 bundle,只结算审核单位。
模型可能是错误的
分数是分类器 输出,而不是事实。保留证据,确定下游阈值,在适当的情况下提供上诉路径,并避免完全自动化的高影响力决策。
网络钩子

在信任事件之前验证原始字节。

终端事件至少发送一次,并且不保证订购。验证 HMAC-SHA256、拒绝过时的时间戳、删除重复的 event_id、快速确认并将繁重的工作移至队列。

JSON
COMPLETED事件
{
  "event_id": "webhook_evt_job_1320c28b72104811b075a26a99496cf6",
  "job_id": "job_1320c28b72104811b075a26a99496cf6",
  "account_id": "acc_xxx",
  "status": "COMPLETED",
  "completedAt": "2026-08-09T02:41:23Z",
  "billing": { "status": "PAID", "estimatedUnits": 31 },
  "usage": { "units_total": 31, "breakdown": {} },
  "delivery": {
    "mode": "PULL",
    "retentionDays": 7,
    "expiresAt": "2026-08-16T02:41:23Z",
    "bundle": {
      "type": "zip",
      "filename": "outputs.zip",
      "download": {
        "url": "https://mediaruntime.com/v1/jobs/job_1320c28b72104811b075a26a99496cf6/bundle?token=...",
        "expiresAt": "2026-08-16T02:41:23Z"
      }
    }
  },
  "meta": {
    "engine_result_url": "https://storage.googleapis.com/...",
    "outputs_root_gs": "gs://.../jobs/acc_xxx/job_.../outputs",
    "request_metadata": {
      "producer": "my-api",
      "entity_id": "video_01J8Y4",
      "media_type": "video"
    }
  }
}
输出住哪里
从 delivery.bundle.download.url 下载完整的 ZIP,或获取 meta.engine_result_url 以枚举各个输出和工件路径。
Node
快速原始身体验证
import express from "express";
import { MediaRuntime } from "@mediaruntime/node";

const media = new MediaRuntime();
const app = express();

// Register this route before any express.json() middleware.
app.post(
  "/webhooks/mediaruntime",
  express.raw({ type: "application/json" }),
  media.webhooks.express(async (event, _req, res) => {
    // Persist and deduplicate event.id before acknowledging.
    console.log(event.id, event.jobId, event.status);
    res.sendStatus(204);
  }),
);
在账户中配置端点
打开帐户 → Webhooks,输入您的 HTTPS 端点,并在显示签名密钥时存储它。公共 API 集成仅需要您的 API 密钥和 Webhook 签名密钥。

发货规则

  • 仅在签名验证和持久排队/重复数据删除后返回任何 2xx。
  • 将 event_id 视为幂等键。
  • 使用meta.request_metadata 无需第二个查找表即可查找您的实体。
  • 下载保留前的输出.expiresAt。
  • FAILED 或 REJECTED 事件包含 error.code/message,且没有可用的 bundle。PARTIAL 批处理的 error.code 为 BATCH_PARTIAL;请检查 delivery.items 中每个子任务的状态及成功的 bundle。
跟踪职位

当 webhook 不实用时进行轮询。

提交立即返回,并带有 job_id。 Webhooks 仍然是了解已完成工作的最低延迟方式,但轮询可用于本地开发、没有公共端点的环境、协调和支持问题。

cURL
找一份工作
curl -sS "https://mediaruntime.com/v1/jobs/$JOB_ID" \
  -H "X-API-Key: $MEDIARUNTIME_API_KEY"
cURL
列出您的职位
# Newest first. Filter by status and page with the cursor.
curl -sS "https://mediaruntime.com/v1/jobs?status=COMPLETED&limit=25" \
  -H "X-API-Key: $MEDIARUNTIME_API_KEY"

# Next page: pass the previous response's next_cursor
curl -sS "https://mediaruntime.com/v1/jobs?limit=25&cursor=$NEXT_CURSOR" \
  -H "X-API-Key: $MEDIARUNTIME_API_KEY"
JSON
响应字段
{
  "job_id": "job_2ee8db582cdf4a2fafb49d52218b3159",
  "status": "COMPLETED",
  "tier": {
    "requested": "premium",
    "required": "standard",
    "effective": "premium",
    "billed": "standard",
    "reasons": []
  },
  "usage": { "units_total": 4 },
  "billing": {
    "status": "PAID",
    "currency": "USD",
    "unit_price_cents": 1,
    "final_units": 4,
    "final_amount_cents": 4
  },
  "bundle": {
    "available": true,
    "download_url": "https://mediaruntime.com/v1/jobs/job_2ee8.../bundle?token=...",
    "expires_at": "2026-08-18T03:14:27Z",
    "size_bytes": 13056793,
    "retention_days": 7
  },
  "media": {
    "format": "mov,mp4,m4a,3gp,3g2,mj2",
    "duration_sec": 61.5,
    "bit_rate": 8000000,
    "video": {
      "codec": "h264",
      "profile": "High",
      "width": 1080,
      "height": 1920,
      "encoded_width": 1920,
      "encoded_height": 1080,
      "fps": 29.97,
      "rotation_deg": 90,
      "is_rotated": true,
      "orientation": "portrait"
    },
    "audio": { "codec": "aac", "sample_rate_hz": 48000, "channels": 2, "layout": "stereo" },
    "streams": { "video": 1, "audio": 1, "other": 0 }
  },
  "metadata": { "asset_id": "asset_0426", "media_type": "video" },
  "error": null,
  "completed_at": "2026-08-11T03:14:53Z"
}
读取层块
requested 是提交作业的 API 密钥的层。 required是工作实际需要的,effective是它运行的车道,billed是你被收费的。运行标准工作的高级钥匙显示 requested: premium 和 billed: standard — 您需要支付工作费用,而不是钥匙费用。
读取媒体块
media 报告 MediaRuntime 在提交时探测输入时在您的输入中发现的内容 — 与决定是否接受作业的探测相同。当作业因不兼容的配对而被拒绝时,这解释了原因:发送到图像输出的 MP3 显示 streams.video: 0,而发送到帧输出的静态图像没有 duration_sec。注意 video.width/height 是应用了旋转的显示尺寸,因此纵向手机夹的读数为 1080x1920,即使 encoded_width/encoded_height 为 1920x1080。每个字段都是可选的:缺少一个字段意味着探测器没有报告它,永远不会为零。
获取内容审核判定
GET /v1/jobs/{job_id}/moderation 只返回判定,因此轮询决策的客户端无需每次获取计费和 bundle 详情。响应包含 verdict、每项检查的 decision 与 confidence,以及升级的 likelihoods。标记为 review_only 的检查仅供参考:它可以产生 review 判定,但不能单独阻止内容。当作业存在但从未请求内容审核时,端点返回 **404**;空的成功响应会与“已审核但未发现问题”无法区分。每项决策的阈值不公开。
获取媒体报道
GET /v1/jobs/{job_id}/media-report 返回 media_report_v1 文档,而不下载捆绑包。 report 内联携带;异常大的报告不会内联存储,然后响应将 report 设置为 null,而 download_url 仍然可以解析,因此请处理两者。当作业没有报告时返回404。
获取兼容性报告
GET /v1/jobs/{job_id}/compatibility-report 无需下载 ZIP 即可返回版本化的 compatibility_report_v1 文档。它包含五个保守配置、逐条规则证据,以及不兼容时可使用的现有修正 preset。这是可执行的指导,而不是详尽的设备认证。请同时处理 report 和 download_url;未请求该 preset 时返回 404。
获取二维码和条形码检测结果
GET /v1/jobs/{job_id}/codes 无需下载 ZIP 即可返回有限的 code_detect_v1 扫描结果。支持图像、视频、动画以及带内嵌封面的音频;纯音频会返回清晰的纠正提示。扫描最多保留 12 个采样帧,并且每帧最多保留 16 个唯一代码。请将每个 decoded_text 视为不可信文本:不要渲染为 HTML,也不要自动打开解码出的 URL。证据帧通过 ZIP 中的 bundle 路径引用。
领域
状态
类型
字符串
注释
QUEUED、PROCESSING、COMPLETED、FAILED、REJECTED,或仅用于批处理的 PARTIAL。
领域
层
类型
对象
注释
请求/必需/有效/计费,以及需要保费的原因。
领域
用法.units_total
类型
整数
注释
工作的计费单位。
领域
计费
类型
对象
注释
货币、单价以及预计与最终单位和金额。
领域
捆绑包.download_url
类型
字符串
注释
作业范围内、即将到期的捆绑包 URL。仅限单一作业端点。
领域
媒体
类型
对象
注释
输入的实际内容是什么,如提交时所探测的那样。旧作业上为空。
领域
媒体.视频.宽度/高度
类型
整数
注释
显示尺寸,已应用旋转。
领域
媒体.duration_sec
类型
数量
注释
没有静态图像,没有时间线。
领域
metadata
类型
对象
注释
您提交的 元数据 对象已回显。
领域
错误
类型
字符串
注释
在 FAILED、REJECTED 或仅用于批处理的 PARTIAL 状态下填充;其他情况为 null。

投票规则

  • 更喜欢 webhook;仅当您无法收到邮件时才进行轮询。
  • 带有 next_cursor 的页面,从不存在偏移量 — 行随着作业更新而移动。
  • 您不拥有的职位 ID 返回 404,与不存在的职位 ID 相同。
  • 列表行省略捆绑包 URL;获取要下载的单个作业。
  • 在民意调查之间退后一步。终端状态不会改变。
计费和定价

预付费、随用随付、按实际使用情况结算。

添加卡、为钱包充值并提交工作,无需定期订阅。 MediaRuntime 在执行之前保留估计值,并在作业达到最终状态时结算最终费用。

计划
Standard Pay-As-You-Go
起始使用价
来自$0.02
最低充值金额
$5.00
默认自动充值
$5.00 在 $2.00 可用
计划
Premium Pay-As-You-Go
起始使用价
来自$0.05
最低充值金额
$20.00
默认自动充值
$20.00 在 $5.00 可用
预订和结算如何运作
提交保留估计费用加上 15% 安全缓冲。完成对实际计费使用量进行收费并释放未使用的预留。只有在签名的支付 webhook 确认后,待处理的 Stripe 充值才会成为钱包积分。
如何衡量使用情况
视频和音频先按媒体时长计算,再反映所请求的输出和处理。图像使用处理单元,每个作业有最低计费单元;输入字节不按 MB 收费。多个输出以及高级编解码器、字幕、GIF、内容审核和水印等功能可能增加单元或需要 Premium。请使用作业估算进行规划,并使用终态的 billing 和 usage 字段进行对账。

钱包规则

  • 可用信用等于钱包信用减去为运行作业预留的资金。
  • 可用信用不足,执行前返回 HTTP 402。
  • 自动充值是可选的,并且需要存档卡。
  • 当不允许升级时,仅 Premium 请求将返回 403。
使用帐户的账单快照
该表显示了公开的美元起始价格,而不是每个工作的统一价格。协商量帐户可以进行特定于帐户的定价。不要仅根据持续时间得出最终费用;保留为作业返回的估算和终端账单快照。
错误和重试

重试传输失败,而不是无效工作。

每个响应都包含 X-Request-Id。错误会添加规范化的 error 对象,同时保留 detail/message 以兼容旧客户端。请记录请求 ID、代码和状态,但绝不要记录 API 密钥、签名 URL 或请求正文。

状态
400
代码
invalid_request
含义
该请求在逻辑上无效或估算器拒绝了它。
您的集成应该做什么
修复请求;不要重试不变。
状态
401
代码
authentication_error
含义
API 密钥无效、过期或已撤销。
您的集成应该做什么
纠正或轮换钥匙;不要盲目重试。
状态
402
代码
billing_required
含义
帐户、钱包或计费预检无法涵盖该作业。
您的集成应该做什么
首先为钱包充值或解决计费问题。
状态
403
代码
permission_denied
含义
计划、角色或功能门不允许该请求。
您的集成应该做什么
改变计划/要求;不要重试不变。
状态
404
代码
not_found
含义
资源不存在,或因所有者范围而不可见。
您的集成应该做什么
更正标识符;不要原样重试。
状态
409
代码
idempotency_in_progress / conflict
含义
使用此密钥的操作仍在进行,或与另一个活动操作冲突。
您的集成应该做什么
仅在 error.retryable 为 true 时重试。
状态
410
代码
gone
含义
短期令牌已过期。
您的集成应该做什么
获取新的结果或令牌。
状态
413
代码
request_too_large
含义
HTTP 请求正文超过 2 MiB。
您的集成应该做什么
单独上传媒体并仅发送 URL。
状态
422
代码
validation_error / idempotency_conflict / unprocessable_entity
含义
验证失败,或幂等密钥与不同的请求正文重复使用。
您的集成应该做什么
更正指定的字段或密钥。
状态
429
代码
rate_limited
含义
帐户或密钥受到速率限制。
您的集成应该做什么
使用指数退避和抖动重试。
状态
500
代码
internal_error
含义
网关发生意外故障。
您的集成应该做什么
使用退避策略安全重试。
状态
502
代码
upstream_error
含义
暂时的平台依赖项发生故障。
您的集成应该做什么
使用退避策略安全重试。
状态
503
代码
service_unavailable
含义
依赖项或执行通道不可用。
您的集成应该做什么
使用退避策略安全重试。
JSON
典型错误体
{
  "error": {
    "code": "billing_required",
    "message": "Insufficient wallet balance for this job",
    "status": 402,
    "retryable": false,
    "request_id": "req_7fa01eec9b6248a5a7be2d60ff4bb978",
    "details": null
  },
  "request_id": "req_7fa01eec9b6248a5a7be2d60ff4bb978",
  "detail": "Insufficient wallet balance for this job"
}
安全重试政策
请使用 error.retryable,而不要自行根据状态码分类。重试作业提交时仍须使用原始 Idempotency-Key:丢失的响应可能掩盖了已接受的付费作业。如果已有跟踪 ID,请发送格式受限的 X-Request-Id;否则记录响应中生成的值,以便支持团队关联排查。
API参考

大多数集成所需的小表面。

以下所有服务器到服务器端点均使用 X-API-Key。标记化捆绑包 URL 是唯一的例外,因为它带有自己的短期、工作范围的凭证。

方法
后处理
路径
/v1/upload-url
目的
当您还没有可获取的媒体 URL 时,可以选择创建 15 分钟的上传目标。
方法
后处理
路径
/v1/jobs
目的
对单输入或批量媒体作业进行排队。
方法
获取
路径
/v1/jobs/{job_id}
目的
一项作业的状态、层决策、使用情况、计费和捆绑链接。
方法
获取
路径
/v1/jobs
目的
列出您的职位,最新的在前。支持 ?status= 和光标分页。
方法
获取
路径
/v1/jobs/{job_id}/moderation
目的
获取单个作业的内容审核判定。未请求内容审核时返回 404。
方法
GET
路径
/v1/jobs/{job_id}/clip-candidates
目的
渲染前先审阅
方法
获取
路径
/v1/jobs/{job_id}/media-report
目的
法医媒体报道了一份工作。 404 当未请求 media_report_v1 时。
方法
获取
路径
/v1/jobs/{job_id}/compatibility-report
目的
单个作业的版本化兼容性判定。未请求 compatibility_report_v1 时返回 404。
方法
获取
路径
/v1/jobs/{job_id}/codes
目的
有限的二维码和条形码检测及证据引用。未请求 code_detect_v1 时返回 404。
方法
获取
路径
/v1/jobs/{job_id}/bundle?token=...
目的
将工作范围的代币兑换为捆绑包;不需要 API 密钥。
方法
后处理
路径
/v1/jobs/{job_id}/retry-webhook
目的
重试您拥有的作业的终端 Webhook。
方法
后处理
路径
/v1/account/watermark-logo/upload-url
目的
为帐户 PNG 徽标创建上传目标。
方法
后处理
路径
/v1/account/watermark-logo/confirm
目的
确认徽标及其位置设置。
机器可读契约

使用版本化的 OpenAPI 3.1 文档生成客户端、验证请求并审查契约。它仅包含受支持的公开 API,且无需 API 密钥。

查看 OpenAPI JSON