-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathyoutube stop automatic video playback userscript.js
178 lines (139 loc) · 4.8 KB
/
youtube stop automatic video playback userscript.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
// ==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, volt4ire
// @icon https://www.youtube.com/favicon.ico
// @noframes
// @match http*://www.youtube.com/*
// @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()
})