NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Recurbate download // @version 1.2.2 // @description Adds a download button for each video on recurbate.me // @author razorwax // @updateURL https://openuserjs.org/meta/razorwax/Recurbate_download.meta.js // @downloadURL https://openuserjs.org/install/razorwax/Recurbate_download.user.js // @match https://recurbate.me/video* // @match https://recu.me/video* // @license MIT // ==/UserScript== function ErrorPrint(errorReason) { var error = "Recurbate Download Error! [reason = " + errorReason + "]"; console.error(error); window.alert(error); } function DataErrorPrint(errorReason) { var description; if (errorReason == "shall_signin") { description = "You need to sign in to an account to be able to download."; } else if (errorReason == "shall_subscribe") { description = "Your current free downloads have been used today, please upgrade your membership to unlock more downloads."; } else if (errorReason == "wrong_token") { description = "Something unexpected has happen, try to reload the site and try again. If it doesn't work then report the error."; } var error = "Recurbate Download Error! [data_reponse = " + errorReason + "]\n\n" + description; console.error(error); window.alert(error); } function WarnPrint(warnMessage) { var warn = "Warning: " + warnMessage; console.warn(warn); window.alert(warn); } function DownloadVideo(url) { if (!url) { ErrorPrint("find_video_src_failure"); return; } window.open(url, '_blank'); } function FindSourceFromUnstartedVideo(videoBtn) { // Find token and id var token = videoBtn.attr("data-token"); var id = videoBtn.attr("data-video-id"); if (token && id) { // Send video request to server var url = "/api/video/" + id + "?token=" + token; $.get(url, function(data) { // Find the src by using jquery selectors var sourceElem = $(data).find("video source"); if (sourceElem.length) { var src = sourceElem.attr("src"); if (src) { DownloadVideo(src); return; } } // Find the src by using string search if (data.includes("<video") && data.includes("src=")) { var src = data.match(/src=".+?"/m); if (!!src) { // Convert to string src = src[0]; // Find the source substring src = src.substring(5, src.length - 1); DownloadVideo(src); return; } } DataErrorPrint(data); }); } else { ErrorPrint("token_and_id_failure"); } } function FindSourceFromStartedVideo() { var foundVideo; var searchVideos = $("video"); if (searchVideos.length == 1) { // Guess this is the video we are looking for foundVideo = searchVideos[0]; } else { // Multiple videos found, search for the correct one var videoIdRegex = /video_\d+/; for (var video of searchVideos) { if (video.id.match(videoIdRegex)) { foundVideo = video; break; } } } if (foundVideo) { var source = foundVideo.src; if (!source) { // Try to find video source by source element var sourceElem = $(foundVideo).find("source"); if (sourceElem && sourceElem.length > 0) { source = sourceElem[0].src; } } DownloadVideo(source); } else { ErrorPrint("find_video_failure"); } } function AddDownloadButton(appendToElem) { // Remove official download button $("a.download.btn").remove(); // Add new download button var downloadBtn = $("<button style=\"margin-left: 10px;\" class=\"btn btn-warning btn-sm\"><i class=\"fas fa-download\"></i><b style=\"color:#212528\"> Download</b></button>").appendTo(appendToElem); downloadBtn.on("click", function() { // Download button press var videoBtns = $("#play_button"); if (videoBtns.length > 0) { // Found the unstarted video player, find src from it FindSourceFromUnstartedVideo($(videoBtns[0])); } else { // Video must have been started FindSourceFromStartedVideo(); } }); } // Create download button $(function () { var addTo = $("a.bookmark"); if (addTo.length == 1) { addTo = addTo.parent(); } else { addTo = $("div.video-info").children("div"); } if (addTo.length > 0) { AddDownloadButton($(addTo[0])); } else { ErrorPrint("add_download_btn_failure"); } });