localav

Lightweight avfun video dumper

当前为 2014-09-08 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name localav
  3. // @namespace https://github.com/doomred
  4. // @description Lightweight avfun video dumper
  5. // @version 0.2
  6. // @encoding utf-8
  7. // @license GPLv3
  8. // @copyleft dye `Eric' jarhoo
  9. // @author dye `Eric' jarhoo
  10. // @homepageURL htpp://saltyremix.com
  11. // @icon https://raw.github.com/doomred/localav/master/localav_icon.png
  12. // @include http://*.acfun.*/v/ac*
  13. // @run-at document-end
  14. // @grant GM_getValue
  15. // @grant GM_setValue
  16. // @grant GM_xmlhttpRequest
  17. // @grant GM_openInTab
  18. // @grant GM_registerMenuCommand
  19. // ==/UserScript==
  20.  
  21. var lvDebug, lvLeft, lvBt, lvMain;
  22. lvDebug = 0; // debug usage
  23. lvLeft = GM_getValue('gm_lv_left', '1em');
  24. lvBt = GM_getValue('gm_lv_bottom', '1em');
  25.  
  26. function forceupdate() {
  27. 'use strict';
  28. GM_openInTab('https://raw.github.com/doomred/localav/master/localav.user.js');
  29. return 0;
  30. }
  31. GM_registerMenuCommand('localav| Force Update!', forceupdate, 'a');
  32.  
  33.  
  34. function lvMain() {
  35. 'use strict';
  36. function dynamicparts(obj) {
  37. var key, lvContBox, lvContSize, temp, i, lvContURL, lvDiv, lvContQuality,lvContType;
  38. lvDiv = window.top.document.getElementById('lv-box');
  39. for(key in obj) {
  40. if(obj.hasOwnProperty(key)) {
  41. lvContBox = document.createElement('div');
  42. lvContBox.classList.add('lv-content');
  43. lvContBox.style.margin = '1em 1.5em 0 1.5em';
  44. lvContBox.style.cssFloat = 'left';
  45. lvContBox.style.cursor = 'pointer';
  46. lvContQuality = obj[key].quality;
  47. lvContType = obj[key].files[0].type;
  48. temp = 0;
  49. lvContURL = '';
  50. for(i = 0; i < obj[key].files.length; i++) {
  51. lvContURL += obj[key].files[i].url;
  52. lvContURL += '^'; // split urls
  53. temp += obj[key].files[i].bytes; // add up bytes
  54. }
  55. lvContBox.setAttribute('data-lv', lvContURL);
  56. if(lvDebug) {window.alert(lvContURL);}
  57. temp = temp / 1024 / 1024 * 100; // leave two float point
  58. lvContSize = parseInt(temp, 10) / 100 + 'MB';
  59.  
  60. if(lvContURL.search('.hlv?') !== -1) { // sina hlv fix
  61. lvContType = 'hlv';
  62. }
  63. if(!parseInt(lvContSize, 10)) {lvContSize = '大小仍是个迷';} // make a joke here
  64.  
  65. lvContBox.innerHTML = lvContQuality + ' [' + lvContType + ']<br />' + lvContSize;
  66.  
  67. lvContBox.addEventListener('click', function (e) { // to download stuff within pure js, midified via stackoverflow
  68. var iframe, eventSender, cSrc, arraySrc, i;
  69. if (!e && window.event) {e = window.event;}
  70. eventSender = (window.event) ? e.srcElement : e.target;
  71. cSrc = eventSender.getAttribute('data-lv');
  72. arraySrc = cSrc.split('^');
  73. if(cSrc.search('.hlv?') !== -1) { // sina hlv fix
  74. for(i = 0; i < arraySrc.length; i++) {
  75. GM_openInTab(arraySrc[i]);
  76. }
  77. } else {
  78. for(i = 0; i < arraySrc.length; i++) {
  79. iframe = document.createElement('iframe');
  80. iframe.style.display = 'none';
  81. iframe.style.position = 'absoulte';
  82. iframe.style.top = '0px';
  83. iframe.style.left = '0px';
  84. iframe.src = arraySrc[i];
  85. document.body.appendChild(iframe);
  86. }
  87. }
  88. }, false);
  89.  
  90. if(lvContURL.search('&id=tudou') !== -1 || 0) { // add broken parsed urls here, blame API
  91. lvContBox.style.backgroundColor = 'grey';
  92. lvContBox.innerHTML += "<br />可能失效";
  93. }
  94.  
  95.  
  96. lvDiv.appendChild(lvContBox);
  97.  
  98. /* fix sina duplicate generated API*/
  99. if(lvContURL.search('v.iask.com') !== -1) {
  100. break;
  101. }
  102. }
  103. }
  104. }
  105.  
  106. var idPlayer, temp, tempNum, playerVID, playerDLURL, playerData, lvDiv ;
  107. // idPlayer = document.getElementById("ACFlashPlayer-re"); This not work, cuz page has two same id name
  108. idPlayer = document.getElementsByTagName('iframe')[0];
  109. temp = idPlayer.getAttribute('src');
  110. temp = temp.substr(temp.search('vid')); // strip & temp store
  111. tempNum = temp.search(';');
  112. playerVID = temp.substring(4, tempNum);
  113. playerDLURL = "https://ssl.acfun.tv//aliyun/index.php?&type=mobileclient&vid=" + playerVID;
  114. // key core of localav, another API: jiexi.avfun.info/index.php?vid=xxx
  115. if(lvDebug) {window.alert(playerDLURL);}
  116.  
  117. /* init lv-box */
  118. lvDiv = document.createElement('div');
  119. lvDiv.style.border = '2px solid';
  120. lvDiv.style.left = lvLeft;
  121. lvDiv.style.bottom = lvBt;
  122. lvDiv.style.lineHeight = '1em';
  123. lvDiv.style.zIndex = '9999';
  124. lvDiv.style.position = 'fixed';
  125. lvDiv.style.backgroundColor = '#ffe';
  126. lvDiv.id = 'lv-box';
  127. lvDiv.setAttribute('draggable', 'true');
  128. window.document.body.appendChild(lvDiv);
  129.  
  130. var lvCloseDiv, lvClose, lvFB;
  131. lvCloseDiv = document.createElement('div');
  132. lvCloseDiv.id = 'lv-topbar';
  133. lvCloseDiv.style.textAlign = 'right';
  134. lvCloseDiv.style.background = '#810400';
  135. lvClose = document.createElement('span');
  136. lvClose.innerHTML = '[CLOSE]';
  137. lvClose.style.cursor = 'pointer';
  138. lvClose.style.padding = '0 5px';
  139. lvClose.style.textDecoration = 'underline';
  140. lvClose.onclick = function() {
  141. lvDiv.style.display = 'none';
  142. };
  143. lvCloseDiv.appendChild(lvClose);
  144. lvDiv.appendChild(lvCloseDiv);
  145. lvFB = document.createElement('div');
  146. lvFB.innerHTML = 'feedback';
  147. lvFB.style.cursor = 'pointer';
  148. lvFB.style.padding = '0 5px';
  149. lvFB.style.textDecoration = 'underline';
  150. lvFB.onclick = function() {
  151. window.open('https://github.com/doomred/localav/issues', 'FEED_ME_BUG');
  152. };
  153. lvDiv.appendChild(lvFB);
  154.  
  155. GM_xmlhttpRequest({
  156. method: "GET",
  157. url: playerDLURL,
  158. headers: {
  159. "Accept": "application/json"
  160. },
  161. onload: function(response) {
  162. playerData = JSON.parse(response.responseText);
  163. dynamicparts(playerData.result);
  164. }
  165. });
  166. /* HTML5 drag & drop element
  167. * Modified via:http://jsfiddle.net/robertc/kKuqH/
  168. * More info: https://stackoverflow.com/questions/6230834/html5-drag-and-drop-anywhere-on-the-screen */
  169. function drag_start(event) {
  170. var style = window.getComputedStyle(event.target, null);
  171. event.dataTransfer.setData("text/plain",
  172. (parseInt(style.getPropertyValue("left"),10) - event.clientX) + ',' + (parseInt(style.getPropertyValue("bottom"),10) + event.clientY));
  173. }
  174. function drag_over(event) {
  175. event.preventDefault();
  176. return false;
  177. }
  178. function drop(event) {
  179. var offset = event.dataTransfer.getData("text/plain").split(',');
  180. var dg = document.getElementById('lv-box');
  181. dg.style.left = (event.clientX + parseInt(offset[0],10)) + 'px';
  182. dg.style.bottom = (-event.clientY + parseInt(offset[1],10)) + 'px';
  183. GM_setValue('gm_lv_left', dg.style.left);
  184. GM_setValue('gm_lv_bt', dg.style.bottom);
  185. event.preventDefault();
  186. return false;
  187. }
  188. document.getElementById('lv-box').addEventListener('dragstart',drag_start,false);
  189. document.body.addEventListener('dragover',drag_over,false);
  190. document.body.addEventListener('drop',drop,false);
  191.  
  192. }
  193. function checkload() {
  194. var temp = document.getElementsByTagName('iframe')[0].getAttribute('src');
  195. if(temp !== null) {
  196. lvMain();
  197. } else {
  198. window.setTimeout(checkload, 1000);
  199. }
  200. }
  201. window.setTimeout(checkload, 1500); /* src attribute of iframe is dynamic generated, needs time */