YouTube.com quality change buttons (Mobile / Desktop)

Adds quality change buttons below the video (144p, 240p, 360p, 480p, 720p, 1080p...) works on mobile (m.youtube.com) and on desktop.

  1. // ==UserScript==
  2. // @name YouTube.com quality change buttons (Mobile / Desktop)
  3. // @namespace m-youtube-com-quality-change-buttons
  4. // @version 1.14
  5. // @description Adds quality change buttons below the video (144p, 240p, 360p, 480p, 720p, 1080p...) works on mobile (m.youtube.com) and on desktop.
  6. // @author hlorand.hu
  7. // @match https://m.youtube.com/watch*
  8. // @match https://youtube.com/watch*
  9. // @match https://*.youtube.com/watch*
  10. // @icon https://www.google.com/s2/favicons?sz=64&domain=tampermonkey.net
  11. // @grant none
  12. // @license https://creativecommons.org/licenses/by-nc-sa/4.0/
  13. // @run-at document-idle
  14. // ==/UserScript==
  15.  
  16. // Screenshot: https://ibb.co/pyXQd4C
  17.  
  18. (function() {
  19. //'use strict';
  20.  
  21. function addbuttons(){
  22. document.getElementById("qualitybuttons").innerText = "";
  23.  
  24. var player = document.getElementById('movie_player');
  25.  
  26. // it is neccesary to start the video, to getAvailableQualityData
  27. if( document.location.href.includes("m.youtube.com") ){
  28. player.click(); // start video
  29. player.click(); // pause video
  30. }
  31.  
  32. const qualities = player.getAvailableQualityData();
  33.  
  34. qualities.forEach((q)=>{
  35.  
  36. let button = document.createElement('button');
  37. button.setAttribute("quality", q.quality);
  38. button.textContent = q.qualityLabel.replace("p50","p").replace("p60","p"); // remove fps from label
  39. button.className = "qualitybutton";
  40.  
  41. button.style.margin = "4px";
  42. button.style.padding = "4px";
  43. button.style.position = "relative";
  44.  
  45. // get current quality
  46. if( player.getPlaybackQualityLabel() == q.qualityLabel ){
  47. button.style.backgroundColor = "darkorange";
  48. } else{
  49. button.style.backgroundColor = "green";
  50. }
  51.  
  52. button.onclick = function() {
  53. player.setPlaybackQualityRange( this.getAttribute("quality") );
  54.  
  55. // highlight the clicked button and desaturate the others
  56. document.querySelectorAll(".qualitybutton").forEach((btn)=>{
  57. btn.style.backgroundColor = "green";
  58. });
  59. this.style.backgroundColor = "darkorange";
  60. };
  61.  
  62. let target = document.getElementById('qualitybuttons');
  63. target.insertBefore(button, target.firstChild);
  64.  
  65. }); // end qualities foreach
  66.  
  67. } // end addbuttons
  68.  
  69.  
  70. // Periodically check if the buttons are visible (sometimes YouTube redraws its interface).
  71. setInterval(()=>{
  72.  
  73. // Creating a div that will contain buttons.
  74. if( document.getElementById("qualitybuttons") == undefined ){
  75.  
  76. // placement of buttons on desktop
  77. let parent = document.getElementById('above-the-fold');
  78.  
  79. // placement of buttons on tablet
  80. if( !parent ){
  81. parent = document.querySelector('.watch-below-the-player');
  82. }
  83.  
  84. // placement of buttons on mobile
  85. if( !parent ){
  86. parent = document.querySelector('.related-chips-slot-wrapper');
  87. }
  88.  
  89. let wrapper = document.createElement('div');
  90. wrapper.setAttribute("id","qualitybuttons");
  91. parent.insertBefore(wrapper, parent.firstChild);
  92. addbuttons();
  93.  
  94. }
  95.  
  96. // Sometimes the buttons are not added, so I check and add them if necessary.
  97. if( document.getElementById("qualitybuttons").textContent.trim() === '' ){
  98. addbuttons();
  99. }
  100. }, 1000);
  101.  
  102. })();