{
  "author": {
    "address": "0xc820da3Ce55C600A6282D2B21083Fe5Aa7E51F3D",
    "name": "tpae",
    "signature": "27f68ec2c07bcd9c49624e8dd711ac25bfda95dab336965409cf91cc7bd48db50557742740b0c71c65c040aa4ecb0d3869569d548d623cb194600755d080114c1c"
  },
  "available_to_orchestrator": true,
  "changelog": "Built and tested single-URL YouTube downloads with per-run video/audio selection, folder choice, safe URL handling, MP4 merging, and overwrite support.",
  "content_hash": "sha256:70a717b3d59e59d8bfd5652543db60bcf6cbe46e3a80f8ffc0e6dcabf7dbb2b0",
  "created_at": "2026-10-07T19:23:31Z",
  "format": "osaurus.template",
  "format_version": 1,
  "id": "BC20B98D-1B93-4A74-A971-C8F77F56CABB",
  "kind": "workflow",
  "name": "YouTube Downloader",
  "requirements": {
    "dependencies": [
      {
        "binaries": [
          "yt-dlp"
        ],
        "manager": "pip",
        "packages": [
          "yt-dlp"
        ]
      },
      {
        "binaries": [
          "ffmpeg"
        ],
        "manager": "apk",
        "packages": [
          "ffmpeg"
        ]
      }
    ],
    "knowledge": [],
    "mcp_servers": [],
    "models": [],
    "network": [],
    "notes": {},
    "permissions": [],
    "plugins": [],
    "secrets": [],
    "tools": [
      "shell_run",
      "file_copy"
    ]
  },
  "summary": "Download one authorized YouTube video or audio file to a folder you choose.",
  "version": 1,
  "workflow": {
    "dependencies": [
      {
        "binaries": [
          "yt-dlp"
        ],
        "manager": "pip",
        "packages": [
          "yt-dlp"
        ]
      },
      {
        "binaries": [
          "ffmpeg"
        ],
        "manager": "apk",
        "packages": [
          "ffmpeg"
        ]
      }
    ],
    "edges": [
      {
        "from": "prepare",
        "to": "download_video",
        "when": {
          "op": "equals",
          "path": "choice",
          "value": "video"
        }
      },
      {
        "from": "prepare",
        "to": "download_audio",
        "when": {
          "op": "equals",
          "path": "choice",
          "value": "audio"
        }
      },
      {
        "from": "download_video",
        "to": "copy_video"
      },
      {
        "from": "download_audio",
        "to": "copy_audio"
      },
      {
        "from": "copy_video",
        "to": "finish"
      },
      {
        "from": "copy_audio",
        "to": "finish"
      }
    ],
    "examples": [
      {
        "input": {
          "destination_folder": "tmp",
          "download_type": "audio",
          "youtube_url": "https://www.youtube.com/watch?v=jNQXAC9IVRw"
        },
        "name": "Download one YouTube audio file"
      },
      {
        "input": {
          "destination_folder": "tmp",
          "download_type": "video",
          "youtube_url": "https://www.youtube.com/watch?v=jNQXAC9IVRw"
        },
        "name": "Download one YouTube video"
      }
    ],
    "input_schema": {
      "additionalProperties": false,
      "properties": {
        "destination_folder": {
          "description": "Choose where the downloaded file should be saved.",
          "format": "folder",
          "title": "Destination folder",
          "type": "string"
        },
        "download_type": {
          "description": "Choose whether to save video or audio.",
          "enum": [
            "video",
            "audio"
          ],
          "title": "Download type",
          "type": "string"
        },
        "youtube_url": {
          "description": "Paste the URL of one YouTube video.",
          "title": "YouTube link",
          "type": "string"
        }
      },
      "required": [
        "youtube_url",
        "download_type",
        "destination_folder"
      ],
      "type": "object",
      "x-order": [
        "youtube_url",
        "download_type",
        "destination_folder"
      ]
    },
    "model_slots": [],
    "nodes": [
      {
        "code": {
          "network": [],
          "secrets": [],
          "source": "async function run(input, ctx) {\n  const bytes = [];\n  for (const ch of input.url.trim()) {\n    const cp = ch.codePointAt(0);\n    if (cp <= 0x7f) bytes.push(cp);\n    else if (cp <= 0x7ff) bytes.push(0xc0 | (cp >> 6), 0x80 | (cp & 0x3f));\n    else if (cp <= 0xffff) bytes.push(0xe0 | (cp >> 12), 0x80 | ((cp >> 6) & 0x3f), 0x80 | (cp & 0x3f));\n    else bytes.push(0xf0 | (cp >> 18), 0x80 | ((cp >> 12) & 0x3f), 0x80 | ((cp >> 6) & 0x3f), 0x80 | (cp & 0x3f));\n  }\n  const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n  let out = '';\n  for (let i = 0; i < bytes.length; i += 3) {\n    const a = bytes[i];\n    const b = i + 1 < bytes.length ? bytes[i + 1] : 0;\n    const c = i + 2 < bytes.length ? bytes[i + 2] : 0;\n    const n = (a << 16) | (b << 8) | c;\n    out += alphabet[(n >> 18) & 63] + alphabet[(n >> 12) & 63];\n    out += i + 1 < bytes.length ? alphabet[(n >> 6) & 63] : '=';\n    out += i + 2 < bytes.length ? alphabet[n & 63] : '=';\n  }\n  return { choice: input.choice, url_b64: out, overwrite: true };\n}",
          "timeout": 30
        },
        "id": "prepare",
        "input": {
          "choice": "{{input.download_type}}",
          "url": "{{input.youtube_url}}"
        },
        "intent": "Safely encode the URL and select the requested download branch.",
        "kind": "code",
        "name": "Prepare safe download",
        "output_schema": {
          "additionalProperties": false,
          "properties": {
            "choice": {
              "enum": [
                "video",
                "audio"
              ],
              "type": "string"
            },
            "overwrite": {
              "type": "boolean"
            },
            "url_b64": {
              "type": "string"
            }
          },
          "required": [
            "choice",
            "url_b64",
            "overwrite"
          ],
          "type": "object"
        },
        "retry": {
          "backoff_seconds": 1,
          "max_attempts": 1
        },
        "timeout": 120
      },
      {
        "id": "download_video",
        "input": {
          "command": "URL_B64='{{nodes.prepare.output.url_b64}}'; URL=$(printf '%s' \"$URL_B64\" | base64 -d); rm -f youtube-download.mp4 youtube-download.f*; yt-dlp --js-runtimes node --no-playlist --format 'bv*[ext=mp4]+ba[ext=m4a]/bv*+ba/b' --merge-output-format mp4 --output youtube-download.mp4 \"$URL\""
        },
        "intent": "Download the best directly available MP4 video with audio.",
        "kind": "tool",
        "name": "Download video",
        "output_schema": {},
        "retry": {
          "backoff_seconds": 2,
          "max_attempts": 2
        },
        "timeout": 300,
        "tool": {
          "name": "shell_run"
        }
      },
      {
        "id": "download_audio",
        "input": {
          "command": "URL_B64='{{nodes.prepare.output.url_b64}}'; URL=$(printf '%s' \"$URL_B64\" | base64 -d); rm -f youtube-download.m4a; yt-dlp --js-runtimes node --no-playlist --format 'bestaudio[ext=m4a]' --output youtube-download.m4a \"$URL\""
        },
        "intent": "Download the best directly available M4A audio stream.",
        "kind": "tool",
        "name": "Download audio",
        "output_schema": {},
        "retry": {
          "backoff_seconds": 2,
          "max_attempts": 2
        },
        "timeout": 180,
        "tool": {
          "name": "shell_run"
        }
      },
      {
        "id": "copy_video",
        "input": {
          "destination": "{{input.destination_folder}}/youtube-download.mp4",
          "overwrite": "{{nodes.prepare.output.overwrite}}",
          "source": "youtube-download.mp4"
        },
        "intent": "Copy the completed MP4 file to the chosen folder.",
        "kind": "tool",
        "name": "Save video",
        "output_schema": {},
        "retry": {
          "backoff_seconds": 1,
          "max_attempts": 1
        },
        "timeout": 120,
        "tool": {
          "name": "file_copy"
        }
      },
      {
        "id": "copy_audio",
        "input": {
          "destination": "{{input.destination_folder}}/youtube-download.m4a",
          "overwrite": "{{nodes.prepare.output.overwrite}}",
          "source": "youtube-download.m4a"
        },
        "intent": "Copy the completed M4A file to the chosen folder.",
        "kind": "tool",
        "name": "Save audio",
        "output_schema": {},
        "retry": {
          "backoff_seconds": 1,
          "max_attempts": 1
        },
        "timeout": 120,
        "tool": {
          "name": "file_copy"
        }
      },
      {
        "code": {
          "network": [],
          "secrets": [],
          "source": "async function run(input, ctx) {\n  const folder = input.folder.replace(/\\/$/, '');\n  const filename = input.media_type === 'video' ? 'youtube-download.mp4' : 'youtube-download.m4a';\n  return {\n    file_path: folder + '/' + filename,\n    media_type: input.media_type,\n    note: 'Download completed. Only save content you are authorized to download.'\n  };\n}",
          "timeout": 30
        },
        "id": "finish",
        "input": {
          "folder": "{{input.destination_folder}}",
          "media_type": "{{input.download_type}}"
        },
        "intent": "Return the path and type of the file that was saved.",
        "kind": "code",
        "name": "Report saved file",
        "output_schema": {
          "additionalProperties": false,
          "properties": {
            "file_path": {
              "type": "string"
            },
            "media_type": {
              "enum": [
                "video",
                "audio"
              ],
              "type": "string"
            },
            "note": {
              "type": "string"
            }
          },
          "required": [
            "file_path",
            "media_type",
            "note"
          ],
          "type": "object"
        },
        "retry": {
          "backoff_seconds": 1,
          "max_attempts": 1
        },
        "timeout": 120
      }
    ],
    "output": {
      "file_path": "{{nodes.finish.output.file_path}}",
      "media_type": "{{nodes.finish.output.media_type}}",
      "note": "{{nodes.finish.output.note}}"
    },
    "output_schema": {
      "additionalProperties": false,
      "properties": {
        "file_path": {
          "title": "Saved file",
          "type": "string"
        },
        "media_type": {
          "enum": [
            "video",
            "audio"
          ],
          "title": "Download type",
          "type": "string"
        },
        "note": {
          "title": "Result",
          "type": "string"
        }
      },
      "required": [
        "file_path",
        "media_type",
        "note"
      ],
      "type": "object"
    },
    "requirement_notes": {},
    "secrets": []
  }
}