{
  "schemaVersion": "1.0",
  "item": {
    "slug": "dj-set-ripper",
    "name": "DJ set ripper",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/Robinnnnn/dj-set-ripper",
    "canonicalUrl": "https://clawhub.ai/Robinnnnn/dj-set-ripper",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/dj-set-ripper",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=dj-set-ripper",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md",
      "scripts/normalize-filenames.sh"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-30T16:55:25.780Z",
      "expiresAt": "2026-05-07T16:55:25.780Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
        "contentDisposition": "attachment; filename=\"network-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/dj-set-ripper"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/dj-set-ripper",
    "agentPageUrl": "https://openagent3.xyz/skills/dj-set-ripper/agent",
    "manifestUrl": "https://openagent3.xyz/skills/dj-set-ripper/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/dj-set-ripper/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "DJ Set Ripper",
        "body": "Extract tracklists from DJ sets and download each track individually.\n\n⚠️ Legal Notice: This skill is intended for downloading music you have the right to access — purchases, free releases, creative commons, etc. Respect copyright laws in your jurisdiction. The author is not responsible for misuse."
      },
      {
        "title": "Dependencies",
        "body": "Same as dj-mp3-sourcer (yt-dlp, ffmpeg/ffprobe, spotdl). No additional dependencies."
      },
      {
        "title": "1. Extract Page Content",
        "body": "Fetch the set URL and extract raw text (description, metadata, comments):\n\nYouTube:\n\nyt-dlp --dump-json \"<url>\" | jq -r '.description'\n\nSoundCloud / Mixcloud:\nUse web_fetch to grab the page content in markdown mode.\n\n1001Tracklists:\nUse web_fetch — this source has the most structured data. Prefer it when available."
      },
      {
        "title": "2. Parse the Tracklist (LLM-Powered)",
        "body": "Feed the raw page content to the model with this prompt structure:\n\nExtract all tracks from this DJ set description. Return a JSON array of objects:\n[{\"number\": 1, \"timestamp\": \"0:00\", \"artist\": \"Artist Name\", \"title\": \"Track Title (Mix Name)\"}]\n\nRules:\n- Preserve remix/mix names in the title (e.g. \"Original Mix\", \"Extended Mix\", \"Remix\")\n- If a track is listed as \"ID - ID\" or \"ID\", set artist and title both to \"ID\"\n- If only a timestamp exists with no track info, skip it\n- Normalize artist names (fix ALL CAPS, etc.)\n- If no timestamps exist, set timestamp to null\n- Number tracks sequentially starting from 1\n\nRaw content:\n\"\"\"\n{description_text}\n\"\"\"\n\nIf parsing returns zero tracks, inform the user the tracklist couldn't be extracted and suggest:\n\nChecking 1001Tracklists manually\nPasting the tracklist directly"
      },
      {
        "title": "3. Download Each Track",
        "body": "For each parsed track (skipping any with artist AND title = \"ID\"):\n\nUse the dj-mp3-sourcer workflow: search sources in priority order, prefer extended mixes, download or surface purchase links\nUse sessions_spawn to parallelize downloads (batch of 3-5 at a time to avoid rate limits)\nSave files to: ~/Downloads/{set-name}/\n\nSet name is derived from the mix title (sanitized for filesystem)."
      },
      {
        "title": "4. Optionally Download the Full Mix",
        "body": "Ask the user if they also want the full mix downloaded. If yes:\n\nyt-dlp -x --audio-format mp3 --audio-quality 0 \\\n  --embed-thumbnail --add-metadata \\\n  -o \"~/Downloads/{set-name}/{set-name} [Full Mix].%(ext)s\" \"<url>\""
      },
      {
        "title": "5. Normalize Filenames",
        "body": "After all downloads complete (not per-batch — wait for every sub-agent to finish), run the normalization script once:\n\n# 1. Write the parsed tracklist as JSON\ncat > /tmp/tracklist.json << 'EOF'\n[{\"artist\": \"Artist\", \"title\": \"Title\"}, ...]\nEOF\n\n# 2. Run normalize\nscripts/normalize-filenames.sh ~/Downloads/{set-name} /tmp/tracklist.json\n\nThis fuzzy-matches each mp3 to a tracklist entry and renames to clean Artist - Title.mp3. Handles NA - prefixes, (Official Video) junk, wrong artist credits, label names, etc.\n\nCritical: Run this in the parent agent after all batches return — do NOT rely on sub-agents to rename. The parsed tracklist is the source of truth for filenames."
      },
      {
        "title": "6. Generate the Log File",
        "body": "Create ~/Downloads/{set-name}/{timestamp}.log with format:\n\nDJ Set Ripper Log\n=================\nSet: {set title}\nURL: {original url}\nDate: {ISO timestamp}\nTracks found: {total}\n\n#   | Artist              | Title                          | Status         | Source   | Bitrate | Size  | File/Link\n----|---------------------|--------------------------------|----------------|----------|---------|-------|----------\n01  | Argy                | Aria (Original Mix)            | ✅ downloaded   | spotdl   | 320k    | 8.2MB | Argy - Aria (Original Mix).mp3\n02  | ID                  | ID                             | ⬛ unidentified | —        | —       | —     | —\n03  | Massano             | Odyssey                        | ✅ downloaded   | youtube  | 271k    | 6.5MB | Massano - Odyssey.mp3\n04  | Boris Brejcha       | Gravity (Extended Mix)         | 🛒 purchase     | beatport | —       | —     | https://...\n05  | Some Bootleg        | Unreleased VIP                 | ❌ not found    | —        | —       | —     | —\n\nSummary: 3 downloaded, 1 purchase link, 1 not found, 1 unidentified\nTotal size: ~XXM (individual tracks) + XXM (full mix)\nFull mix: ✅ downloaded → {set-name} [Full Mix].mp3\n\nNotes:\n- Bitrate via `ffprobe -v quiet -show_entries format=bit_rate -of csv=p=0 \"<file>\"`\n- File size via `ls -lh`"
      },
      {
        "title": "Edge Cases",
        "body": "No tracklist in description — check 1001Tracklists via web_search: \"{set title}\" site:1001tracklists.com\n\"ID - ID\" tracks — log as unidentified, don't attempt download\nBootlegs / mashups — search anyway, but expect failures. log as not found with note\nB2B sets — multiple artists in set title, handle gracefully\nDuplicate tracks — deduplicate by artist+title before downloading\nVery long sets (50+ tracks) — batch in groups of 5, report progress as batches complete"
      },
      {
        "title": "Configuration",
        "body": "SettingDefaultNotesOutput directory~/Downloads/{set-name}/Per-set subfolderFormatmp3 320kVia dj-mp3-sourcerDownload full mixask userCan be set to always/neverFree only modetruePassed through to dj-mp3-sourcer (skip paid sources, use spotdl/yt-dlp only)Parallel downloads5Max concurrent track downloads"
      }
    ],
    "body": "DJ Set Ripper\n\nExtract tracklists from DJ sets and download each track individually.\n\n⚠️ Legal Notice: This skill is intended for downloading music you have the right to access — purchases, free releases, creative commons, etc. Respect copyright laws in your jurisdiction. The author is not responsible for misuse.\n\nDependencies\n\nSame as dj-mp3-sourcer (yt-dlp, ffmpeg/ffprobe, spotdl). No additional dependencies.\n\nWorkflow\n1. Extract Page Content\n\nFetch the set URL and extract raw text (description, metadata, comments):\n\nYouTube:\n\nyt-dlp --dump-json \"<url>\" | jq -r '.description'\n\n\nSoundCloud / Mixcloud: Use web_fetch to grab the page content in markdown mode.\n\n1001Tracklists: Use web_fetch — this source has the most structured data. Prefer it when available.\n\n2. Parse the Tracklist (LLM-Powered)\n\nFeed the raw page content to the model with this prompt structure:\n\nExtract all tracks from this DJ set description. Return a JSON array of objects:\n[{\"number\": 1, \"timestamp\": \"0:00\", \"artist\": \"Artist Name\", \"title\": \"Track Title (Mix Name)\"}]\n\nRules:\n- Preserve remix/mix names in the title (e.g. \"Original Mix\", \"Extended Mix\", \"Remix\")\n- If a track is listed as \"ID - ID\" or \"ID\", set artist and title both to \"ID\"\n- If only a timestamp exists with no track info, skip it\n- Normalize artist names (fix ALL CAPS, etc.)\n- If no timestamps exist, set timestamp to null\n- Number tracks sequentially starting from 1\n\nRaw content:\n\"\"\"\n{description_text}\n\"\"\"\n\n\nIf parsing returns zero tracks, inform the user the tracklist couldn't be extracted and suggest:\n\nChecking 1001Tracklists manually\nPasting the tracklist directly\n3. Download Each Track\n\nFor each parsed track (skipping any with artist AND title = \"ID\"):\n\nUse the dj-mp3-sourcer workflow: search sources in priority order, prefer extended mixes, download or surface purchase links\nUse sessions_spawn to parallelize downloads (batch of 3-5 at a time to avoid rate limits)\nSave files to: ~/Downloads/{set-name}/\n\nSet name is derived from the mix title (sanitized for filesystem).\n\n4. Optionally Download the Full Mix\n\nAsk the user if they also want the full mix downloaded. If yes:\n\nyt-dlp -x --audio-format mp3 --audio-quality 0 \\\n  --embed-thumbnail --add-metadata \\\n  -o \"~/Downloads/{set-name}/{set-name} [Full Mix].%(ext)s\" \"<url>\"\n\n5. Normalize Filenames\n\nAfter all downloads complete (not per-batch — wait for every sub-agent to finish), run the normalization script once:\n\n# 1. Write the parsed tracklist as JSON\ncat > /tmp/tracklist.json << 'EOF'\n[{\"artist\": \"Artist\", \"title\": \"Title\"}, ...]\nEOF\n\n# 2. Run normalize\nscripts/normalize-filenames.sh ~/Downloads/{set-name} /tmp/tracklist.json\n\n\nThis fuzzy-matches each mp3 to a tracklist entry and renames to clean Artist - Title.mp3. Handles NA - prefixes, (Official Video) junk, wrong artist credits, label names, etc.\n\nCritical: Run this in the parent agent after all batches return — do NOT rely on sub-agents to rename. The parsed tracklist is the source of truth for filenames.\n\n6. Generate the Log File\n\nCreate ~/Downloads/{set-name}/{timestamp}.log with format:\n\nDJ Set Ripper Log\n=================\nSet: {set title}\nURL: {original url}\nDate: {ISO timestamp}\nTracks found: {total}\n\n#   | Artist              | Title                          | Status         | Source   | Bitrate | Size  | File/Link\n----|---------------------|--------------------------------|----------------|----------|---------|-------|----------\n01  | Argy                | Aria (Original Mix)            | ✅ downloaded   | spotdl   | 320k    | 8.2MB | Argy - Aria (Original Mix).mp3\n02  | ID                  | ID                             | ⬛ unidentified | —        | —       | —     | —\n03  | Massano             | Odyssey                        | ✅ downloaded   | youtube  | 271k    | 6.5MB | Massano - Odyssey.mp3\n04  | Boris Brejcha       | Gravity (Extended Mix)         | 🛒 purchase     | beatport | —       | —     | https://...\n05  | Some Bootleg        | Unreleased VIP                 | ❌ not found    | —        | —       | —     | —\n\nSummary: 3 downloaded, 1 purchase link, 1 not found, 1 unidentified\nTotal size: ~XXM (individual tracks) + XXM (full mix)\nFull mix: ✅ downloaded → {set-name} [Full Mix].mp3\n\nNotes:\n- Bitrate via `ffprobe -v quiet -show_entries format=bit_rate -of csv=p=0 \"<file>\"`\n- File size via `ls -lh`\n\nEdge Cases\nNo tracklist in description — check 1001Tracklists via web_search: \"{set title}\" site:1001tracklists.com\n\"ID - ID\" tracks — log as unidentified, don't attempt download\nBootlegs / mashups — search anyway, but expect failures. log as not found with note\nB2B sets — multiple artists in set title, handle gracefully\nDuplicate tracks — deduplicate by artist+title before downloading\nVery long sets (50+ tracks) — batch in groups of 5, report progress as batches complete\nConfiguration\nSetting\tDefault\tNotes\nOutput directory\t~/Downloads/{set-name}/\tPer-set subfolder\nFormat\tmp3 320k\tVia dj-mp3-sourcer\nDownload full mix\task user\tCan be set to always/never\nFree only mode\ttrue\tPassed through to dj-mp3-sourcer (skip paid sources, use spotdl/yt-dlp only)\nParallel downloads\t5\tMax concurrent track downloads"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/Robinnnnn/dj-set-ripper",
    "publisherUrl": "https://clawhub.ai/Robinnnnn/dj-set-ripper",
    "owner": "Robinnnnn",
    "version": "1.0.1",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/dj-set-ripper",
    "downloadUrl": "https://openagent3.xyz/downloads/dj-set-ripper",
    "agentUrl": "https://openagent3.xyz/skills/dj-set-ripper/agent",
    "manifestUrl": "https://openagent3.xyz/skills/dj-set-ripper/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/dj-set-ripper/agent.md"
  }
}