// ==UserScript==
// @name YouTube Play All
// @description Adds the Play-All-Button to the videos, shorts, and live sections of a YouTube-Channel
// @version 20250325-2
// @author Robert Wesner (https://robert.wesner.io)
// @license MIT
// @namespace http://robert.wesner.io/
// @match https://*.youtube.com/*
// @icon https://scripts.yt/favicon.ico
// @grant none
// @downloadURL none
// ==/UserScript==
/**
* @var {{ defaultPolicy: any, createPolicy: (string, Object) => void }} window.trustedTypes
*/
/**
* @var {{ script: { version: string } }} GM_info
*/
(async function () {
'use strict';
const scriptVersion = GM_info.script.version || null;
if (scriptVersion && /-(alpha|beta|dev|test)$/.test(scriptVersion)) {
console.log(
'%cYTPA - YouTube Play All\n',
'color: #bf4bcc; font-size: 32px; font-weight: bold',
'You are currently running a test version:',
scriptVersion,
);
}
if (window.hasOwnProperty('trustedTypes') && !window.trustedTypes.defaultPolicy) {
window.trustedTypes.createPolicy('default', { createHTML: string => string });
}
document.head.insertAdjacentHTML('beforeend', ``);
let id;
const apply = () => {
let parent = location.host === 'm.youtube.com'
// mobile view
? document.querySelector('ytm-feed-filter-chip-bar-renderer > div')
// desktop view
: document.querySelector('ytd-feed-filter-chip-bar-renderer iron-selector#chips');
// #5: add a custom container for buttons if Latest/Popular/Oldest is missing
if (parent === null) {
const grid = document.querySelector('ytd-rich-grid-renderer, ytm-rich-grid-renderer');
grid.insertAdjacentHTML('afterbegin', '
');
parent = grid.querySelector('.ytpa-button-container');
}
// See: available-lists.md
let [allPlaylist, popularPlaylist] = window.location.pathname.endsWith('/videos')
// Normal videos
// list=UULP has the all videos sorted by popular
// list=UU adds shorts into the playlist, list=UULF has videos without shorts
? ['UULF', 'UULP']
// Shorts
: window.location.pathname.endsWith('/shorts')
? ['UUSH', 'UUPS']
// Live streams
: ['UULV', 'UUPV'];
// Check if popular videos are displayed
if (parent.querySelector(':nth-child(2).selected, :nth-child(2).iron-selected')) {
parent.insertAdjacentHTML(
'beforeend',
`Play Popular`
);
} else {
parent.insertAdjacentHTML(
'beforeend',
`Play All`
);
}
if (location.host === 'm.youtube.com') {
// YouTube returns an "invalid response" when using client side routing for playnext=1 on mobile
document.querySelectorAll('.ytpa-btn').forEach(btn => btn.addEventListener('click', event => {
event.preventDefault();
window.location.href = btn.href;
}));
} else {
// Only allow random play in desktop version for now
parent.insertAdjacentHTML('beforeend', `
Play Random
▾
`);
document.body.insertAdjacentHTML('beforeend', `