您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
多视图视频和流媒体
// ==UserScript== // @name YouTube multi-view // @name:en YouTube multi-view // @name:ja YouTube 複窓視聴 // @name:zh-cn YouTube 多视图 // @namespace https://www.youtube.com/ // @version 2024-07-20 // @description multi-view video and streaming // @description:en multi-view video and streaming // @description:ja 生放送や動画を複窓で見れます // @description:zh-cn 多视图视频和流媒体 // @author ぐらんぴ // @match https://www.youtube.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com // @grant none // @require https://greasyfork.org/scripts/433051-trusted-types-helper/code/Trusted-Types%20Helper.js // @license MIT // ==/UserScript== divide = 2 let addBtn = setInterval(()=>{ if(document.querySelectorAll("#end > div").length !== 2){ clearInterval(addBtn) }else{ let btns = document.querySelector("#buttons"), div = document.createElement('div') div.innerHTML = `<button style="color: #ff00dd; position: relative; background: transparent; border: none; outline: none; box-shadow: none; cursor: pointer;"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path fill-rule="evenodd" clip-rule="evenodd" d="M11 17H4C2.34315 17 1 15.6569 1 14V6C1 4.34315 2.34315 3 4 3H20C21.6569 3 23 4.34315 23 6V14C23 15.6569 21.6569 17 20 17H13V19H16C16.5523 19 17 19.4477 17 20C17 20.5523 16.5523 21 16 21H8C7.44772 21 7 20.5523 7 20C7 19.4477 7.44772 19 8 19H11V17ZM4 5H20C20.5523 5 21 5.44772 21 6V14C21 14.5523 20.5523 15 20 15H4C3.44772 15 3 14.5523 3 14V6C3 5.44772 3.44772 5 4 5Z" fill="currentColor" /></svg></button>` btns.before(div) let div2 = document.createElement('div') div2.innerHTML = `<input type="text" placeholder="URL" style="position: absolute; display: flex; width: 500px; right: 10px; top: 50px;" input> <button class="add" style="position: absolute; display: flex; right: 10px; top: 50px;" id='submit'>add</button> <button class="switch" style="position: absolute; display: flex; width: 54px; right: 516px; top: 50px;" id='submit'>switch</button>` div.appendChild(div2) let hideDiv2 = document.querySelector("#end > div:nth-child(2) > div") hideDiv2.style.display = 'none' document.querySelector("#end > div:nth-child(2) > button").addEventListener('click', ()=>{ let del = document.querySelectorAll(".del") if(hideDiv2.style.display == 'none'){ hideDiv2.style.display = '' del.forEach(elm => { elm.style.display = ""; }) }else{ hideDiv2.style.display = 'none' del.forEach(elm => { elm.style.display = "none"; }) } }); a() } },1000) function a(){ document.querySelector(".add").onclick =()=>{ if(location.href.match('/watch')){// /watch parent = document.querySelector("ytd-watch-flexy") //document.querySelector("ytd-watch-grid") }else if(location.href.match('/results')){// /results parent = document.querySelector("ytd-search") }else{// /home, /subscriptions, /you let parents = document.querySelectorAll("ytd-browse") for(let i = 0; i < parents.length; i++){ if(parents[i].getAttribute('role') !== null){ parent = parents[i] } } } let ytd = document.createElement('div') ytd.innerHTML = ` <div class="area" style="display: none;"> <div class="content_class" style="display: flex; flex-wrap: wrap;"></div> </div>` parent.before(ytd) if(location.href.match('/watch')){ Vwidth = (document.querySelector("#masthead").clientWidth-(document.querySelector("yt-icon > span > div > svg").width.animVal.value*3))/2-1 // document.querySelector("#icon > yt-icon-shape > icon-shape > div > svg").width.animVal.value console.log(Vwidth) }else{ Vwidth = document.querySelector("#page-manager").clientWidth / divide -1 console.log(Vwidth) } Vval = document.querySelector("#end > div:nth-child(2) > div > input[type=text]").value if(Vval.match('&')){ Vsrc = Vval.substring(0, Vval.indexOf("&")).replace("watch?v=", "embed/") }else{ Vsrc = Vval.replace("watch?v=", "embed/") } let divWatch = document.createElement('div') divWatch.innerHTML = ` <iframe width="${Vwidth}" height="${Math.floor(Vwidth/1.77)}" src="${Vsrc}" title="" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> <div style="text-align: center;"> <button class="del" style="position: absolute;" id='submit'>delete</button> </div>` divWatch.addEventListener('click', (e)=>{ //console.log(e.target.closest('div').parentNode); e.target.closest('div').parentNode.remove() }); document.querySelector(".content_class").appendChild(divWatch) } document.querySelector(".switch").onclick =()=>{ if(location.href.match('/watch')){// /watch parent = document.querySelector("ytd-watch-flexy")//document.querySelector("ytd-watch-grid") }else if(location.href.match('/results')){// /results parent = document.querySelector("ytd-search") }else{// /home, /subscriptions, /you let parents = document.querySelectorAll("ytd-browse") for(let i = 0; i < parents.length; i++){ if(parents[i].getAttribute('role') !== null){ parent = parents[i] } } } if(parent.style.display == ""){ parent.style.display = 'none' if(document.querySelector(".area") !== null){ document.querySelector(".area").style.display = '' } }else{ parent.style.display = '' if(document.querySelector(".area") !== null){ document.querySelector(".area").style.display = 'none' } } } } var oldHref = window.location.href; var observer = new MutationObserver(()=>{ if(oldHref != window.location.href){ oldHref = window.location.href; var currHref = window.location.href; a() if(document.querySelector(".area") !== null && location.href.match('/results')){ (async () => { await new Promise(resolve => setTimeout(resolve, 800)); //Without this code, display = 'none' is unstable. document.querySelector("ytd-search").style.display = '' document.querySelector(".area").style.display = 'none' console.log('async') })(); }else if(document.querySelector(".area") !== null){ (async () => { await new Promise(resolve => setTimeout(resolve, 800)); let parents = document.querySelectorAll("ytd-browse") for(let i = 0; i < parents.length; i++){ if(parents[i].getAttribute('role') !== null){ if(parents[i].style.display !== 'none' || document.querySelectorAll(".area") !== null){ parents[i].style.display = '' document.querySelector(".area").style.display = 'none' } } } })(); } } }) observer.observe(document.body, {childList: true, subtree: true, });