click_to_play@youtube

disable autoplay and unload player

  1. // ==UserScript==
  2. // @name click_to_play@youtube
  3. // @namespace click_to_play@youtube
  4. // @namespace https://greasyfork.org/ja/scripts/9886
  5. // @homepageURL https://greasyfork.org/ja/scripts/9886
  6. // @license http://creativecommons.org/licenses/by-nc-sa/4.0/
  7. // @description disable autoplay and unload player
  8. // @include http://*
  9. // @include https://*
  10. // @exclude https://www.youtube.com/*
  11. // @author noi
  12. // @version 1.10
  13. // @grant GM_log
  14. // ==/UserScript==
  15.  
  16.  
  17. /**************************************************************
  18. [about]
  19. Stop youtube video autoplay, and unload the players.
  20. It will display a thumbnail image instead.
  21.  
  22. youtubeの埋め込み動画を読みこまないように変更し、
  23. 代わりにサムネイル画像を表示します。
  24.  
  25. Firefoxのプラグイン「click-to-play」はHTML5をブロックしないので、
  26. スクリプトを作成。
  27.  
  28. ****************************
  29. References
  30.  
  31. No Embed Youtube @author eight
  32. https://greasyfork.org/ja/scripts/1590
  33.  
  34. ****************************
  35. history
  36.  
  37. 06/19/2016 - v1.10 一部微調整
  38. 06/18/2016 - v1.09 同一ページに複数動画がある場合の指定ミス修正
  39. 06/16/2016 - v1.08 サイト側のcssにより動画の位置ずれが生じる場合に対応
  40. 07/03/2015 - v1.07 動画iframeの取得エラー時の動作修正
  41. 06/07/2015 - v1.06 起動にディレイ追加
  42. 05/17/2015 - v1.04 DOM操作削減
  43. 05/15/2015 - v1.03 サムネ画像のサイズ修正
  44. 05/15/2015 - v1.02 v1.01のバグ修正
  45. 05/15/2015 - v1.01 再生ボタンを変更
  46. 05/15/2015 - v1.00 release
  47. **************************************************************/
  48.  
  49. "use strict";
  50. var number = 0;
  51.  
  52. var xpath = [
  53. '//iframe[contains(@src,"youtube.com/embed/")]|',
  54. '//iframe[contains(@src,"youtube.com/v/")]|',
  55. '//embed[contains(@src,"youtube.com/v/") and not(ancestor::object)]|',
  56. '//object[./param[contains(@value,"youtube.com/v/")]]',
  57. ].join('');
  58.  
  59. var playButton = '<div style="width:100%;height:100%;background:url(\'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAAA8CAMAAADG+c2+AAAAsVBMVEUAAAD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApKSnOzs47OzsAAAD8/Pytra0aGhqSkpKHh4cDAwPh4eFcXFzGxsYxMTH7+/ukpKQSEhLv7+99fX0CAgLb29tQUFD+/v6+vr7m5ub5+fmbm5sNDQ3r6+tycnLV1dVGRkb///+2trYICAj29vZmZmYhISEAAADz8/MgICDz8/P///91kYKsAAAAOnRSTlOZACQBgkZyiwSRTzGHU1Rko+GoiP3Rn8bCmeyy3aX7zZ30vpnpr/7Z7/rKnPK65av+1Zv4tqEy96H2cK1dPgAAARxJREFUeF7N2OlOwkAUR/E/XZdpi4oLKOAGuIGKu/P+D6aN6YifjOkxmd8DnISktPde9VphUCdRrj/Lo6QKQpdpg1mcqoM0zn4GXwbqqDSbwUKA4jvYF6LfBgtBiq+gEcY0wawUpsw+g7FAcU9hKlAaKhAqUC1UpUSoRJFQkXKRfs1t74hld/f22aC1r8MRGWwcHqHBxngCB+30+AQKOqdn51DQmc3hoL2/2IKCztX1DRR0lisq6NzewUG7WD9DQefx4AEKOpdPeNDnn7xYv/n82CxX9F/P55fDbE6/YH3+BIwnPn9G34cjD0YRcFjCxzl84ORH4kqoCl8r8MWHXs3w5ZFfb/kFnD8R8EeMhinV0cD80yEIOVXVG6eqD/g5Xi0pxQ0LAAAAAElFTkSuQmCC\') no-repeat center center;"></div>';
  60.  
  61. var players = {};
  62.  
  63. var blockEmbed = function(node){
  64.  
  65. var result = document.evaluate(xpath, node, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
  66.  
  67. for(var i=0,j=result.snapshotLength;i<j;i++){
  68. var ele = result.snapshotItem(i);
  69. if(ele.hasAttribute('c2p')) continue;
  70.  
  71. var url = ele.src; //iframe or embed
  72. //object
  73. if(!url){
  74.  
  75. for(var x=0,y=ele.childNodes.length; x<y; x++){
  76. var param = ele.childNodes[x];
  77. if(param.nodeName == "PARAM" && param.getAttribute("name") == "movie"){
  78. url = param.getAttribute("value");
  79. break;
  80. }
  81. }
  82. }
  83. if(!url) continue;
  84.  
  85.  
  86. var parent = ele.parentNode;
  87.  
  88. var id = url.match(/(embed|v)\/(.+?)(\?|&|$)/)[2];
  89. var movieUrl = "https://www.youtube.com/watch?v=" + id;
  90.  
  91. var src = location.protocol + '//img.youtube.com/vi/' + id + '/mqdefault.jpg';
  92. var txt = "";
  93.  
  94.  
  95. var eleW = ele.style.width || ele.width || ele.offsetWidth;
  96. var eleH = ele.style.height || ele.height || ele.offsetHeight;
  97. try{
  98. eleW = eleW.replace(/(px|em)/i,"");
  99. eleH = eleH.replace(/(px|em)/i,"");
  100. }catch(e){}
  101. var tmpId = ele.id;
  102. var tmpClass = ele.className;
  103.  
  104. if(eleH == 0){
  105. eleW = eleH = 100.111;
  106. var tmpNum = number;
  107. txt = 'width:'+ eleW +'px;height:'+ eleH +'px;';
  108. var tmpTxt = txt;
  109.  
  110. ele.onload = function(){
  111. var hei = this.offsetHeight;
  112. var wid = this.offsetWidth;
  113. this.parentNode.removeChild(this);
  114.  
  115. var obj = document.getElementById('c2p_thumbnail' + tmpNum);
  116. obj.height = hei;
  117. obj.width = wid;
  118.  
  119. obj.contentDocument.body.setAttribute("style",obj.contentDocument.body.getAttribute("style").replace(tmpTxt,'width:'+ wid +'px;height:'+ hei +'px;'))
  120. }
  121. }else txt = 'width:'+ eleW +'px;height:'+ eleH +'px;';
  122.  
  123. var thumbnail = document.createElement("iframe");
  124. thumbnail.width = eleW;
  125. thumbnail.height = eleH;
  126.  
  127.  
  128. thumbnail.id = 'c2p_thumbnail' + number;
  129. playButton = '<body style="' + txt + 'background:url(' + src + ') no-repeat center center ; background-size: 100% 100%;" title="click to play!" num="' + number + '"></body>'
  130. + playButton
  131. + '</div>';
  132. thumbnail.srcdoc = playButton;
  133. thumbnail.setAttribute('c2p','thum');
  134. thumbnail.scrolling="no";
  135. thumbnail.frameborder="no";
  136. thumbnail.setAttribute('num',number);
  137.  
  138. thumbnail.onload = function(){
  139. var that = this
  140. var unBlock = function(e){
  141. var thumb = e.target;
  142. if(!thumb.tagName != 'body') thumb = thumb.parentNode;
  143. thumb.removeEventListener('click',unBlock,false);
  144.  
  145. var num = thumb.getAttribute('num');
  146.  
  147. that.parentNode.replaceChild(players[num],that);
  148. delete players[num];
  149. };
  150. this.id = tmpId;
  151. this.className = tmpClass;
  152.  
  153. var contentDocument = this.contentDocument || this.contentWindow.document;
  154. contentDocument.body.addEventListener('click',unBlock,false);
  155.  
  156. };
  157.  
  158. parent.insertBefore(thumbnail,ele);
  159.  
  160. ele.setAttribute('c2p','done')
  161. players[number] = ele;
  162.  
  163. if(eleH != 100.111)parent.removeChild(ele);
  164.  
  165.  
  166. number++;
  167. }
  168. };
  169.  
  170. var observer = new MutationObserver(function(mutations){
  171. for(var i=0,j=mutations.length;i<j;i++){
  172. var m = mutations[i];
  173. if(m.type != "childList") return;
  174.  
  175. for(var x=0,y=m.addedNodes.length;x<y;x++){
  176. blockEmbed(m.addedNodes[x]);
  177. }
  178. }
  179. });
  180. blockEmbed(document.documentElement);
  181. setTimeout(function(){
  182. observer.observe(document.body, {childList: true,subtree: true});
  183. },1000);
  184.  
  185.  
  186. var onEventUnload = function(){
  187. window.removeEventListener("beforeunload", onEventUnload,false);
  188.  
  189. observer.disconnect();
  190. observer = xpath = blockEmbed = null;
  191. };
  192. window.addEventListener('beforeunload',onEventUnload, false);
  193.