{
  "name": "subtitle-extract",
  "summary": "Extracts a text subtitle track from a media container (MKV, MP4, WebM) as SubRip or WebVTT.",
  "rationale": "Demuxing a caption stream out of a container needs ffmpeg AND a hardened fetch: an agent that pulls the URL itself walks past every SSRF control, and carrying an ffmpeg per call is not something an agent does inline.",
  "family": "av",
  "price_usd": "0.003",
  "free": false,
  "timeout_ms": 60000,
  "max_timeout_seconds": 81,
  "input_schema": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type": "object",
    "properties": {
      "url": {
        "type": "string",
        "maxLength": 2048,
        "format": "uri",
        "description": "Absolute http(s) URL of a media container that can carry subtitles (MKV/WebM, MP4/MOV, AVI or Ogg), at most 2048 characters."
      },
      "stream": {
        "default": 0,
        "description": "Zero-based index counted among the subtitle streams only (0 to 63, default 0); a missing stream fails with no_subtitle_stream.",
        "type": "integer",
        "minimum": 0,
        "maximum": 63
      },
      "to": {
        "default": "srt",
        "description": "Format of the returned captions, srt (default) or vtt, written by ffmpeg.",
        "type": "string",
        "enum": [
          "srt",
          "vtt"
        ]
      }
    },
    "required": [
      "url"
    ],
    "additionalProperties": false
  },
  "input_example": {
    "url": "https://grist.tools/samples/av/subtitle-movie.mkv",
    "stream": 0,
    "to": "srt"
  },
  "output_example": {
    "source_url": "https://grist.tools/samples/av/subtitle-movie.mkv",
    "bytes": 1486,
    "container": "matroska",
    "stream_index": 0,
    "format": "srt",
    "cue_count": 2,
    "subtitle": "1\n00:00:00,500 --> 00:00:02,000\nThe kettle starts to hum.\n\n2\n00:00:02,500 --> 00:00:04,000\nSteam rises from the spout.\n\n"
  },
  "errors": [
    "invalid_input",
    "blocked_target",
    "unreachable_target",
    "upstream_timeout",
    "unsupported_content_type",
    "too_large",
    "unprocessable",
    "internal"
  ]
}