// ==UserScript==
// @name Auto Next
// @namespace http://tampermonkey.net/
// @version 1.0
// @description Busca los reproductores compatibles en el listado, los selecciona y maximiza. También redirige al siguiente episodio de manera automática.
// @author Chomusuke
// @license MIT
// @match https://serieskao.top/*
// @match https://xupalace.org/*
// @match https://hlsflast.com/*
// @match https://vidhidefast.com/*
// @match https://dood.work/*
// @match https://kllamrd.org/*
// @match https://sandratableother.com/*
// @match https://waaw.to/*
// @grant none
// ==/UserScript==
// REORGANIZAR A GUSTO
const reproductores = ['streamwish', 'filelions', 'doodstream', 'embedsito', 'voe', 'waaw']
// streamwish, filelions, doodstream, stape, vox, waav
const timeRemainToNext = 15 //tiempo restante del video para que inicie redirección
// USE F11 para tenerlo en pantalla completa siempre
// NO TOCAR---------------------------------------------------------------------------------
const sudomains = {
'streamwish':'https://hlsflast.com',
'filelions':'https://vidhidefast.com',
'doodstream':'https://dood.work',
'embedsito':'https://kllamrd.org',
'voe':'https://sandratableother.com',
'waaw':'https://waaw.to',
}
const videoListURL = 'https://xupalace.org'
const mainURL = 'https://serieskao.top'
const timeout = 5500; // Límite de tiempo en milisegundos
const waitForElements = (selector) => {
return new Promise((resolve, reject) => {
const timeout = 5000; // Límite de tiempo en milisegundos
const startTime = Date.now();
const interval = setInterval(() => {
const elements = document.querySelectorAll(selector);
if (elements.length > 0) {
clearInterval(interval);
resolve(elements);
} else if (Date.now() - startTime > timeout) {
clearInterval(interval);
reject(new Error(`Timeout: No se encontraron elementos para el selector "${selector}" dentro de 5 segundos.`));
}
}, 100);
});
};
const waitForElement = (selector) => {
return new Promise((resolve, reject) => {
const timeout = 5000; // Límite de tiempo en milisegundos
const startTime = Date.now();
const interval = setInterval(() => {
const element = document.querySelector(selector);
if (element) {
clearInterval(interval);
resolve(element);
} else if (Date.now() - startTime > timeout) {
clearInterval(interval);
reject(new Error(`Timeout: No se encontró el elemento para el selector "${selector}" dentro de 5 segundos.`));
}
}, 100);
});
};
(function () {
'use strict';
//para el principal
if (window.self !== window.top || !window.location.href.startsWith(mainURL)) return;
const capituloSigLink = Array.from(document.querySelectorAll('a'))
.find(link => link.textContent.includes('Capitulo Siguiente'));
let curIndex = 0;
let curPlayer = reproductores[curIndex];
// Escuchar mensajes de iframes
window.addEventListener('message', (event) => {
// Asegúrar origen del mensaje
console.log(event)
if (event.origin.startsWith(sudomains[curPlayer]) || event.origin.startsWith(videoListURL)) {
if (capituloSigLink && event.data === 'next'){
window.location.href = capituloSigLink.href;
}
if (event.data === 'full-size'){
fullscreen()
}
if (event.data === 'fail'){
curIndex = curIndex < reproductores.length -1 ? curIndex +1 : -1;
if (curIndex < 0){
alert("No hay reproductores disponibles")
return
}
curPlayer = reproductores[curIndex];
const iframe = document.querySelector('iframe');
if (iframe) {
iframe.src = iframe.src; // Recarga el iframe
}
}
if (event.data === 'requestCurPlayer'){
event.source.postMessage({ curPlayer: curPlayer }, event.origin);
}
}
});
const fullscreen = () => {
const frame = document.querySelector('iframe');
if (!frame) return;
if (frame.style.position ==='fixed'){
frame.style.position = 'relative';
frame.style.zIndex = '300';
}else{
frame.style.position = 'fixed';
frame.style.zIndex = '10000';
}
}
window.addEventListener('load', fullscreen);
})();
(function () {
'use strict';
// Verifica que se ejecute en la lista de videos
if (window.self === window.top ||
!window.location.href.startsWith(videoListURL)||
!document.referrer.startsWith(mainURL)) return;
// Solicitar la variable curSelection desde el root
window.top.postMessage("requestCurPlayer", mainURL);
window.addEventListener('message', (event) => {
if (event.origin === mainURL) {
if (event.data.curPlayer) {
const curPlayer = event.data.curPlayer;
const button = document.createElement('button');
const searchAndClick = async () => {
try{
console.log(`Buscando el primer <li> con ${curPlayer}...`);
const liElements = await waitForElements(`li[onclick*="${curPlayer}"]`);
if (liElements.length > 0) {
const firstLi = liElements[0];
const onclickValue = firstLi.getAttribute('onclick');
const urlMatch = onclickValue.match(/'([^']+)'/);
// Simular el clic en el primer elemento <li>
firstLi.click();
} else {
console.error(`No se encontró ningún elemento <li> con "${curPlayer}" en este iframe.`);
}
}catch(error){
console.error('Error:',error.message);
window.top.postMessage("fail", mainURL);
}
};
button.addEventListener('click', searchAndClick);
button.click()
}
}
});
})();
(function () {
'use strict';
// Ejecutar dentro del iframe del reproductor
if (window.self === window.top ||
!document.referrer.startsWith(videoListURL)) return;
// Variable global para asegurarse de que solo haya una instancia del botón
let redirectButtonInstance = null;
// Función que muestra el botón con la cuenta regresiva y redirige al hacer clic o cuando termina el tiempo
function showRedirectButton() {
// Si ya hay un botón, no hacemos nada
if (redirectButtonInstance) return;
// Crear el contenedor del botón
const buttonContainer = document.createElement('div');
buttonContainer.style.position = 'fixed';
buttonContainer.style.top = '10px';
buttonContainer.style.right = '10px';
buttonContainer.style.zIndex = '999999';
// Crear el botón de "Siguiente Video"
const button = document.createElement('button');
button.textContent = 'Siguiente video en 5 segundos';
button.style.padding = '10px 15px';
button.style.backgroundColor = '#007bff';
button.style.color = '#fff';
button.style.border = 'none';
button.style.borderRadius = '5px';
button.style.cursor = 'pointer';
// Crear el botón de cancelación "X"
const cancelButton = document.createElement('button');
cancelButton.textContent = 'X';
cancelButton.style.padding = '10px 15px';
cancelButton.style.backgroundColor = '#ff0000';
cancelButton.style.color = '#fff';
cancelButton.style.border = 'none';
cancelButton.style.borderRadius = '50%';
cancelButton.style.cursor = 'pointer';
cancelButton.style.marginLeft = '10px';
// Función que actualiza el texto de cuenta regresiva en el botón
let countdown = 5;
const updateButtonText = () => {
button.textContent = `Siguiente video en ${countdown} segundos`;
if (countdown === 0) {
window.top.postMessage('next', mainURL);
}
countdown--;
};
// Llama a la función de actualización cada segundo
const intervalId = setInterval(updateButtonText, 1000);
// Función para cancelar la redirección si se hace clic en "X"
cancelButton.addEventListener('click', () => {
clearInterval(intervalId); // Detener la cuenta regresiva
button.textContent = 'Redirección cancelada';
button.disabled = true; // Deshabilitar el botón
cancelButton.disabled = true; // Deshabilitar el botón "X"
});
// Función para redirigir al hacer clic en el botón
button.addEventListener('click', () => {
clearInterval(intervalId); // Detener la cuenta regresiva si se hace clic
window.top.postMessage('next', mainURL);
});
// Agregar los botones al contenedor y el contenedor al cuerpo de la página
buttonContainer.appendChild(button);
buttonContainer.appendChild(cancelButton);
document.body.appendChild(buttonContainer);
// Guardar la instancia para evitar que se cree otra
redirectButtonInstance = buttonContainer;
}
// Función para convertir el tiempo en formato 'MM:SS' a segundos
function timeToSeconds(timeStr) {
const [minutes, seconds] = timeStr.split(':').map(num => parseInt(num, 10));
return minutes * 60 + seconds;
}
// Función que verifica el tiempo y llama a la función si se cumple la condición
function checkTime() {
// Obtén el tiempo del div con clase "jw-text-elapsed"
const elapsedElement = document.querySelector('.jw-icon.jw-icon-inline.jw-text.jw-reset.jw-text-elapsed')||
document.querySelector('.plyr__controls__item.plyr__time--current.plyr__time');
const elapsedTime = elapsedElement ? elapsedElement.textContent.trim() : '00:00';
// Obtén el tiempo del div con clase "jw-text-duration"
const durationElement = document.querySelector('.jw-icon.jw-icon-inline.jw-text.jw-reset.jw-text-duration')||
document.querySelector('.plyr__controls__item.plyr__time--duration.plyr__time')||
document.querySelector('.vjs-remaining-time-display');
const durationTime = durationElement && durationElement.textContent.trim()!=='0:00' ? durationElement.textContent.trim() : '10:00';
// Convierte ambos tiempos a segundos
const elapsedTimeSeconds = timeToSeconds(elapsedTime);
const durationTimeSeconds = timeToSeconds(durationTime);
// Si el tiempo del primer div (elapsed) es igual o mayor al tiempo del segundo div (duration) menos 15 segundos
if (elapsedTimeSeconds >= (durationTimeSeconds - 20)) {
showRedirectButton();
}
}
// Solicitar la variable curSelection desde el root
window.top.postMessage("requestCurPlayer", mainURL);
window.addEventListener('message', (event) => {
if (event.origin === mainURL) {
if (event.data.curPlayer) {
const curPlayer = event.data.curPlayer;
if (!window.location.href.startsWith(sudomains[curPlayer])) return;
const button = document.createElement('button');
const performActions = async () => {
try{
await waitForElement('video');
const videoElement = document.querySelector('video');
if (videoElement) {
videoElement.click();
} else {
console.warn('No se encontró el elemento <video>.');
}
}catch(error){
console.error('Error: ',error.message);
window.top.postMessage("fail", mainURL);
}
};
button.addEventListener('click', performActions);
button.click()
const escButton = document.createElement('button');
escButton.style.position = 'fixed'
escButton.style.top = '40px';
escButton.style.right = '10px';
escButton.style.zIndex = '999999';
escButton.style.padding = '5px 10px';
escButton.style.backgroundColor = 'whitesmoke';
escButton.style.color = '#fff';
escButton.style.border = 'none';
escButton.style.borderRadius = '5px';
escButton.style.cursor = 'pointer';
escButton.textContent = '❌';
escButton.addEventListener('click', () => {
window.top.postMessage('full-size', mainURL);
});
document.body.appendChild(escButton);
// Llama a la función `checkTime` cada segundo para verificar el tiempo continuamente
setInterval(checkTime, 1000);
}
}
});
})();