1// Turn off YouTube auto-captions on embedded players. 2// YouTube has no player parameter to force captions OFF (cc_load_policy=1 can only force 3// them ON), and embeds frequently auto-enable captions/auto-generated lyrics even when the 4// same video shows none on youtube.com. This wraps each embed with the IFrame API and 5// clears the active caption track when YouTube applies one. The CC button stays available, 6// so viewers who want captions can still turn them on manually. 7// YouTube applies the auto-caption track around the start of playback, so a single clear 8// on ready is not enough: we retry for a short window after the first play, then stand 9// down permanently so a viewer's manual CC choice is never overridden. 10// Only targets iframes whose src includes enablejsapi=1 (set in the video/header card templates). 11(function () { 12 var frames = document.querySelectorAll('iframe[src*="youtube.com/embed/"], iframe[src*="youtube-nocookie.com/embed/"]'); 13 var targets = []; 14 for (var i = 0; i < frames.length; i++) { 15 if (frames[i].src.indexOf("enablejsapi=1") !== -1) targets.push(frames[i]); 16 } 17 if (!targets.length) return; 18 19 function clearCaptions(player) { 20 var opts = (player.getOptions && player.getOptions()) || []; 21 if (opts.indexOf("captions") !== -1) player.setOption("captions", "track", {}); 22 if (opts.indexOf("cc") !== -1) player.setOption("cc", "track", {}); 23 } 24 25 function wrap(el) { 26 var done = false; // stop interfering after the post-play clear window 27 var played = false; 28 new YT.Player(el, { 29 events: { 30 onReady: function (e) { clearCaptions(e.target); }, 31 // Captions module usually loads just before/at playback start. 32 onApiChange: function (e) { if (!done) clearCaptions(e.target); }, 33 onStateChange: function (e) { 34 if (e.data === YT.PlayerState.PLAYING && !played) { 35 played = true; 36 var p = e.target; 37 clearCaptions(p); 38 setTimeout(function () { clearCaptions(p); }, 250); 39 setTimeout(function () { clearCaptions(p); }, 750); 40 setTimeout(function () { clearCaptions(p); done = true; }, 1500); 41 } 42 } 43 } 44 }); 45 } 46 47 function initPlayers() { 48 for (var i = 0; i < targets.length; i++) wrap(targets[i]); 49 } 50 51 if (window.YT && window.YT.Player) { 52 initPlayers(); 53 } else { 54 var prev = window.onYouTubeIframeAPIReady; 55 window.onYouTubeIframeAPIReady = function () { 56 if (typeof prev === "function") prev(); 57 initPlayers(); 58 }; 59 if (!document.querySelector('script[src*="youtube.com/iframe_api"]')) { 60 var tag = document.createElement("script"); 61 tag.src = "https://www.youtube.com/iframe_api"; 62 document.head.appendChild(tag); 63 } 64 } 65})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.