Youtube Repeat button

Youtube動画プレイヤーにリピートボタンをつける(html5プレイヤーのみ動作)

目前為 2015-11-16 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name Youtube Repeat button
  3. // @namespace
  4. // @version 0.1.2
  5. // @description Youtube動画プレイヤーにリピートボタンをつける(html5プレイヤーのみ動作)
  6. // @author Nobby
  7. // @match https://www.youtube.com/watch*
  8. // @grant GM_setValue
  9. // @grant GM_getValue
  10. // ==/UserScript==
  11.  
  12. (function(){
  13. var player = document.getElementById('movie_player');
  14. var video = document.querySelector('video');
  15. var repeat = GM_getValue('rpt',false);
  16. var control = document.getElementsByClassName('ytp-chrome-controls')[0];
  17. var yrb = document.createElement('button');
  18. var title = 'リピート';
  19. yrb.setAttribute('class', 'ytp-button ytp-repeat-button');
  20. yrb.setAttribute('style', 'float:right;');
  21.  
  22. var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
  23. svg.setAttribute('width', '100%');
  24. svg.setAttribute('height', '100%');
  25. svg.setAttribute('viewBox', '-128 -128 768 768');
  26. svg.setAttribute('version', '1.1');
  27. svg.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
  28. svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
  29.  
  30. var defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
  31.  
  32. var from = 'M363 363v0h0v0h0v0l0-0 0-0v0h0zM149 149v0h0v0h0v0l0 0-0 0v0h0zM469 256l-85 85v-64H64v-42h320v-64l85 85z';
  33. var to = 'M363 363v-86h42v128H149v64l-85-85 85-85v64h214zM149 149v86h-42V107h256V43l85 85-85 85v-64H149zM256 256l-0 0v-0H256v-0h0v-0l0 0z';
  34.  
  35. if(repeat){
  36. from = [to, to = from][0];
  37. video.setAttribute('loop', '');
  38. title = 'リピート解除';
  39. }
  40. yrb.setAttribute('title', title);
  41.  
  42. var path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
  43. path.setAttribute('id', 'ytp-repeat');
  44. path.setAttribute('d', from);
  45.  
  46. var animate = document.createElementNS('http://www.w3.org/2000/svg', 'animate');
  47. animate.setAttribute('attributeType', 'XML');
  48. animate.setAttribute('attributeName', 'd');
  49. animate.setAttribute('fill', 'freeze');
  50. animate.setAttribute('dur', '0.2s');
  51. animate.setAttribute('keySplines', '.4 0 1 1');
  52. animate.setAttribute('repeatCount', '1');
  53. animate.setAttribute('begin', 'indefinite');
  54.  
  55. var use1 = document.createElementNS('http://www.w3.org/2000/svg', 'use');
  56. use1.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#ytp-repeat');
  57. use1.setAttribute('class', 'ytp-svg-shadow');
  58.  
  59. var use2 = document.createElementNS('http://www.w3.org/2000/svg', 'use');
  60. use2.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#ytp-repeat');
  61. use2.setAttribute('class', 'ytp-svg-fill');
  62.  
  63. path.appendChild(animate);
  64. defs.appendChild(path);
  65. svg.appendChild(defs);
  66. svg.appendChild(use1);
  67. svg.appendChild(use2);
  68. yrb.appendChild(svg);
  69.  
  70. control.appendChild(yrb);
  71.  
  72. var tooltext = document.getElementsByClassName('ytp-tooltip-text')[0];
  73. var tooltip = tooltext.parentNode.parentNode;
  74. var delay = null;
  75. yrb.addEventListener('mouseover', function(){
  76. yrb.removeAttribute('title');
  77. tooltip.setAttribute('aria-hidden', 'true');
  78. tooltip.setAttribute('class', 'ytp-tooltip ytp-bottom');
  79. delay = setTimeout(function() {
  80. tooltip.style.display = '';
  81. tooltext.textContent = title;
  82. var parentRect = player.getBoundingClientRect();
  83. var childRect = yrb.getBoundingClientRect();
  84. var tipRect = tooltip.getBoundingClientRect();
  85. var x_left = childRect.left - parentRect.left + (childRect.width - tipRect.width)/2;
  86. tooltip.setAttribute('style', 'left:'+x_left+'px');
  87. tooltip.removeAttribute('aria-hidden');
  88. }, 500);
  89. }, false);
  90. yrb.addEventListener('mouseleave', function(){
  91. clearTimeout(delay);
  92. tooltip.style.display = 'none';
  93. tooltip.setAttribute('aria-hidden', 'true');
  94. yrb.setAttribute('title', title);
  95. }, false);
  96. yrb.addEventListener('click', function(){
  97. if(repeat){
  98. video.removeAttribute('loop');
  99. title = 'リピート';
  100. }else{
  101. video.setAttribute('loop', '');
  102. title = 'リピート解除';
  103. }
  104. repeat = !repeat;
  105. tooltext.textContent = title;
  106. var parentRect = player.getBoundingClientRect();
  107. var childRect = yrb.getBoundingClientRect();
  108. var tipRect = tooltip.getBoundingClientRect();
  109. var x_left = childRect.left - parentRect.left + (childRect.width - tipRect.width)/2;
  110. tooltip.setAttribute('style', 'left:'+x_left+'px');
  111. setTimeout(function() {
  112. animate.setAttribute('from', from);
  113. animate.setAttribute('to', to);
  114. animate.beginElement();
  115. path.setAttribute('d', from);
  116. from = [to, to = from][0];
  117. }, 50);
  118. }, false);
  119. window.onbeforeunload = function(){
  120. GM_setValue('rpt',repeat);
  121. };
  122. })();