Lazy Embedded Video

Lazy load embedded videos from Youtube/Dailymotion/Vimeo/Rutube/Twitch/Ustream/Coub/Vine/Facebook

目前為 2021-06-13 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name Lazy Embedded Video
  3. // @namespace zeusex81@gmail.com
  4. // @description Lazy load embedded videos from Youtube/Dailymotion/Vimeo/Rutube/Twitch/Ustream/Coub/Vine/Facebook
  5. // @version 3.7
  6. // @include *
  7. // @icon https://i.imgur.com/rf0mFDM.png
  8. // @license MIT
  9. // @grant GM.getValue
  10. // @grant GM.setValue
  11. // @grant GM_getValue
  12. // @grant GM_setValue
  13. // @run-at document-start
  14. // @noframes
  15. // ==/UserScript==
  16.  
  17. (async function() {
  18. var a = document.createElement("A");
  19. try { a.href = top.location.href; }
  20. catch(e) { a.href = document.referrer || location.href; }
  21. if(a.hostname && /(youtube|dailymotion|vimeo|rutube|twitch|ustream|coub|vine|facebook)\.[^.]+$/.test(a.hostname))
  22. return;
  23.  
  24. var getValue = typeof(GM) != "undefined" ? GM.getValue : typeof(GM_getValue) != "undefined" ? GM_getValue :
  25. function(name, value) { return localStorage.getItem(name) || value; };
  26. var setValue = typeof(GM) != "undefined" ? GM.setValue : typeof(GM_setValue) != "undefined" ? GM_setValue :
  27. function(name, value) { localStorage.setItem(name, value); };
  28.  
  29. var settings = JSON.parse(await getValue("zeusLEV", '[false,true,[]]'));
  30. while(typeof(settings) == "string") settings = JSON.parse(settings);
  31. if(settings[2].includes(location.hostname))
  32. return;
  33. window.addEventListener("message", async function(e) {
  34. if(!e.data.startsWith("zeusLEV")) return;
  35. var data = e.data.split(' ');
  36. switch(data[1]) {
  37. case "CSP" : iframes[parseInt(data[2])].dataset.zeusLEV = 3; break;
  38. case "play" : iframes[parseInt(data[2])].removeAttribute("srcdoc");
  39. iframes[parseInt(data[2])].src = data[3]; break;
  40. case "settings" :
  41. settings = JSON.parse(await getValue("zeusLEV", '[false,true,[]]'));
  42. while(typeof(settings) == "string") settings = JSON.parse(settings);
  43. switch(data[2]) {
  44. case "autoplay" : settings[0] = data[3] == 'true'; break;
  45. case "flash" : settings[1] = data[3] == 'true'; break;
  46. case "reset" : settings[2] = []; break;
  47. case "whitelist" :
  48. observer.disconnect();
  49. cancelAnimationFrame(animation);
  50. if(!settings[2].includes(location.hostname))
  51. settings[2].push(location.hostname);
  52. for(var i = 0; i < iframes.length; i++)
  53. iframes[i].removeAttribute("srcdoc");
  54. break;
  55. }
  56. setValue("zeusLEV", JSON.stringify(settings));
  57. break;
  58. }
  59. });
  60.  
  61. var html, iframes = [];
  62. var createHtml = function(url, src, api, background_img) {
  63. /(.*\/\/(?:[^.\/]+\.)?([^.\/]+)\.[^.\/]+)\//i.test(url);
  64. var provider_url = RegExp.$1, provider_name = RegExp.$2, data_convert = "", button_color = "";
  65. api += '&callback=jsonpCallback';
  66. if(api.includes("yahooapis"))
  67. data_convert += 'data = data.query.results.json;';
  68. switch(provider_name) {
  69. case "youtube" :
  70. button_color = "#c22";
  71. data_convert += 'data = {'+
  72. 'thumbnail_url: (data.items[0].snippet.thumbnails.maxres || data.items[0].snippet.thumbnails.standard || '+
  73. 'data.items[0].snippet.thumbnails.high || data.items[0].snippet.thumbnails.medium || '+
  74. 'data.items[0].snippet.thumbnails.default).url,'+
  75. 'title: data.items[0].snippet.title,'+
  76. 'author_url: "https://www.youtube.com/channel/"+data.items[0].snippet.channelId,'+
  77. 'author_name: data.items[0].snippet.channelTitle,'+
  78. 'duration: data.items[0].contentDetails ? /PT(\\d+H)?(\\d+M)?(\\d+S)?/i.test(data.items[0].contentDetails.duration) && '+
  79. '(parseInt(RegExp.$1||0)*3600+parseInt(RegExp.$2||0)*60+parseInt(RegExp.$3||0)) || "LIVE" : "PLAYLIST"'+
  80. '};';
  81. /*data_convert += 'if(data.thumbnail_url) {'+
  82. 'var img = new Image();'+
  83. 'img.onload = function() {'+
  84. 'var valid = this.naturalWidth > 120;'+
  85. 'if(this.src.includes("hqdefault_live")) {'+
  86. 'this.src = this.src.replace("hqdefault"+(valid ? "" : "_live"), "maxresdefault");'+
  87. '} else if(valid) {'+
  88. 'document.body.style.backgroundImage = "url("+this.src+")";'+
  89. '} else if(this.src.includes("maxresdefault")) {'+
  90. 'this.src = this.src.replace("maxresdefault", "sddefault");'+
  91. '} else {'+
  92. 'document.body.style.backgroundImage = "url("+this.src.replace("sddefault", "hqdefault")+")";'+
  93. '}'+
  94. '};'+
  95. 'img.src = removeProtocol(data.thumbnail_url.replace(/\\w+.jpg$/, "hqdefault_live.jpg"));'+
  96. 'delete data.thumbnail_url;'+
  97. '}';*/
  98. break;
  99. case "dailymotion" :
  100. button_color = "#fd5";
  101. // data_convert += 'if(data.thumbnail_url) data.thumbnail_url = data.thumbnail_url.replace(/\\/x240[^.]+/i, "");';
  102. data_convert += 'data.author_url = data["owner.url"];'+
  103. 'data.author_name = data["owner.screenname"];'+
  104. 'if(!data.duration) data.duration = "LIVE";';
  105. break;
  106. case "vimeo" :
  107. button_color = "#5af";
  108. data_convert += 'if(data.thumbnail_url) data.thumbnail_url = data.thumbnail_url.replace(/_\\d+x\\d+/i, "");';
  109. break;
  110. case "rutube" :
  111. button_color = "#444";
  112. data_convert += 'if(data.thumbnail_url) data.thumbnail_url = data.thumbnail_url.replace(/\\?.+/i, "");';
  113. break;
  114. case "twitch" :
  115. button_color = "#548";
  116. var id = url.match(/[^\/]+$/)[0];
  117. if(src.includes("channel")) { // channel live
  118. data_convert += 'var script = document.getElementById("api");'+
  119. 'if(script.src.includes("/users")) {'+
  120. 'if(data.users[0]) {'+
  121. 'var script2 = document.createElement("SCRIPT");'+
  122. 'script2.id = "api";'+
  123. 'script2.src = "'+api+'".replace("{api}", "streams")+"&channel="+data.users[0]._id;'+
  124. 'document.body.replaceChild(script2, script);'+
  125. '}'+
  126. 'return;'+
  127. '} else if(script.src.includes("/streams")) {'+
  128. 'if(data.streams.length == 0) {'+
  129. 'document.getElementById("space").insertAdjacentHTML("afterend", "<div id=duration>offline</div>");'+
  130. 'var script2 = document.createElement("SCRIPT");'+
  131. 'script2.id = "api";'+
  132. 'script2.src = "'+api+'".replace("{api}", "channels/"+script.src.match(/[^=]+$/)[0]);'+
  133. 'document.body.replaceChild(script2, script);'+
  134. 'return;'+
  135. '}'+
  136. 'if(data.streams[0].preview)'+
  137. 'data.streams[0].channel.video_banner = data.streams[0].preview.template.replace("{width}x{height}", "0x0");'+
  138. 'else delete data.streams[0].channel.video_banner;'+
  139. 'data = data.streams[0].channel;'+
  140. '}'+
  141. 'data.title = data.status || "Untitled Broadcast";'+
  142. 'if(data.video_banner) data.thumbnail_url = data.video_banner;'+
  143. 'if(data.url) data.author_url = data.url;'+
  144. 'if(data.display_name) data.author_name = data.display_name;'+
  145. 'if(data.game) data.duration = \'playing <a target=_blank href="'+provider_url+
  146. '/directory/game/\'+data.game+\'">\'+data.game+\'</a>\';'+
  147. 'if(document.getElementById("duration")) delete data.duration;';
  148. if(background_img)
  149. api = api.replace("{api}", "users")+'&login='+id;
  150. else
  151. api = api.replace("{api}", "streams")+'&channel='+id;
  152. } else { // video recorded
  153. api = api.replace("{api}", "videos/"+id);
  154. data_convert += 'if(data.preview) data.thumbnail_url = data.preview.template.replace("{width}x{height}", "0x0");'+
  155. 'if(data.channel) data.author_url = data.channel.url;'+
  156. 'if(data.channel) data.author_name = data.channel.display_name;'+
  157. 'if(data.length) data.duration = data.length;';
  158. }
  159. break;
  160. case "ustream" :
  161. button_color = "#f82";
  162. if(background_img) // channel live
  163. data_convert += 'delete data.thumbnail_url;';
  164. break;
  165. case "coub" :
  166. button_color = "#04f";
  167. data_convert += 'if(data.channel_url) data.author_url = data.channel_url;';
  168. break;
  169. case "vine" :
  170. button_color = "#0b8";
  171. break;
  172. case "facebook" :
  173. button_color = "#ccc";
  174. data_convert += 'data.title = /<a.*?>(.+)<\\/a><p>/i.test(data.html) ? RegExp.$1 : "Untitled";';
  175. break;
  176. }
  177. if(!html) html = [
  178. '<!doctype html>'+
  179. '<html>'+
  180. '<head>'+
  181. '<title>Lazy Embedded Video</title>'+
  182. '<style>'+
  183. 'html { height:100%; } '+
  184. 'body { margin:0; height:100%; color:white; font:14px sans-serif; '+
  185. 'background:black center/100% no-repeat; } '+
  186. 'a { color:inherit; font-weight:bold; text-decoration:none; } '+
  187. 'a:hover { text-decoration:underline; } '+
  188. '#interface { position:absolute; width:100%; height:100%; overflow:hidden; opacity:0.9; '+
  189. '-moz-user-select:none; -webkit-user-select:none; -ms-user-select:none; user-select:none; } '+
  190. '#playButton { display:flex; height:100%; cursor:pointer; } '+
  191. '#playButton > div { width:70px; height:70px; margin:auto; border-radius:50%; background-color:black; } '+
  192. '#playButton:hover > div { background-color:', button_color, '; } '+
  193. '#playButton > div > div { width:0; height:0; margin:20px 0 0 25px; border:solid transparent; '+
  194. 'border-width:14px 0px 14px 28px; border-left-color:white; } '+
  195. '#infobar { position:absolute; top:0px; width:100%; height:32px; display:flex; '+
  196. 'box-sizing:border-box; background:black; border:0px solid grey; border-bottom-width:1px; } '+
  197. '#author, #title, #duration { overflow:hidden; white-space:nowrap; margin:auto 8px; } '+
  198. '#author { flex-shrink:0; max-width:30%; color:', button_color ,'; } '+
  199. '#space { flex-grow:1; } '+
  200. '#duration { flex-shrink:0; } '+
  201. '#settingsButton { flex-basis:32px; flex-shrink:0; font:bold 20px sans-serif; text-align:center; cursor:pointer; } '+
  202. '#settingsButton:hover { color:', button_color, '; } '+
  203. '#settingsButton.active { background-color:', button_color, '; color:black; } '+
  204. '#settingsPanel { position:absolute; right:0px; top:31px; max-height:100%; margin:0px; list-style:none; padding:8px; '+
  205. 'border:solid grey; border-width:0px 0px 1px 1px; background-color:', button_color ,'; color:black; cursor:default; visibility:hidden; } '+
  206. '#settingsPanel.active { visibility:visible; } '+
  207. '#settingsPanel label { display:inline-block; width:144px; vertical-align:top; } '+
  208. '#settingsPanel button { width:100%; }'+
  209. '</style>'+
  210. '</head>'+
  211. '<body>'+
  212. '<div id=interface>'+
  213. '<div id=playButton><div><div></div></div></div>'+
  214. '<div id=infobar>'+
  215. '<a id=author target=_blank onmouseenter="this.title = this.scrollWidth > this.clientWidth ? this.textContent : \'\';" href="', provider_url, '">', provider_name, '</a>'+
  216. '<a id=title target=_blank onmouseenter="this.title = this.scrollWidth > this.clientWidth ? this.textContent : \'\';" href="', url, '">', url, '</a>'+
  217. '<div id=space></div>'+
  218. '<span id=settingsButton>⚙</span>'+
  219. '</div>'+
  220. '<ul id=settingsPanel>'+
  221. '<li><label>Allow autoplay:</label><input class=setting type=checkbox', '', '></li>'+
  222. '<li><label>Legacy Flash support:</label><input class=setting type=checkbox', '', '></li>'+
  223. '<li><button class=setting>Whitelist this site</button>'+
  224. '<li><button class=setting>Clear whitelist</button>'+
  225. '</ul>'+
  226. '</div>'+
  227. '<script>'+
  228. 'parent.postMessage("zeusLEV CSP ', iframes.length, '", "'+location.href+'");'+
  229. 'document.getElementById("playButton").onclick = function() {'+
  230. 'parent.postMessage("zeusLEV play ', iframes.length, ' ', src, '", "'+location.href+'");'+
  231. '};'+
  232. 'var settingsButton = document.getElementById("settingsButton");'+
  233. 'var settingsPanel = document.getElementById("settingsPanel");'+
  234. 'settingsButton.onclick = function() {'+
  235. 'settingsButton.classList.toggle("active");'+
  236. 'settingsPanel.classList.toggle("active");'+
  237. '};'+
  238. '[].slice.call(settingsPanel.getElementsByClassName("setting")).forEach(function(e, i) {'+
  239. 'switch(i) {'+
  240. 'case 0: e.onchange = function() { parent.postMessage("zeusLEV settings autoplay "+e.checked, "'+location.href+'"); }; break;'+
  241. 'case 1: e.onchange = function() { parent.postMessage("zeusLEV settings flash "+e.checked , "'+location.href+'"); }; break;'+
  242. 'case 2: e.onclick = function() { parent.postMessage("zeusLEV settings whitelist" , "'+location.href+'"); }; break;'+
  243. 'case 3: e.onclick = function() { parent.postMessage("zeusLEV settings reset" , "'+location.href+'"); }; break;'+
  244. '}'+
  245. '});'+
  246. 'var loaded = false;'+
  247. 'function removeProtocol(url) { return url.replace(/^[a-z]+:/i, ""); }'+
  248. 'function jsonpCallback(data) {',
  249. data_convert,
  250. 'loaded = true;'+
  251. 'if(data.thumbnail_url) document.body.style.backgroundImage = "url("+removeProtocol(data.thumbnail_url)+")";'+
  252. 'if(data.url) document.getElementById("title").href = removeProtocol(data.url);'+
  253. 'if(data.title) document.getElementById("title").textContent = data.title;'+
  254. 'if(data.author_url) document.getElementById("author").href = removeProtocol(data.author_url);'+
  255. 'if(data.author_name) document.getElementById("author").textContent = data.author_name;'+
  256. 'if(data.duration) document.getElementById("space").insertAdjacentHTML("afterend",'+
  257. '"<div id=duration>"+(Number(data.duration) ? new Date(data.duration*1000).toISOString().substr(11,8) : data.duration)+"</div>");'+
  258. '}'+
  259. '</script>'+
  260. '<script id=api src="', api, '"></script>'+
  261. '<script>'+
  262. 'if(!loaded)'+
  263. 'document.body.style.backgroundImage = "', background_img, '";'+
  264. '</script>'+
  265. '</body>'+
  266. '</html>'
  267. ];
  268. html[ 1] = button_color;
  269. html[ 3] = button_color;
  270. html[ 5] = button_color;
  271. html[ 7] = button_color;
  272. html[ 9] = button_color;
  273. html[11] = provider_url;
  274. html[13] = provider_name;
  275. html[15] = url;
  276. html[17] = url;
  277. html[19] = settings[0] ? ' checked' : '';
  278. html[21] = settings[1] ? ' checked' : '';
  279. html[23] = iframes.length;
  280. html[25] = iframes.length;
  281. html[27] = src;
  282. html[29] = data_convert;
  283. html[31] = api;
  284. html[33] = background_img;
  285. };
  286.  
  287. var createOembed = function(api, url) { return api+encodeURIComponent(url); };
  288. // var createNOembed = function(api, url) { return createOembed("https://noembed.com/embed?url=", url); };
  289. var createJOembed = function(api, url) { return createOembed("https://json2jsonp.com/?url=", createOembed(api, url)); };
  290.  
  291. var createLazyVideo = function(elem) {
  292. var id, args = "", url, src = a.href = elem.src || elem.data || elem.dataset.src;
  293. if(!a.hostname || elem.dataset.zeusLEV) return;
  294. elem.dataset.zeusLEV = 1;
  295. switch(a.hostname.match(/([^.]+)\.[^.]+$/)[1]) {
  296. case "youtube" :
  297. case "youtube-nocookie" :
  298. if(/\/(?:p\/|embed\/videoseries)([^&]*)/i.test(a.pathname)) {
  299. id = RegExp.$1 || (/[?&]list=([^&]+)/i.test(a.search) && RegExp.$1);
  300. if(!id || (settings[0] && a.search.includes("autoplay=1"))) return;
  301. if(/[?&](v=[^&]+)/i.test(a.search)) args += "&"+RegExp.$1;
  302. if(/[?&](index=[^&]+)/i.test(a.search)) args += "&"+RegExp.$1;
  303. if(/[?&](start=[^&]+)/i.test(a.search)) args += "&"+RegExp.$1;
  304. createHtml(
  305. url = /[?&]v=([^&]+)/i.test(a.search) ? "https://www.youtube.com/watch?list="+id+args : "https://www.youtube.com/playlist?list="+id,
  306. src = "https://www.youtube-nocookie.com/embed/videoseries?autoplay=1&list="+id+args,
  307. "https://www.googleapis.com/youtube/v3/playlists?part=snippet&fields=items/snippet(channelId,title,thumbnails,channelTitle)&key=AIzaSyDLowtdhRBblJhyDhtiPaIbwRKT_PSyHWE&id="+id,
  308. /[?&]v=([^&]+)/i.test(a.search) ? "url(https://i.ytimg.com/vi/"+RegExp.$1+"/hqdefault.jpg)" : null
  309. );
  310. } else {
  311. if(/\/(?:v|embed)\/([^&]*)/i.test(a.pathname)) id = RegExp.$1 || (/[?&]v=([^&]+)/i.test(a.search) && RegExp.$1);
  312. if(!id || (settings[0] && a.search.includes("autoplay=1"))) return;
  313. if(/[?&](start=[^&]+)/i.test(a.search)) args += "&"+RegExp.$1;
  314. createHtml(
  315. url = "https://www.youtube.com/watch?v="+id+args,
  316. src = "https://www.youtube-nocookie.com/embed/"+id+"?autoplay=1"+args,
  317. // createNOembed("https://www.youtube.com/oembed?format=json&url=", url),
  318. "https://www.googleapis.com/youtube/v3/videos?part=snippet,contentDetails&fields=items(snippet(channelId,title,thumbnails,channelTitle),contentDetails/duration)&key=AIzaSyDLowtdhRBblJhyDhtiPaIbwRKT_PSyHWE&id="+id,
  319. "url(https://i.ytimg.com/vi/"+id+"/hqdefault.jpg)"
  320. );
  321. }
  322. break;
  323. case "dailymotion" :
  324. if(/\/(?:swf|embed)\/(?:video\/)?([^&_]+)/i.test(a.pathname)) id = RegExp.$1;
  325. if(!id || (settings[0] && a.search.includes("autoplay=1"))) return;
  326. // if(/[?&](mute=[^&]+)/i.test(a.search)) args += "&"+RegExp.$1;
  327. if(/[?&](start=[^&]+)/i.test(a.search)) args += "&"+RegExp.$1;
  328. createHtml(
  329. url = "https://www.dailymotion.com/video/"+id+"?"+args,
  330. src = "https://www.dailymotion.com/embed/video/"+id+"?autoplay=1"+args,
  331. // createOembed("https://www.dailymotion.com/services/oembed?format=json&url=", url),
  332. "https://api.dailymotion.com/video/"+id+"?fields=owner.screenname,owner.url,title,url,duration,thumbnail_url",
  333. "url(https://www.dailymotion.com/thumbnail/video/"+id+")"
  334. );
  335. break;
  336. case "vimeo" :
  337. if(/\/(?:moogaloop\.swf|video\/)([^&]*)/i.test(a.pathname))
  338. id = RegExp.$1 || (/[?&]clip_id=([^&]+)/i.test(a.search) && RegExp.$1);
  339. if(!id || (settings[0] && a.search.includes("autoplay=1"))) return;
  340. if(/[?&](loop=[^&]+)/i.test(a.search)) args += "&"+RegExp.$1;
  341. if(/(\#t=[\dhms]+)/i.test(a.hash)) args += RegExp.$1;
  342. createHtml(
  343. url = "https://vimeo.com/"+id+"?"+args,
  344. src = "https://player.vimeo.com/video/"+id+"?autoplay=1"+args,
  345. createOembed("https://vimeo.com/api/oembed.json?url=", url)
  346. );
  347. break;
  348. case "rutube" :
  349. if(/(?:\/play)?\/embed\/([^&.\/]+)/i.test(a.pathname)) id = RegExp.$1;
  350. else if(/[?&]pl_video=([^&]+)/i.test(a.search)) id = RegExp.$1;
  351. if(!id || (settings[0] && a.search.includes("autoStart=1"))) return;
  352. if(/[?&](bmstart=[^&]+)/i.test(a.search)) args += "&"+RegExp.$1;
  353. createHtml(
  354. url = "https://rutube.ru/"+(isNaN(id) ? "video/"+id+"/" : "tracks/"+id+".html"),
  355. src = "https://rutube.ru/"+(a.pathname.includes("/embed/") ? "play/embed/"+id+"?autoStart=1"+args : "pl/?pl_video="+id),
  356. createJOembed("https://rutube.ru/api/oembed/?format=json&url=", url)
  357. );
  358. break;
  359. case "twitch" :
  360. if(/[?&](channel|video)=([^&]+)/i.test(a.search)) {args = RegExp.$1; id = RegExp.$2;}
  361. else if(/[?&](stream=.+&channelId)=([^&]+)/i.test(a.search)) {args = RegExp.$1; id = RegExp.$2;}
  362. else if(/\/(.+)\/embed/i.test(a.pathname)) {args = "channel"; id = RegExp.$1;}
  363. if(!id || (settings[0] && a.search.includes("autoplay=true"))) return;
  364. createHtml(
  365. url = "https://www.twitch.tv/"+(args=="video" ? id.replace("v","c/v/") : args=="channel" ? id :
  366. args.replace("stream=", "streams/").replace("&channelId", "/channel/")+id),
  367. src = "https://player.twitch.tv/?autoplay=true&"+args+"="+id+"&parent="+location.hostname,
  368. "https://api.twitch.tv/kraken/{api}?client_id=du8sn5luinquldpeh4e2hy8le87fdo&api_version=5",
  369. args=="channel" ? "url(https://static-cdn.jtvnw.net/previews-ttv/live_user_"+id+"-0x0.jpg)" : null
  370. );
  371. break;
  372. case "ustream" :
  373. if(/(?:\/embed)?\/(channel\/|recorded\/)?([^&]+)/i.test(a.pathname)) {args = RegExp.$1 || "channel/"; id = RegExp.$2;}
  374. if(!id || (settings[0] && a.search.includes("autoplay=1"))) return;
  375. createHtml(
  376. url = "https://www.ustream.tv/"+args+id,
  377. src = "https://www.ustream.tv/embed/"+(args=="channel/" ? "" : args)+id+"?html5ui=1&autoplay=1",
  378. createJOembed("https://www.ustream.tv/oembed?format=json&url=", url),
  379. args=="channel/" && !isNaN(id) ? "url(https://static-cdn1.ustream.tv/i/channel/live/1_"+id+",640x360,b:0.jpg)" : null
  380. );
  381. break;
  382. case "coub" :
  383. if(/\/embed\/([^&]+)/i.test(a.pathname)) id = RegExp.$1;
  384. if(!id || (settings[0] && a.search.includes("autostart=true"))) return;
  385. createHtml(
  386. url = "https://coub.com/view/"+id,
  387. src = "https://coub.com/embed/"+id+"?startWithHD=true&autostart=true",
  388. createJOembed("https://coub.com/api/oembed.json?url=", url)
  389. );
  390. break;
  391. case "vine" :
  392. if(/\/v\/([^&]+)\/embed\/([^&]+)/i.test(a.pathname)) {args = RegExp.$2; id = RegExp.$1;}
  393. if(!id) return;
  394. createHtml(
  395. url = "https://vine.co/v/"+id,
  396. src = "https://vine.co/v/"+id+"/embed/"+args+"?audio=1",
  397. createOembed("https://vine.co/oembed.json?url=", url)
  398. );
  399. break;
  400. case "facebook" :
  401. if(a.pathname.endsWith("/plugins/video.php") && /[?&]href=([^&]+)/i.test(a.search)) {
  402. url = location.protocol+decodeURIComponent(RegExp.$1).replace(/^[a-z]+:/i, '');
  403. if(/\/videos.*?\/(\d+)/i.test(url)) id = RegExp.$1;
  404. }
  405. if(!id || (settings[0] && a.search.includes("autoplay=1"))) return;
  406. createHtml(
  407. url,
  408. src = "https://www.facebook.com/plugins/video.php?autoplay=1&href="+encodeURIComponent(url),
  409. createOembed("https://www.facebook.com/plugins/video/oembed.json/?url=", url),
  410. "url(https://graph.facebook.com/"+id+"/picture)"
  411. );
  412. break;
  413. default :
  414. return;
  415. }
  416. if(elem.tagName != "IFRAME") {
  417. if(elem.parentNode.tagName == "OBJECT")
  418. elem = elem.parentNode;
  419. var iframe = document.createElement("IFRAME");
  420. iframe.src = src;
  421. iframe.id = elem.id;
  422. iframe.name = elem.name;
  423. iframe.className = elem.className;
  424. iframe.style.cssText = elem.style.cssText;
  425. iframe.width = elem.width;
  426. iframe.height = elem.height;
  427. iframe.frameBorder = elem.border;
  428. iframe.align = elem.align;
  429. elem.parentNode.replaceChild(iframe, elem);
  430. elem = iframe;
  431. }
  432. elem.dataset.zeusLEV = 2;
  433. elem.allowFullscreen = true;
  434. elem.srcdoc = html.join("");
  435. iframes.push(elem);
  436. setTimeout(function() {
  437. if(elem.dataset.zeusLEV != 3)
  438. elem.removeAttribute("srcdoc");
  439. }, 5000);
  440. };
  441.  
  442. var observer, animation;
  443. var update = function() {
  444. if(!document.body) {
  445. animation = requestAnimationFrame(update);
  446. } else if(!observer) {
  447. observer = new MutationObserver(function() { if(!animation) animation = requestAnimationFrame(update); });
  448. observer.observe(document.body, {childList: true, attributes: false, characterData: false, subtree: true});
  449. animation = requestAnimationFrame(update);
  450. } else {
  451. var nodes = document.querySelectorAll(settings[1] ? "IFRAME, EMBED, OBJECT" : "IFRAME");
  452. for(var i = 0; i < nodes.length; i++)
  453. createLazyVideo(nodes[i]);
  454. animation = null;
  455. }
  456. };
  457. update();
  458. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址