您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Watch theYNC Underground videos without needing an account
当前为
// ==UserScript== // @name theYNC.com Underground bypass // @description Watch theYNC Underground videos without needing an account // @require https://cdn.jsdelivr.net/npm/@trim21/[email protected]/dist/gm_fetch.js // @namespace Violentmonkey Scripts // @match *://*.theync.com/* // @match *://theync.com/* // @match *://*.theync.net/* // @match *://theync.net/* // @match *://*.theync.com/* // @match *://theync.com/* // @grant GM.xmlHttpRequest // @connect media.theync.com // @connect archive.org // @grant GM_addStyle // @version 3.1 // @license MIT // @author - // ==/UserScript== function getTheYNCVideoURLFromThumbnail (url) { for (const [, group_url] of url.matchAll( /^https?:\/\/theync\.(?:com|org|net)\/media\/thumbs\/(.*?)\.[a-zA-Z0-9_.-]*/gim )) { if (group_url) { return `https://media.theync.com/videos/${group_url}.mp4` } } } function isValidURL (url) { return new Promise((resolve, reject) => GM_fetch(url, { method: 'HEAD' }).then(response => { if (response.ok) { return resolve(response.status) } return reject(response.status) }) ) } function waitForElement (selector) { return new Promise(resolve => { { const element = document.querySelector(selector) if (element) { return resolve(element) } } const observer = new MutationObserver(() => { const element = document.querySelector(selector) if (element) { observer.disconnect() resolve(element) } }) // If you get 'parameter 1 is not of type 'Node'' error, see https://stackoverflow.com/a/77855838/492336 observer.observe(document.body, { childList: true, subtree: true }) }) } GM_addStyle(` .loader { border: 0.25em solid #f3f3f3; border-top-width: 0.25em; border-top-style: solid; border-top-color: rgb(243, 243, 243); border-top: 0.25em solid rgb(0, 0, 0); border-radius: 50%; width: 1em; height: 1em; animation: spin 2s linear infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .border-gold { display: flex !important; align-items: center; justify-content: center; gap: 1em; } `) waitForElement('.content-block').then(contentBlock => { for (const element of contentBlock.querySelectorAll( '.upgrade-profile > .upgrade-info-block' )) { const thumbnailURL = element.querySelector( '.image-block > .image > img' ).src if (!thumbnailURL) continue const videoURL = getTheYNCVideoURLFromThumbnail(thumbnailURL) if (!videoURL) continue isValidURL(videoURL).then(_status => { location.href = videoURL }) return } for (const element of contentBlock.querySelectorAll('.inner-block > a')) { const undergroundLogo = element.querySelector('.item-info > .border-gold') if (!undergroundLogo) continue const thumbnailURL = element.querySelector('.image > img').src if (!thumbnailURL) continue const videoURL = getTheYNCVideoURLFromThumbnail(thumbnailURL) if (!videoURL) continue const loadingElement = document.createElement('div') loadingElement.classList.add('loader') undergroundLogo.appendChild(loadingElement) isValidURL(videoURL) .then( _status => { undergroundLogo.textContent = 'BYPASSED' undergroundLogo.style.backgroundColor = 'green' element.href = videoURL }, _status => GM_fetch( `https://archive.org/wayback/available?url=${element.href}`, { method: 'GET' } ) .then(archiveResponse => archiveResponse.json()) .then(({ archived_snapshots }) => { if (archived_snapshots.closest) { undergroundLogo.textContent = 'ARCHIVED' undergroundLogo.style.backgroundColor = 'blue' element.href = archived_snapshots.closest.url } }) ) .finally(() => loadingElement.remove()) } })