Embedded Youtube Video Full HD and No Annotations

Auto selects the highest resolution on all Youtube Videos AND embedded youtube videos on ALL webpages!

  1. // ==UserScript==
  2. // @name Embedded Youtube Video Full HD and No Annotations
  3. // @version 3.2
  4. // @namespace http://userscripts.org/users/zackton
  5. // @include *
  6. // @run-at document-start
  7. // @grant none
  8. // @description Auto selects the highest resolution on all Youtube Videos AND embedded youtube videos on ALL webpages!
  9. // ==/UserScript==
  10.  
  11. //Change the default quality to what you would prefer.
  12. //"small","medium","large","hd720","hd1080","highres" <-- change to one of these
  13. // 240p 360p 480p 720p 1080p 1440p and above (highest quality)
  14.  
  15. var defaultQuality = "hd1080";
  16.  
  17. defaultQuality = verifyDefaultQuality(defaultQuality);
  18.  
  19. //console.log(window.location.href); //DEBUG
  20.  
  21. //On /v/ or /embed/ pages (loaded directly or via an iframe)
  22. if ((/^(https?\:\/\/(www\.)?youtube(-nocookie)?.com\/(v|embed|e)\/[a-zA-Z0-9+\-\_]{11})/).test(window.location.href)){
  23. document.addEventListener('DOMContentLoaded', function(){
  24. //console.log("embed"); //DEBUG
  25. var interval = setInterval(function(){
  26. var player = document.getElementById("player").childNodes[0];
  27. if (player != undefined){
  28. if(player.nodeName.toLowerCase() != "embed"){
  29. //console.log("html5 embed"); //DEBUG
  30. ensureSetQuality(player);
  31. }
  32. clearInterval(interval);
  33. }
  34. },10);
  35. }, false);
  36. //All the other pages
  37. } else {
  38. // Continue after the page is fully loaded
  39. document.addEventListener('DOMContentLoaded', execOnPageLoad, false);
  40. }
  41.  
  42. function execOnPageLoad(){
  43. //console.log("execOnPageLoad"); // DEBUG
  44. if ((/^(https?\:\/\/(www\.)?youtube.com\/(watch|user\/|channel\/))/).test(window.location.href)){
  45. //console.log("watch"); //DEBUG
  46. if (document.getElementById("gm-YAPiHQ") == null){
  47. var scr = document.createElement("script");
  48. scr.id = "gm-YAPiHQ";
  49. scr.innerHTML =
  50. ["var tag = document.createElement('script');",
  51. "tag.src = '//www.youtube.com/iframe_api';",
  52. "var firstScriptTag = document.getElementsByTagName('script')[0];",
  53. "firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);",
  54. "var ytplayer0;",
  55. "function onYouTubePlayerReady(playerId){",
  56. //" console.log('onReady1');", //DEBUG
  57. " ytplayer0 = window.top.document.getElementById('movie_player') || window.top.document.getElementById('movie_player-html5') || window.top.document.getElementById('movie_player-flash') || window.top.document.getElementById('video-player-flash') || window.top.document.getElementById('video-player');",
  58. " ytplayer0.setPlaybackQuality('" + defaultQuality + "');",
  59. " waitSetHQ();",
  60. "};",
  61. "function ytPlayerOnYouTubePlayerReady(playerId){",
  62. //" console.log('onReady2');", //DEBUG
  63. " ytplayer0 = window.top.document.getElementById('movie_player') || window.top.document.getElementById('movie_player-html5') || window.top.document.getElementById('movie_player-flash') || window.top.document.getElementById('video-player-flash') || window.top.document.getElementById('video-player');",
  64. " ytplayer0.setPlaybackQuality('" + defaultQuality + "');",
  65. " waitSetHQ();",
  66. "};",
  67. "var c;",
  68. "function waitSetHQ(wStart){",
  69. //" console.log('WSHQ');", //DEBUG
  70. " if (wStart==undefined)",
  71. " wStart = new Date();",
  72. " ytplayer0 = window.top.document.getElementById('movie_player') || window.top.document.getElementById('movie_player-html5') || window.top.document.getElementById('movie_player-flash') || window.top.document.getElementById('video-player-flash') || window.top.document.getElementById('video-player');",
  73. " ytplayer0.setPlaybackQuality('" + defaultQuality + "');",
  74. " if (c==undefined){",
  75. //" console.log(c);", //DEBUG
  76. " c='" + defaultQuality + "';",
  77. " var q = ['small','medium','large','hd720','hd1080','highres'];",
  78. " var avq = ytplayer0.getAvailableQualityLevels();",
  79. " for (var i=q.lastIndexOf('" + defaultQuality + "');i>=0;--i){",
  80. " if (avq.lastIndexOf(q[i]) >= 0){",
  81. " c=q[i];",
  82. " break;",
  83. " }",
  84. " }",
  85. " }",
  86. " if (c==ytplayer0.getPlaybackQuality()){",
  87. //" console.log(c+' '+ytplayer0.getPlaybackQuality());", //DEBUG
  88. " c=undefined;",
  89. " return;",
  90. " } else if ((new Date())-wStart<10000)",
  91. " setTimeout(function(){waitSetHQ(wStart)},10);",
  92. "}",
  93. ].join('\n');
  94. //console.log(scr.innerHTML); // DEBUG
  95. document.getElementsByTagName("body")[0].appendChild(scr);
  96. }
  97. var target = document.getElementById("player");
  98. var observer;
  99. try {
  100. observer = new MutationObserver(waitSetHQ); //Firefox (Gecko)
  101. } catch (e){
  102. observer = new WebKitMutationObserver(waitSetHQ); //Chrome (WebKit)
  103. }
  104. var config = { attributes: true, childList: false, characterData: true, subtree: false };
  105. observer.observe(target, config); // register observer
  106. } else if ((/^(https?\:\/\/(www\.)?youtube.com\/channels)/).test(window.location.href)){
  107. var target = document.body;
  108. var observer;
  109. try {
  110. observer = new MutationObserver(onChannelsMutation); //Firefox (Gecko)
  111. } catch (e){
  112. observer = new WebKitMutationObserver(onChannelsMutation); //Chrome (WebKit)
  113. }
  114. var config = { attributes: true, childList: true, characterData: true, subtree: true };
  115. observer.observe(target, config);
  116. //Everywhere else
  117. } else {
  118. searchAndReplace(); // Look for embedded videos
  119. // Keep watching for changes in page content, pass changed/inserted nodes to searchAndReplace()
  120. // https://developer.mozilla.org/en-US/docs/DOM/MutationObserver
  121. var target = document.body;
  122. var observer;
  123. try {
  124. observer = new MutationObserver(onMutation); //Firefox (Gecko)
  125. } catch (e){
  126. observer = new WebKitMutationObserver(onMutation); //Chrome (WebKit)
  127. }
  128. var config = { attributes: true, childList: true, characterData: true, subtree: true };
  129. observer.observe(target, config); // register observer
  130. }
  131. }
  132.  
  133. //Caller must make sure that videoObj.setPlaybackQuality will be defined at some point,
  134. // if not, the function will keep calling itself every 100ms on videoObj until the 10s timeout.
  135. function ensureSetQuality(videoObj,highestAQ,firstCalledAt){
  136. //console.log("ensureSetQuality()" + firstCalledAt); //DEBUG
  137. if (firstCalledAt==undefined)
  138. firstCalledAt = new Date();
  139. else if ((new Date()-firstCalledAt) > 10000)
  140. return;
  141. if (typeof(videoObj.setPlaybackQuality) == "function"){
  142. videoObj.setPlaybackQuality(defaultQuality);
  143. if (videoObj.getPlayerState() == 1 || videoObj.getPlayerState() == 3)
  144. videoObj.playVideo(); // to avoid reload glitch after pausing/starting again
  145. //Store the defaultQuality or the next highest available quality in highestAQ
  146. if (highestAQ==undefined){
  147. var q = ["small","medium","large","hd720","hd1080","highres"];
  148. for (var i=q.lastIndexOf(defaultQuality);i>=0;--i){
  149. if ((videoObj.getAvailableQualityLevels()).lastIndexOf(q[i]) >= 0){
  150. highestAQ=q[i];
  151. break;
  152. }
  153. }
  154. }
  155. if (videoObj.getPlaybackQuality() != highestAQ){
  156. setTimeout(function(){ensureSetQuality(videoObj,highestAQ,firstCalledAt)},100)
  157. }
  158. } else
  159. setTimeout(function(){ensureSetQuality(videoObj,highestAQ,firstCalledAt)},100);
  160. }
  161.  
  162. function onChannelsMutation(mutations){
  163. mutations.forEach(function(mutation) {
  164. if (mutation.type === "attributes"){
  165. if (mutation.target.nodeName.toLowerCase() == "embed"){
  166. if (typeof(mutation.target.setPlaybackQuality == "function")){
  167. //console.log("attr hit"); //DEBUG
  168. ensureSetQuality(ensureSetQuality);
  169. }
  170. }
  171. } else if (mutation.type === "childList"){
  172. for (var i=0;i<mutation.addedNodes.length;++i)
  173. if (mutation.addedNodes[i].nodeName.toLowerCase() == "embed"){
  174. if (typeof(mutation.addedNodes[i].setPlaybackQuality == "function")){
  175. //console.log("added hit"); //DEBUG
  176. ensureSetQuality(mutation.addedNodes[i]);
  177. }
  178. }
  179. }
  180. });
  181. }
  182.  
  183. function onMutation(mutations){
  184. var significantNodes = [];
  185. mutations.forEach(function(mutation) {
  186. //console.log(mutation.type); // DEBUG
  187. if (mutation.type === "attributes"){
  188. significantNodes[significantNodes.length] = mutation.target;
  189. } else if (mutation.type === "childList"){
  190. //console.log("onMutation: childList"); //DEBUG
  191. for (var i=0;i<mutation.addedNodes.length;++i)
  192. significantNodes[significantNodes.length] = mutation.addedNodes[i];
  193. }
  194. });
  195. //console.log("significantNodes length: " + significantNodes.length); // DEBUG
  196. if (significantNodes.length>0)
  197. searchAndReplace(significantNodes);
  198. }
  199.  
  200. function recAddToArr(obj,array){
  201. array.push(obj);
  202. }
  203.  
  204. function onMutation(mutations){
  205. var significantNodes = [];
  206. mutations.forEach(function(mutation) {
  207. //console.log(mutation.type); // DEBUG
  208. if (mutation.type === "attributes"){
  209. significantNodes[significantNodes.length] = mutation.target;
  210. } else if (mutation.type === "childList"){
  211. //console.log("onMutation: childList"); //DEBUG
  212. for (var i=0;i<mutation.addedNodes.length;++i)
  213. significantNodes[significantNodes.length] = mutation.addedNodes[i];
  214. }
  215. });
  216. //console.log("significantNodes length: " + significantNodes.length); // DEBUG
  217. if (significantNodes.length>0)
  218. searchAndReplace(significantNodes);
  219. }
  220.  
  221. function searchAndReplace(pNodes){
  222. // console.log("searchAndReplace()"); //DEBUG
  223. if (typeof pNodes == "object") //if searchAndReplace() was called because the page content changed and the function received the changed nodes
  224. {
  225. // console.log("searchAndReplace(pNodes) : " + pNodes.length); // DEBUG
  226. for (var i=0;i<pNodes.length;++i){
  227. // console.log(pNodes[i].nodeName.toLowerCase());
  228. // console.log(pNodes[i].getElementsByTagName("object").length); //DEBUG
  229. if ((/^embed$/i).test(pNodes[i].nodeName)){
  230. // console.log("embed mutation"); //DEBUG
  231. var embedSrc = pNodes[i].getAttribute("src");
  232. if (!embedSrc)
  233. continue;
  234. // console.log("embedSrc: " + embedSrc); //DEBUG
  235. var replaceUrl = replaceSrc(embedSrc);
  236. if (embedSrc != replaceUrl)
  237. pNodes[i].setAttribute("src",replaceUrl);
  238. } else if ((/^iframe$/i).test(pNodes[i].nodeName)){
  239. // console.log("iframe mutation"); //DEBUG
  240. var iframeSrc = pNodes[i].getAttribute("src");
  241. if (!iframeSrc)
  242. continue;
  243. // console.log("iframeSrc: " + iframeSrc); //DEBUG
  244. var replaceUrl = replaceSrc(iframeSrc);
  245. if (iframeSrc != replaceUrl)
  246. pNodes[i].setAttribute("src",replaceUrl);
  247. } else if ((/^object$/i).test(pNodes[i].nodeName)){
  248. var objectData = pNodes[i].getAttribute("data");
  249. if (!objectData)
  250. continue;
  251. // console.log("objectData: " + objectData); //DEBUG
  252. var replaceUrl = replaceSrc(objectData);
  253. if (objectData != replaceUrl)
  254. pNodes[i].setAttribute("data",replaceUrl);
  255. var objectChildren = pNodes[i].getElementsByTagName("param");
  256. for (var j=0;j<objectChildren.length;++j){
  257. if (objectChildren[j].getAttribute("name") != "movie")
  258. continue;
  259. var paramMovie = objectChildren[j].getAttribute("value");
  260. if (paramMovie){
  261. // console.log("paramMovie: " + paramMovie); //DEBUG
  262. var replaceUrl = replaceSrc(paramMovie);
  263. if (paramMovie != replaceUrl)
  264. objectChildren[j].setAttribute("movie",replaceUrl);
  265. } // if
  266. } // for j
  267. } // else if
  268. } // for i
  269. } else {
  270. //console.log("searchAndReplace()"); // DEBUG
  271.  
  272. var lElems = new Array();
  273. lElems["object"] = "data";
  274. lElems["embed"] = "src";
  275. lElems["param"] = "value";
  276. lElems["iframe"] = "src";
  277.  
  278. for (var cTag in lElems){
  279. var cParam = lElems[cTag];
  280. var tagArr = document.getElementsByTagName(cTag);
  281. for (var i=0;i<tagArr.length;++i){
  282. var tagParam = tagArr[i].getAttribute(cParam);
  283. if (!tagParam
  284. || (cTag == "param" && tagArr[i].getAttribute("name") != "movie"))
  285. continue;
  286. var replaceUrl = replaceSrc(tagParam);
  287. if (tagParam != replaceUrl)
  288. tagArr[i].setAttribute(cParam,replaceUrl);
  289. } // for i
  290. } //for key
  291. } // else
  292. }
  293.  
  294. function replaceSrc(src){
  295. if ((/^(https?\:\/\/(www\.)?youtube(-nocookie)?\.com\/(v|e|embed)\/[a-zA-Z0-9+\-\_]{11})/).test(src)){
  296. //insert / modify vq parameter
  297. if ((new RegExp("(\\?|\\&)vq=[^#^&]*(\\#|\\&)?")).test(src))
  298. src = src.replace(new RegExp("(\\?|\\&)vq=[^#^&]*(\\#|\\&)?"),"$1vq=" +defaultQuality+ "$2");
  299. else
  300. src = src.replace(/^(https?\:\/\/(www\.)?youtube(-nocookie)?\.com\/(v|e|embed)\/[a-zA-Z0-9+\-\_]{11})\??/,"$1?vq=" +defaultQuality+ "&iv_load_policy=3&");
  301. //insert / modify enablejsapi parameter (set its value to 1)
  302. if ((new RegExp("(\\?|\\&)enablejsapi=[^#^&]*(\\#|\\&)?")).test(src))
  303. src = src.replace(new RegExp("(\\?|\\&)enablejsapi=[^#^&]*(\\#|\\&)?"),"$1enablejsapi=1$2");
  304. else
  305. src = src.replace(/^(https?\:\/\/(www\.)?youtube(-nocookie)?\.com\/(v|e|embed)\/[a-zA-Z0-9+\-\_]{11})\??/,"$1?enablejsapi=1&");
  306. }
  307. return src;
  308. }
  309.  
  310. function verifyDefaultQuality(quality){
  311. if (["small","medium","large","hd720","hd1080","highres"].indexOf(quality) < 0)
  312. return "hd1080";
  313. return quality;
  314. }

QingJ © 2025

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