您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Add download links for facebook videos (support video on newfeeds and single video page). Fork from EThaiZone version.
// ==UserScript== // @name Facebook Videos Downloader - Fork // @description Add download links for facebook videos (support video on newfeeds and single video page). Fork from EThaiZone version. // @author nhtera // @match //*.facebook.com/ // @version 0.0.3.1 // @namespace https://greasyfork.runtimutd.eu.org/users/16893 // ==/UserScript== (function () { // Get the side bar so we can append to it later var sidebar = document.getElementById('fbPhotoPageActions'); function closest(el, selector) { var matchesFn; // find vendor prefix ['matches','webkitMatchesSelector','mozMatchesSelector','msMatchesSelector','oMatchesSelector'].some(function(fn) { if (typeof document.body[fn] == 'function') { matchesFn = fn; return true; } return false; }) // traverse parents while (el!==null) { var parent = el.parentElement; if (parent!==null && parent[matchesFn](selector)) { return parent; } el = parent; } return null; } function isElementInViewport (el) { //special bonus for those using jQuery if (typeof jQuery === "function" && el instanceof jQuery) { el = el[0]; } var rect = el.getBoundingClientRect(); return ( rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */ rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */ ); } function renderFBDownloader(counter) { // Get all the <embed> elements var embedElements = document.querySelectorAll('embed[flashvars]'); // Flag if we found the video url or not var found = false; for (var i = 0; i < embedElements.length; i++) { debugger // Get the flashvars attribute and decode it var flashvars = decodeURIComponent(embedElements[i].getAttribute('flashvars')); var videoDiv = closest(embedElements[i], "div"); //"video"); if (videoDiv) videoDiv = videoDiv.parentNode else videoDiv = embedElements[i].parentNode ; // Check if this string contains the code we're looking for var hd_src_index = flashvars.indexOf('hd_src'); var p_width_index = flashvars.indexOf('&width='); if (hd_src_index > -1 && p_width_index > -1) { // This string contains the payload we are looking for so parse it var obj = JSON.parse(flashvars.slice(7, p_width_index)); //var video_data = obj.video_data[0]; var video_data = obj.video_data.progressive[0]; //var title = video_data.video_id; var title = video_data.video_id; if(document.querySelectorAll('h2.uiHeaderTitle')[0] !== undefined){ if(document.querySelectorAll('h2.uiHeaderTitle')[0].innerText.length > 0){ title = document.querySelectorAll('h2.uiHeaderTitle')[0].innerText; } } // High Def if (video_data.hd_src) { var hd_link = document.createElement('a'); hd_link.href = video_data.hd_src; hd_link.innerHTML = 'Download HD Video'; hd_link.className = 'fbPhotosPhotoActionsItem'; hd_link.download = title + '_hd.mp4'; hd_link.target = "_blank"; hd_link.style.position = "relative"; hd_link.style.zIndex = 9999; if(sidebar){ if(!sidebar.getAttribute("data-linkdownhdloadadded")){ sidebar.appendChild(hd_link); sidebar.setAttribute('data-linkdownhdloadadded', true); } } if(videoDiv){ if(!videoDiv.getAttribute("data-linkdownhdloadadded")){ hd_link.style.margin = "5px 0 0 5px"; hd_link.style.color = "red"; hd_link.style.cssFloat = "left"; videoDiv.appendChild(hd_link); videoDiv.setAttribute('data-linkdownhdloadadded', true); } } } // Low Def if (video_data.sd_src) { var sd_link = document.createElement('a'); sd_link.href = video_data.sd_src; sd_link.innerHTML = 'Download SD Video'; sd_link.className = 'fbPhotosPhotoActionsItem'; sd_link.download = title + '_sd.mp4'; sd_link.target = "_blank"; sd_link.style.position = "relative"; sd_link.style.zIndex = 9999; if(sidebar){ if(!sidebar.getAttribute("data-linkdownsdloadadded")){ sidebar.appendChild(sd_link); sidebar.setAttribute('data-linkdownsdloadadded', true); } } if(videoDiv){ if(!videoDiv.getAttribute("data-linkdownsdloadadded")){ sd_link.style.color = "red"; sd_link.style.cssFloat = "right"; sd_link.style.margin = "5px 5px 0 0"; videoDiv.appendChild(sd_link); videoDiv.setAttribute('data-linkdownsdloadadded', true); } } } found = true; } // end if } // end loop if (!found && counter > 20) { //var not_found = document.createElement('span'); //not_found.innerHTML = 'No download link :('; //sidebar.appendChild(not_found); } return found; } var counter = 0; function doExec() { counter++; try { log("Find flashvars. " + counter); if (renderFBDownloader(counter) == true) { log("Video links rendered."); } else { setTimeout(doExec, 1000); log("Try again."); } } catch(e) { log("Error" + e); setTimeout(doExec, 1000); } } function log(msg) { //alert(msg); console.log("[FB Video Downloader] " + msg); } log("First Start."); doExec(); function checkVideoInViews() { var videoElements = document.querySelectorAll('video'); if(videoElements.length > 0){ var checkVideoOnView = isElementInViewport(videoElements[0]); if(checkVideoOnView){ doExec(); } } } var patternfbh = /facebook\.com\/(.*?)/; if (!sidebar && document.URL.match(patternfbh)) { if (window.removeEventListener) { window.removeEventListener("scroll", checkVideoInViews); } else if (window.detachEvent) { window.detachEvent("scroll", checkVideoInViews); } if (window.addEventListener) { window.addEventListener("scroll", checkVideoInViews, false); } else if (window.attachEvent) { window.attachEvent("onscroll", checkVideoInViews, false); } } })();