🏠 Home 

YouTube: Stop Automatic Video Playback

Stop automatic video playback everywhere. Works on first page load & after navigating.

// ==UserScript==
// @name            YouTube: Stop Automatic Video Playback
// @namespace       org.sidneys.userscripts
// @homepage        https://gist.githubusercontent.com/sidneys/02a9025ae1f23aefe1f4ea02e78b0ac8/raw/
// @version         4.7.3
// @description     Stop automatic video playback everywhere. Works on first page load & after navigating.
// @author          sidneys
// @icon            https://www.youtube.com/favicon.ico
// @noframes
// @match           http*://www.youtube.com/*
// @require         https://greasyfork.org/scripts/38888-greasemonkey-color-log/code/Greasemonkey%20%7C%20Color%20Log.js
// @run-at          document-start
// ==/UserScript==
/**
* ESLint
* @global
*/
/* global Debug */
Debug = false
/**
* Applicable URL paths
* @default
* @constant
*/
const urlPathList = [
'/channel',
'/watch'
]
/**
* YouTube API Player States
* @constant
* @enum
*/
const PLAYERSTATE = {
'-1': 'UNSTARTED',
0: 'ENDED',
1: 'PLAYING',
2: 'PAUSED',
3: 'BUFFERING',
5: 'CUED'
}
/**
* Generate a method name for an event name using the DOM convention ("on" + Event Name)
* @param {String} eventName - Event name (e.g. 'Click')
* @returns {String} - Method name (e.g. 'onclick')
*/
let getHandlerMethodNameForEventName = eventName => `on${eventName.toLowerCase()}`
/**
* Lookup the first <video> Element
* @returns {Element} - <video> Element
*/
let getVideoElement = () => document.querySelector('video')
/**
* Lookup YouTube Video Player through the DOM
* @returns {Object} - YouTube Video Player
*/
let getYoutubePlayer = () => {
console.debug('getYoutubePlayer')
// Lookup Player element
const playerElement = document.querySelector('ytd-player')
// Return the property containing the Player API
return playerElement && playerElement.player_
}
/**
* Stop playback on YouTube via the Player API
* @param {Object} youtubePlayer - YouTube Video Player API
*/
let stopYoutubePlayerPlayback = (youtubePlayer) => {
console.debug('stopYoutubePlayerPlayback')
// Get YouTube Video element
const videoElement = getVideoElement()
// Playback event types to watch
const eventTypeList = [ 'play', 'playing', 'timeupdate' ]
// Iterate playback event types
eventTypeList.forEach((eventType, eventTypeIndex) => {
// Playback "Stopper" method, each playback event
let eventHandler = () => {
console.debug(`videoElement#${eventType}`)
// Remove all "Stopper" event handlers by deleting <video>#onplay, <video>#onplaying, <video>#ontimeupdate
eventTypeList.forEach((eventType) => {
const handlerMethodName = getHandlerMethodNameForEventName(eventType)
delete videoElement[handlerMethodName]
videoElement[handlerMethodName] = null
// DEBUG
console.debug('videoElement', 'removing event handler method:', handlerMethodName)
})
// Lookup YouTube Player state
const playerState = youtubePlayer.getPlayerState()
// Stop video (if it is not already paused)
if (youtubePlayer.getPlayerState() !== 2) {
youtubePlayer.pauseVideo()
// Status
console.info('Stopped automatic video playback', 'during the', PLAYERSTATE[playerState], 'phase')
// DEBUG
console.debug('stopYoutubePlayerPlayback', 'eventType:', eventType, 'playerState:', `${playerState} (${PLAYERSTATE[playerState]})`)
}
}
// Add event handler to video element
const handlerMethodName = getHandlerMethodNameForEventName(eventType)
videoElement[handlerMethodName] = eventHandler
})
}
/**
* Init
*/
let init = () => {
console.info('init')
// Verify URL path
if (!urlPathList.some(urlPath => window.location.pathname.startsWith(urlPath))) { return }
// Initiate lookup loop
let requestId
let lookup = () => {
// Lookup YouTube Player
const youtubePlayer = getYoutubePlayer()
// Is 1. the Player API available,  2. the Player ready?
if (!youtubePlayer || (youtubePlayer && !youtubePlayer.isReady())) {
// DEBUG
console.debug('❌ YouTube Player API unavailable or Player not ready yet.')
// Skip loop
requestId = window.requestAnimationFrame(lookup)
return
}
// Stop Playback
stopYoutubePlayerPlayback(youtubePlayer)
// DEBUG
console.debug('✅ YouTube Player API available and Player ready.')
// End loop
window.cancelAnimationFrame(requestId)
}
// Initiate loop
requestId = window.requestAnimationFrame(lookup)
}
/**
* Handle in-page navigation (modern YouTube)
* @listens window:Event#yt-navigate-finish
*/
window.addEventListener('yt-navigate-finish', () => {
console.debug('window#yt-navigate-finish')
init()
})