Facebook Videos Downloader - Fork

Add download links for facebook videos (support video on newfeeds and single video page). Fork from EThaiZone version.

当前为 2015-10-30 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Facebook Videos Downloader - Fork
  3. // @description Add download links for facebook videos (support video on newfeeds and single video page). Fork from EThaiZone version.
  4. // @author nhtera
  5. // @match //*.facebook.com/
  6. // @version 0.0.3.1
  7. // @namespace https://greasyfork.org/users/16893
  8. // ==/UserScript==
  9.  
  10. (function () {
  11. // Get the side bar so we can append to it later
  12. var sidebar = document.getElementById('fbPhotoPageActions');
  13. function closest(el, selector) {
  14. var matchesFn;
  15.  
  16. // find vendor prefix
  17. ['matches','webkitMatchesSelector','mozMatchesSelector','msMatchesSelector','oMatchesSelector'].some(function(fn) {
  18. if (typeof document.body[fn] == 'function') {
  19. matchesFn = fn;
  20. return true;
  21. }
  22. return false;
  23. })
  24.  
  25. // traverse parents
  26. while (el!==null) {
  27. var parent = el.parentElement;
  28. if (parent!==null && parent[matchesFn](selector)) {
  29. return parent;
  30. }
  31. el = parent;
  32. }
  33.  
  34. return null;
  35. }
  36. function isElementInViewport (el) {
  37.  
  38. //special bonus for those using jQuery
  39. if (typeof jQuery === "function" && el instanceof jQuery) {
  40. el = el[0];
  41. }
  42.  
  43. var rect = el.getBoundingClientRect();
  44.  
  45. return (
  46. rect.top >= 0 &&
  47. rect.left >= 0 &&
  48. rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
  49. rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
  50. );
  51. }
  52.  
  53. function renderFBDownloader(counter) {
  54.  
  55. // Get all the <embed> elements
  56. var embedElements = document.querySelectorAll('embed[flashvars]');
  57.  
  58. // Flag if we found the video url or not
  59. var found = false;
  60.  
  61. for (var i = 0; i < embedElements.length; i++) {
  62. debugger
  63. // Get the flashvars attribute and decode it
  64. var flashvars = decodeURIComponent(embedElements[i].getAttribute('flashvars'));
  65. var videoDiv = closest(embedElements[i], "div"); //"video");
  66. if (videoDiv) videoDiv = videoDiv.parentNode
  67. else videoDiv = embedElements[i].parentNode ;
  68.  
  69. // Check if this string contains the code we're looking for
  70. var hd_src_index = flashvars.indexOf('hd_src');
  71. var p_width_index = flashvars.indexOf('&width=');
  72. if (hd_src_index > -1 && p_width_index > -1) {
  73. // This string contains the payload we are looking for so parse it
  74. var obj = JSON.parse(flashvars.slice(7, p_width_index));
  75. //var video_data = obj.video_data[0];
  76. var video_data = obj.video_data.progressive[0];
  77.  
  78. //var title = video_data.video_id;
  79. var title = video_data.video_id;
  80. if(document.querySelectorAll('h2.uiHeaderTitle')[0] !== undefined){
  81. if(document.querySelectorAll('h2.uiHeaderTitle')[0].innerText.length > 0){
  82. title = document.querySelectorAll('h2.uiHeaderTitle')[0].innerText;
  83. }
  84. }
  85.  
  86. // High Def
  87. if (video_data.hd_src)
  88. {
  89. var hd_link = document.createElement('a');
  90. hd_link.href = video_data.hd_src;
  91. hd_link.innerHTML = 'Download HD Video';
  92. hd_link.className = 'fbPhotosPhotoActionsItem';
  93. hd_link.download = title + '_hd.mp4';
  94. hd_link.target = "_blank";
  95. hd_link.style.position = "relative";
  96. hd_link.style.zIndex = 9999;
  97. if(sidebar){
  98. if(!sidebar.getAttribute("data-linkdownhdloadadded")){
  99. sidebar.appendChild(hd_link);
  100. sidebar.setAttribute('data-linkdownhdloadadded', true);
  101. }
  102. }
  103. if(videoDiv){
  104. if(!videoDiv.getAttribute("data-linkdownhdloadadded")){
  105. hd_link.style.margin = "5px 0 0 5px";
  106. hd_link.style.color = "red";
  107. hd_link.style.cssFloat = "left";
  108. videoDiv.appendChild(hd_link);
  109. videoDiv.setAttribute('data-linkdownhdloadadded', true);
  110. }
  111. }
  112. }
  113.  
  114. // Low Def
  115. if (video_data.sd_src)
  116. {
  117. var sd_link = document.createElement('a');
  118. sd_link.href = video_data.sd_src;
  119. sd_link.innerHTML = 'Download SD Video';
  120. sd_link.className = 'fbPhotosPhotoActionsItem';
  121. sd_link.download = title + '_sd.mp4';
  122. sd_link.target = "_blank";
  123. sd_link.style.position = "relative";
  124. sd_link.style.zIndex = 9999;
  125. if(sidebar){
  126. if(!sidebar.getAttribute("data-linkdownsdloadadded")){
  127. sidebar.appendChild(sd_link);
  128. sidebar.setAttribute('data-linkdownsdloadadded', true);
  129. }
  130. }
  131. if(videoDiv){
  132. if(!videoDiv.getAttribute("data-linkdownsdloadadded")){
  133. sd_link.style.color = "red";
  134. sd_link.style.cssFloat = "right";
  135. sd_link.style.margin = "5px 5px 0 0";
  136. videoDiv.appendChild(sd_link);
  137. videoDiv.setAttribute('data-linkdownsdloadadded', true);
  138. }
  139. }
  140. }
  141.  
  142. found = true;
  143. } // end if
  144.  
  145. } // end loop
  146.  
  147. if (!found && counter > 20) {
  148. //var not_found = document.createElement('span');
  149. //not_found.innerHTML = 'No download link :(';
  150. //sidebar.appendChild(not_found);
  151. }
  152. return found;
  153. }
  154.  
  155. var counter = 0;
  156. function doExec() {
  157. counter++;
  158. try {
  159. log("Find flashvars. " + counter);
  160. if (renderFBDownloader(counter) == true) {
  161. log("Video links rendered.");
  162. } else {
  163. setTimeout(doExec, 1000);
  164. log("Try again.");
  165. }
  166. } catch(e) {
  167. log("Error" + e);
  168. setTimeout(doExec, 1000);
  169. }
  170. }
  171.  
  172. function log(msg) {
  173. //alert(msg);
  174. console.log("[FB Video Downloader] " + msg);
  175. }
  176. log("First Start.");
  177. doExec();
  178. function checkVideoInViews() {
  179. var videoElements = document.querySelectorAll('video');
  180. if(videoElements.length > 0){
  181. var checkVideoOnView = isElementInViewport(videoElements[0]);
  182. if(checkVideoOnView){
  183. doExec();
  184. }
  185. }
  186. }
  187.  
  188. var patternfbh = /facebook\.com\/(.*?)/;
  189. if (!sidebar && document.URL.match(patternfbh)) {
  190. if (window.removeEventListener) {
  191. window.removeEventListener("scroll", checkVideoInViews);
  192. } else if (window.detachEvent) {
  193. window.detachEvent("scroll", checkVideoInViews);
  194. }
  195. if (window.addEventListener) {
  196. window.addEventListener("scroll", checkVideoInViews, false);
  197. } else if (window.attachEvent) {
  198. window.attachEvent("onscroll", checkVideoInViews, false);
  199. }
  200. }
  201. })();