停用 YouTube AV1

停用 YouTube 的 AV1 视频播放

  1. // ==UserScript==
  2. // @name Disable YouTube AV1
  3. // @description Disable AV1 for video playback on YouTube
  4. // @name:zh-TW 停用 YouTube AV1
  5. // @description:zh-TW 停用 YouTube 的 AV1 影片播放
  6. // @name:zh-HK 停用 YouTube AV1
  7. // @description:zh-HK 停用 YouTube 的 AV1 影片播放
  8. // @name:zh-CN 停用 YouTube AV1
  9. // @description:zh-CN 停用 YouTube 的 AV1 视频播放
  10. // @name:ja YouTube AV1 停用
  11. // @description:ja YouTube の動画再生に AV1 を停用する
  12. // @name:ko YouTube AV1 비활성화
  13. // @description:ko YouTube의 동영상 재생에 AV1을 비활성화하기
  14. // @name:vi Vô hiệu hóa YouTube AV1
  15. // @description:vi Vô hiệu hóa AV1 để phát video trên YouTube
  16. // @name:de YouTube AV1 deaktivieren
  17. // @description:de Deaktiviert AV1 für die Videowiedergabe auf YouTube
  18. // @name:fr Désactiver YouTube AV1
  19. // @description:fr Désactivez AV1 pour la lecture des vidéos sur YouTube
  20. // @name:it Disabilita YouTube AV1
  21. // @description:it Disabilita AV1 per la riproduzione dei video su YouTube
  22. // @name:es Desactivar AV1 en YouTube
  23. // @description:es Desactivar AV1 para la reproducción de videos en YouTube
  24. // @namespace http://tampermonkey.net/
  25. // @version 2.4.5
  26. // @author CY Fung
  27. // @match https://www.youtube.com/*
  28. // @match https://www.youtube.com/embed/*
  29. // @match https://www.youtube-nocookie.com/embed/*
  30. // @match https://m.youtube.com/*
  31. // @exclude https://www.youtube.com/live_chat*
  32. // @exclude https://www.youtube.com/live_chat_replay*
  33. // @exclude /^https?://\S+\.(txt|png|jpg|jpeg|gif|xml|svg|manifest|log|ini)[^\/]*$/
  34. // @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com
  35. // @grant none
  36. // @run-at document-start
  37. // @license MIT
  38. // @compatible chrome
  39. // @compatible firefox
  40. // @compatible opera
  41. // @compatible edge
  42. // @compatible safari
  43. // @unwrap
  44. // @allFrames true
  45. // @inject-into page
  46. // ==/UserScript==
  47.  
  48. (function () {
  49. 'use strict';
  50.  
  51. console.debug("disable-youtube-av1", "injected");
  52.  
  53. const supportedFormatsConfig = () => {
  54.  
  55. function typeTest(type) {
  56.  
  57. if (typeof type === 'string' && type.startsWith('video/')) {
  58. if (type.includes('av01')) {
  59. if (/codecs[\x20-\x7F]+\bav01\b/.test(type)) return false;
  60. } else if (type.includes('av1')) {
  61. if (/codecs[\x20-\x7F]+\bav1\b/.test(type)) return false;
  62. }
  63. }
  64.  
  65. }
  66.  
  67. // return a custom MIME type checker that can defer to the original function
  68. function makeModifiedTypeChecker(origChecker, dx) {
  69. // Check if a video type is allowed
  70. return function (type) {
  71. let res = undefined;
  72. if (type === undefined) res = false;
  73. else res = typeTest(type);
  74. if (res === undefined) res = origChecker.apply(this, arguments);
  75. else res = !dx ? res : (res ? "probably" : "");
  76.  
  77. // console.debug(20, type, res)
  78.  
  79. return res;
  80. };
  81. }
  82.  
  83. // Override video element canPlayType() function
  84. const proto = (HTMLVideoElement || 0).prototype;
  85. if (proto && typeof proto.canPlayType == 'function') {
  86. proto.canPlayType = makeModifiedTypeChecker(proto.canPlayType, true);
  87. }
  88.  
  89. // Override media source extension isTypeSupported() function
  90. const mse = window.MediaSource;
  91. // Check for MSE support before use
  92. if (mse && typeof mse.isTypeSupported == 'function') {
  93. mse.isTypeSupported = makeModifiedTypeChecker(mse.isTypeSupported);
  94. }
  95.  
  96. };
  97.  
  98. function disableAV1() {
  99.  
  100. // This is the setting to disable AV1 [ 480p (or below) - AV1, above 480p - VP9 ]
  101. // localStorage['yt-player-av1-pref'] = '480';
  102. try {
  103. Object.defineProperty(localStorage.constructor.prototype, 'yt-player-av1-pref', {
  104. get() {
  105. if (this === localStorage) return '480';
  106. return this.getItem('yt-player-av1-pref');
  107. },
  108. set(nv) {
  109. this.setItem('yt-player-av1-pref', nv);
  110. return true;
  111. },
  112. enumerable: true,
  113. configurable: true
  114. });
  115. } catch (e) {
  116. // localStorage['yt-player-av1-pref'] = '480';
  117. }
  118.  
  119. if (localStorage['yt-player-av1-pref'] !== '480') {
  120.  
  121. console.warn('disable-youtube-av1', '"yt-player-av1-pref = 480" is not supported in your browser.');
  122. return;
  123. }
  124.  
  125. console.debug("disable-youtube-av1", "AV1 disabled by yt-player-av1-pref = 480");
  126.  
  127. }
  128.  
  129. disableAV1();
  130.  
  131. supportedFormatsConfig();
  132.  
  133. })();