使用 YouTube AV1

使用 AV1 进行 YouTube 视频播放

  1. // ==UserScript==
  2. // @name Use YouTube AV1
  3. // @description Use AV1 for video playback on YouTube
  4. // @name:zh-TW 使用 YouTube AV1
  5. // @description:zh-TW 使用 AV1 進行 YouTube 影片播放
  6. // @name:zh-HK 使用 YouTube AV1
  7. // @description:zh-HK 使用 AV1 進行 YouTube 影片播放
  8. // @name:zh-CN 使用 YouTube AV1
  9. // @description:zh-CN 使用 AV1 进行 YouTube 视频播放
  10. // @name:ja YouTube AV1 の使用
  11. // @description:ja YouTube の動画再生に AV1 を使用する
  12. // @name:ko YouTube AV1 사용
  13. // @description:ko YouTube의 동영상 재생에 AV1을 사용하기
  14. // @name:vi Sử dụng YouTube AV1
  15. // @description:vi Sử dụng AV1 để phát video trên YouTube
  16. // @name:de YouTube AV1 verwenden
  17. // @description:de Verwende AV1 für die Videowiedergabe auf YouTube
  18. // @name:fr Utiliser YouTube AV1
  19. // @description:fr Utiliser AV1 pour la lecture des vidéos sur YouTube
  20. // @name:it Usa YouTube AV1
  21. // @description:it Usa AV1 per la riproduzione dei video su YouTube
  22. // @name:es Usar AV1 en YouTube
  23. // @description:es Usar 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. //
  39. // @compatible firefox Violentmonkey
  40. // @compatible firefox Tampermonkey
  41. // @compatible firefox FireMonkey
  42. // @compatible chrome Violentmonkey
  43. // @compatible chrome Tampermonkey
  44. // @compatible opera Violentmonkey
  45. // @compatible opera Tampermonkey
  46. // @compatible safari Stay
  47. // @compatible edge Violentmonkey
  48. // @compatible edge Tampermonkey
  49. // @compatible brave Violentmonkey
  50. // @compatible brave Tampermonkey
  51. //
  52. // @unwrap
  53. // @allFrames true
  54. // @inject-into page
  55. // ==/UserScript==
  56.  
  57.  
  58.  
  59. (function (__Promise__) {
  60. 'use strict';
  61.  
  62. /** @type {globalThis.PromiseConstructor} */
  63. const Promise = (async () => { })().constructor; // YouTube hacks Promise in WaterFox Classic and "Promise.resolve(0)" nevers resolve.
  64.  
  65. console.debug("use-youtube-av1", "injected");
  66.  
  67. const supportedFormatsConfig = () => {
  68.  
  69.  
  70. function typeTest(type) {
  71.  
  72. if (typeof type === 'string' && type.startsWith('video/')) {
  73. if (type.includes('av01')) {
  74. if (/codecs[\x20-\x7F]+\bav01\b/.test(type)) return true;
  75. } else if (type.includes('av1')) {
  76. if (/codecs[\x20-\x7F]+\bav1\b/.test(type)) return true;
  77. }
  78. }
  79.  
  80. }
  81.  
  82. // return a custom MIME type checker that can defer to the original function
  83. function makeModifiedTypeChecker(origChecker, dx) {
  84. // Check if a video type is allowed
  85. return function (type) {
  86. let res = undefined;
  87. if (type === undefined) res = false;
  88. else res = typeTest(type);
  89. if (res === undefined) res = origChecker.apply(this, arguments);
  90. else res = !dx ? res : (res ? "probably" : "");
  91.  
  92. // console.debug(20, type, res)
  93.  
  94. return res;
  95. };
  96. }
  97.  
  98. // Override video element canPlayType() function
  99. const proto = (HTMLVideoElement || 0).prototype;
  100. if (proto && typeof proto.canPlayType == 'function') {
  101. proto.canPlayType = makeModifiedTypeChecker(proto.canPlayType, true);
  102. }
  103.  
  104. // Override media source extension isTypeSupported() function
  105. const mse = window.MediaSource;
  106. // Check for MSE support before use
  107. if (mse && typeof mse.isTypeSupported == 'function') {
  108. mse.isTypeSupported = makeModifiedTypeChecker(mse.isTypeSupported);
  109. }
  110.  
  111. }
  112.  
  113. function enableAV1() {
  114.  
  115. // This is the setting to force AV1
  116. // localStorage['yt-player-av1-pref'] = '8192';
  117. try {
  118. Object.defineProperty(localStorage.constructor.prototype, 'yt-player-av1-pref', {
  119. get() {
  120. if (this === localStorage) return '8192';
  121. return this.getItem('yt-player-av1-pref');
  122. },
  123. set(nv) {
  124. this.setItem('yt-player-av1-pref', nv);
  125. return true;
  126. },
  127. enumerable: true,
  128. configurable: true
  129. });
  130. } catch (e) {
  131. // localStorage['yt-player-av1-pref'] = '8192';
  132. }
  133.  
  134. if (localStorage['yt-player-av1-pref'] !== '8192') {
  135.  
  136. console.warn("use-youtube-av1", 'Use YouTube AV1 is not supported in your browser.');
  137. return;
  138. }
  139.  
  140. console.debug("use-youtube-av1", "AV1 enabled");
  141.  
  142. supportedFormatsConfig();
  143.  
  144. }
  145.  
  146. let promise = null;
  147.  
  148. try {
  149. promise = navigator.mediaCapabilities.decodingInfo({
  150. type: "file",
  151. video: {
  152. contentType: "video/mp4; codecs=av01.0.05M.08.0.110.05.01.06.0",
  153. height: 1080,
  154. width: 1920,
  155. framerate: 30,
  156. bitrate: 2826848,
  157. },
  158. audio: {
  159. contentType: "audio/webm; codecs=opus",
  160. channels: "2.1",
  161. samplerate: 44100,
  162. bitrate: 255236,
  163. }
  164. });
  165. } catch (e) {
  166. promise = null;
  167. }
  168.  
  169. const callback = (result) => {
  170.  
  171. if (result && result.supported && result.smooth) enableAV1();
  172. else {
  173. console.warn("force-youtube-av1", 'Your browser does not support AV1. You might conside to use the latest version of Google Chrome or Mozilla FireFox.');
  174. }
  175. };
  176.  
  177. (promise || Promise.resolve(0)).catch(callback).then(callback);
  178.  
  179. })(Promise);

QingJ © 2025

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