// ==UserScript== // @name KamTape Downloader // @namespace kamtape // @version 7.0 // @match https://www.kamtape.com/watch?v=* // @match https://www.kamtape.com/results* // @grant none // @run-at document-end // ==/UserScript== (function() { 'use strict'; function sanitize(name) { return name.replace(/[\/\\?%*:|"<>]/g, "_"); } function createDownloadButton(videoId, title) { const button = document.createElement("button"); button.textContent = "Download Video"; button.style.marginLeft = "6px"; button.onclick = function() { let filename = sanitize(title || "video") + ".webm"; const link = document.createElement("a"); link.href = "https://www.kamtape.com/get_video.php?video_id=" + videoId + "&webm=1"; link.download = filename; document.body.appendChild(link); link.click(); document.body.removeChild(link); }; return button; } function insertWatchButton() { const videoId = new URLSearchParams(window.location.search).get("v"); if (!videoId) return; if (document.getElementById("kamtape-download-row")) return; const firstActionsDiv = document.querySelector("#actionsAndStatsDiv .actionsDiv"); if (!firstActionsDiv) return; const actionRow = document.createElement("div"); actionRow.className = "actionRow"; actionRow.id = "kamtape-download-row"; actionRow.style.marginTop = "10px"; const h1 = document.querySelector("h1"); const title = h1 ? h1.textContent.trim() : "video"; actionRow.appendChild(createDownloadButton(videoId, title)); firstActionsDiv.appendChild(actionRow); } function insertSearchButtons() { const infos = document.querySelectorAll(".vinfo"); infos.forEach(function(info) { if (info.querySelector(".kamtape-download")) return; const link = info.querySelector(".vtitle a"); if (!link) return; const match = link.href.match(/v=([^&]+)/); if (!match) return; const videoId = match[1]; const title = link.textContent.trim(); const button = createDownloadButton(videoId, title); button.className = "kamtape-download"; button.style.display = "block"; const ratings = info.querySelectorAll(".rating"); const rating = ratings[ratings.length - 1]; if (rating && rating.parentNode) { rating.parentNode.insertBefore(button, rating.nextSibling); } else { info.appendChild(button); } }); } function run() { insertWatchButton(); insertSearchButtons(); } run(); setTimeout(run, 500); })();