Autoplay für SerienStream.to
< Feedback on s.to autoplay
// ==UserScript==// @name bs.to autoplay// @namespace http://tampermonkey.net/// @version 2.5.1 (10.12.20)// @description auto play. sit back and relax.// @author xZaheer, ipgroup2010// @match https://bs.to/*// @match https://*.vivo.sx/*// @grant GM_setValue// @grant GM_getValue// @grant GM_deleteValue// @grant GM_openInTab// @grant window.close// @require https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js// @license GPL// ==/UserScript==class VivoHandler { constructor() { this.episodeHandler = new EpisodeHandler(); this.currentEpisode = this.episodeHandler.getCurrent(); this.nextEpisode = this.episodeHandler.getNext(); this.prevEpisode = this.episodeHandler.getPrev(); this.skipTime = this.episodeHandler.getCurrentSkip(); if(window.location.href.includes("vivo.sx")) { this.initEvents(); } } initEvents() { if(window.location.href.includes("https://vivo.sx")) { this.play(); } else { let waitForElem = setInterval(() => { let videoElem = document.querySelector("video"); if(videoElem) { clearTimeout(waitForElem); GM_setValue("playing", true); this.resize(); this.onEnd(); this.resume(); this.showControls(); this.trackWatchedState(); } }, 50); } } play() { // code by https://greasyfork.org/de/scripts/28779-zu-vivo-video-navigieren // Thank you! var source = document.getElementsByTagName('body')[0].innerHTML; if (source != null) { source = source.replace(/(?:.|\n)+Core\.InitializeStream\s*\(\s*\{[^)}]*source\s*:\s*'(.*?)'(?:.|\n)+/, "$1"); var toNormalize = decodeURIComponent(source); var url = "" for (var i = 0; i < toNormalize.length; i++) { var c = toNormalize.charAt(i); if (c != ' ') { var t = (function (c) { return c.charCodeAt == null ? c : c.charCodeAt(0); })(c) + '/'.charCodeAt(0); if (126 < t) { t -= 94; } url += String.fromCharCode(t); } } if (!url.toLowerCase().startsWith("http")) { alert("Vivo-Script Defect!"); return; } } GM_setValue("playing", true); window.location.href = url; } showControls() { //document.body.style.position = "relative"; let nextButton = document.createElement("button"); let prevButton = document.createElement("button"); nextButton.style.visibility = "hidden"; prevButton.style.visibility = "hidden";; nextButton.innerHTML = "Nächste Episode"; prevButton.innerHTML = "Vorherige Episode"; nextButton.style.position = "absolute"; prevButton.style.position = "absolute"; nextButton.addEventListener("click", () => { this.episodeHandler.clean(); this.episodeHandler.setCurrent(this.nextEpisode); window.location.href = this.nextEpisode + "#autoplay"; }); prevButton.addEventListener("click", () => { this.episodeHandler.clean(); this.episodeHandler.setCurrent(this.prevEpiside); window.location.href = this.prevEpisode + "#autoplay"; }); document.body.appendChild(nextButton); document.body.appendChild(prevButton); prevButton.style.left = "0"; nextButton.style.left = "calc(100% - "+ (nextButton.offsetWidth + 1) +"px)"; nextButton.style.top = "50%"; prevButton.style.top = "50%"; let timer = null; document.body.addEventListener("mousemove", () => { if(timer) { clearTimeout(timer); } nextButton.style.visibility = "visible"; prevButton.style.visibility = "visible"; timer = setTimeout(() => { nextButton.style.visibility = "hidden"; prevButton.style.visibility = "hidden"; }, 1000); }) } resize() { let video = document.querySelector("video"); video.style.width = "100%"; video.style.height = "100%"; document.body.style.margin = "0px"; } onEnd() { let videoElem = document.querySelector("video"); videoElem.onended = () => { let current = videoElem.currentTime; let duration = videoElem.duration; if (current && duration) { this.episodeHandler.watch(this.currentEpisode, current, duration); } let nextEpisode = this.episodeHandler.getNext(); this.episodeHandler.clean(); this.episodeHandler.setCurrent(nextEpisode); window.location.href = nextEpisode + "#autoplay"; } } trackWatchedState() { let videoElem = document.querySelector("video"); if(videoElem && this.currentEpisode) { videoElem.addEventListener('progress', (event) => { let current = videoElem.currentTime; let duration = videoElem.duration; if (current && duration) { this.episodeHandler.watch(this.currentEpisode, current, duration); } }); } } skip() { let videoElem = document.querySelector("video"); videoElem.currentTime = this.skipTime; } resume() { let videoElem = document.querySelector("video"); let data = this.episodeHandler.getWatched(this.currentEpisode); if((data.current !== data.duration) && videoElem && data) { videoElem.currentTime = data.current; } else { this.skip(); } }}class BsHandler { constructor() { this.episodeHandler = new EpisodeHandler(); this.buttonElem = null; if(window.location.href.includes("bs.to")) { this.initEvents(); } } initEvents() { // handle bs.to/* if(this.isLoggedIn()) { } // handle episode overview table if(window.location.href.includes("bs.to/serie") && this.isEpisodeOverview()){ this.episodeHandler.clean(); this.initElementsEpisodeOverview(); } // handle episode view if(!this.isEpisodeOverview() && this.isEpisodeSelected()){ if(this.isVivoAvailable() && this.isAutoplayForEpisode()) { this.closeOnPlay(); this.setPrevNext(); this.showAutoplayOverlay(); this.clickPlay(); } else { this.episodeHandler.clean(); } } } isAutoplayForEpisode() { return (window.location.href.includes("#autoplay")) ? true : false; } setPrevNext() { let episodes = document.querySelector("#episodes > ul"); let selectedEpisode = episodes.querySelector(".active"); let nextEpisode = episodes.querySelector("li.active + li"); let prevEpisode = selectedEpisode.previousElementSibling; let prevUrl = (prevEpisode) ? prevEpisode.querySelector("a").href : ""; let nextUrl = (nextEpisode) ? nextEpisode.querySelector("a").href : ""; this.episodeHandler.setPrev(prevUrl); this.episodeHandler.setNext(nextUrl); } showAutoplayOverlay() { let overlayElem = document.createElement("h1"); document.querySelector("#root").style.visibility = "hidden"; document.body.style.overflow = "hidden"; document.body.style.height = "100vh"; document.querySelector("footer").style.visibility = "hidden"; overlayElem.innerHTML = "Auto Playing ..." overlayElem.style.position = "absolute"; document.body.style.display = "flex"; document.body.style.alignItems = "center"; document.body.style.justifyContent = "center"; overlayElem.style.zIndex = "999"; document.body.appendChild(overlayElem); } initElementsEpisodeOverview() { let tableElem = document.querySelectorAll("#root > section > table > tbody > tr"); let episodeRowElemToHandle = []; tableElem.forEach(episodeRowElem => { if(episodeRowElem.querySelector(".vivo")) { episodeRowElemToHandle.push(episodeRowElem); } }); this.addSkipControl(); this.addContinueButtons(episodeRowElemToHandle); this.addProgessBars(episodeRowElemToHandle); } addSkipControl() { let seasonUrl = this.getActiveSeasonUrl(); let onChange = (event) => { let time = parseInt(event.target.value) || 0; this.episodeHandler.setSkipForSeason(seasonUrl, time); }; let divElem = document.createElement("div"); let labelElem = document.createElement("label"); let inputElem = document.createElement("input"); inputElem.type = "number"; divElem.appendChild(labelElem); labelElem.innerHTML= "Intro überspringen (in Sekunden):" divElem.appendChild(inputElem); let locationElem = document.querySelector("#root > section > div.selectors"); locationElem.appendChild(divElem); inputElem.value = this.episodeHandler.getSkipForSeason(seasonUrl) || ""; inputElem.addEventListener("change", onChange); } getActiveSeasonUrl() { return document.querySelector("#seasons > ul > .active > a").href; } addProgessBars(elements) { elements.forEach((episodeRowElem) => { let url = episodeRowElem.querySelector("a").href; let data = this.episodeHandler.getWatched(url); let percentage = data.current * 100 / data.duration; if(percentage) { let episodeProgressbarElem = document.createElement("meter"); episodeProgressbarElem.value = percentage; episodeProgressbarElem.max = 100; episodeProgressbarElem.style.width = "100%"; episodeRowElem.appendChild(episodeProgressbarElem); } }); } addContinueButtons(elements) { elements.forEach((episodeRowElem) => { let location = episodeRowElem.querySelector("[title='vivo']").parentElement; let buttonElem = document.createElement("a"); buttonElem.innerHTML = "AutoPlay"; buttonElem.style.cursor = "pointer"; buttonElem.addEventListener("click", () => { let url = episodeRowElem.querySelector("a").href; this.episodeHandler.clean(); this.episodeHandler.setCurrent(url); window.open(url + "#autoplay"); }) location.prepend(buttonElem); }); } isLoggedIn() { let logoutButtonElem = document.querySelector("#root > header > section > a:nth-child(4)"); return (logoutButtonElem) ? true : false; } isEpisodeOverview() { let isSerie = window.location.href.includes("serie"); return (isSerie && !this.isEpisodeSelected()); } isEpisodeSelected() { let checkElem = document.querySelector("#root > section > ul.hoster-tabs.top"); return (checkElem) ? true : false; } isVivoAvailable() { let vivoButton = document.querySelector("#root > section > ul.hoster-tabs.top > li > a > i.vivo"); if(!vivoButton) { return false; } else { return true; } } clickPlay() { let seasonUrl = this.getActiveSeasonUrl(); let skipTime = this.episodeHandler.getSkipForSeason(seasonUrl); this.episodeHandler.setCurrentSkip(skipTime); // setTimeout needed because loading time of js libs setTimeout(() => { let playerElem = document.querySelector("section.serie .hoster-player"); let clickEvent = new Event("click"); clickEvent.which = 1; clickEvent.pageX = 1; clickEvent.pageY = 1; playerElem.dispatchEvent(clickEvent); }, 1000) } closeOnPlay() { setInterval(() => { if(GM_getValue("playing")) { window.close(); } }, 1000); }}class EpisodeHandler { watch(episodeUrl, current, duration) { let data = JSON.parse(GM_getValue(episodeUrl) || "{}"); data.watched = {current: current, duration: duration}; GM_setValue(episodeUrl, JSON.stringify(data)); } getWatched(episodeUrl) { let data = GM_getValue(episodeUrl); if(!data) { return false; } data = JSON.parse(data); return data.watched; } // oursource setSkipForSeason(seasonUrl, time) { let data = JSON.parse(GM_getValue(seasonUrl) || "{}"); data.skipTime = time; console.log(data); GM_setValue(seasonUrl, JSON.stringify(data)); } getSkipForSeason(seasonUrl) { let data = GM_getValue(seasonUrl); if(!data) { return false; } data = JSON.parse(data); return data.skipTime; } //outsource end setCurrentSkip(time) { GM_setValue("currentSkip", time); } getCurrentSkip() { return GM_getValue("currentSkip") || 0; } getCurrent() { return GM_getValue("current"); } setCurrent(episodeUrl) { GM_setValue("current", episodeUrl); } getPrev() { return GM_getValue("prev"); } setPrev(episodeUrl) { GM_setValue("prev", episodeUrl); } getNext() { return GM_getValue("next"); } setNext(episodeUrl) { GM_setValue("next", episodeUrl); } clean() { GM_deleteValue("current"); GM_deleteValue("next"); GM_deleteValue("prev"); GM_deleteValue("playing"); GM_deleteValue("currentSkip"); }}(function() { 'use strict'; let vivoHandler = new VivoHandler(); let bsHandler = new BsHandler();})();
Vielen Dank! Hat geholfen. Bitte die aktuelle Version testen.Hab es mal auf github gepackt https://github.com/zaheer-exe/burningseries-autoplayGruß Zaheer!
Sign in to post a reply.
// ==UserScript==
// @name bs.to autoplay
// @namespace http://tampermonkey.net/
// @version 2.5.1 (10.12.20)
// @description auto play. sit back and relax.
// @author xZaheer, ipgroup2010
// @match https://bs.to/*
// @match https://*.vivo.sx/*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_deleteValue
// @grant GM_openInTab
// @grant window.close
// @require https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js
// @license GPL
// ==/UserScript==
class VivoHandler {
constructor() {
this.episodeHandler = new EpisodeHandler();
this.currentEpisode = this.episodeHandler.getCurrent();
this.nextEpisode = this.episodeHandler.getNext();
this.prevEpisode = this.episodeHandler.getPrev();
this.skipTime = this.episodeHandler.getCurrentSkip();
if(window.location.href.includes("vivo.sx")) {
this.initEvents();
}
}
initEvents() {
if(window.location.href.includes("https://vivo.sx")) {
this.play();
} else {
let waitForElem = setInterval(() => {
let videoElem = document.querySelector("video");
if(videoElem) {
clearTimeout(waitForElem);
GM_setValue("playing", true);
this.resize();
this.onEnd();
this.resume();
this.showControls();
this.trackWatchedState();
}
}, 50);
}
}
play() {
// code by https://greasyfork.org/de/scripts/28779-zu-vivo-video-navigieren
// Thank you!
var source = document.getElementsByTagName('body')[0].innerHTML;
if (source != null) {
source = source.replace(/(?:.|\n)+Core\.InitializeStream\s*\(\s*\{[^)}]*source\s*:\s*'(.*?)'(?:.|\n)+/, "$1");
var toNormalize = decodeURIComponent(source);
var url = ""
for (var i = 0; i < toNormalize.length; i++) {
var c = toNormalize.charAt(i);
if (c != ' ') {
var t = (function (c) { return c.charCodeAt == null ? c : c.charCodeAt(0); })(c) + '/'.charCodeAt(0);
if (126 < t) {
t -= 94;
}
url += String.fromCharCode(t);
}
}
if (!url.toLowerCase().startsWith("http")) {
alert("Vivo-Script Defect!");
return;
}
}
GM_setValue("playing", true);
window.location.href = url;
}
showControls() {
//document.body.style.position = "relative";
let nextButton = document.createElement("button");
let prevButton = document.createElement("button");
nextButton.style.visibility = "hidden";
prevButton.style.visibility = "hidden";;
nextButton.innerHTML = "Nächste Episode";
prevButton.innerHTML = "Vorherige Episode";
nextButton.style.position = "absolute";
prevButton.style.position = "absolute";
nextButton.addEventListener("click", () => {
this.episodeHandler.clean();
this.episodeHandler.setCurrent(this.nextEpisode);
window.location.href = this.nextEpisode + "#autoplay";
});
prevButton.addEventListener("click", () => {
this.episodeHandler.clean();
this.episodeHandler.setCurrent(this.prevEpiside);
window.location.href = this.prevEpisode + "#autoplay";
});
document.body.appendChild(nextButton);
document.body.appendChild(prevButton);
prevButton.style.left = "0";
nextButton.style.left = "calc(100% - "+ (nextButton.offsetWidth + 1) +"px)";
nextButton.style.top = "50%";
prevButton.style.top = "50%";
let timer = null;
document.body.addEventListener("mousemove", () => {
if(timer) {
clearTimeout(timer);
}
nextButton.style.visibility = "visible";
prevButton.style.visibility = "visible";
timer = setTimeout(() => {
nextButton.style.visibility = "hidden";
prevButton.style.visibility = "hidden";
}, 1000);
})
}
resize() {
let video = document.querySelector("video");
video.style.width = "100%";
video.style.height = "100%";
document.body.style.margin = "0px";
}
onEnd() {
let videoElem = document.querySelector("video");
videoElem.onended = () => {
let current = videoElem.currentTime;
let duration = videoElem.duration;
if (current && duration) {
this.episodeHandler.watch(this.currentEpisode, current, duration);
}
let nextEpisode = this.episodeHandler.getNext();
this.episodeHandler.clean();
this.episodeHandler.setCurrent(nextEpisode);
window.location.href = nextEpisode + "#autoplay";
}
}
trackWatchedState() {
let videoElem = document.querySelector("video");
if(videoElem && this.currentEpisode) {
videoElem.addEventListener('progress', (event) => {
let current = videoElem.currentTime;
let duration = videoElem.duration;
if (current && duration) {
this.episodeHandler.watch(this.currentEpisode, current, duration);
}
});
}
}
skip() {
let videoElem = document.querySelector("video");
videoElem.currentTime = this.skipTime;
}
resume() {
let videoElem = document.querySelector("video");
let data = this.episodeHandler.getWatched(this.currentEpisode);
if((data.current !== data.duration) && videoElem && data) {
videoElem.currentTime = data.current;
} else {
this.skip();
}
}
}
class BsHandler {
constructor() {
this.episodeHandler = new EpisodeHandler();
this.buttonElem = null;
if(window.location.href.includes("bs.to")) {
this.initEvents();
}
}
initEvents() {
// handle bs.to/*
if(this.isLoggedIn()) {
}
// handle episode overview table
if(window.location.href.includes("bs.to/serie") && this.isEpisodeOverview()){
this.episodeHandler.clean();
this.initElementsEpisodeOverview();
}
// handle episode view
if(!this.isEpisodeOverview() && this.isEpisodeSelected()){
if(this.isVivoAvailable() && this.isAutoplayForEpisode()) {
this.closeOnPlay();
this.setPrevNext();
this.showAutoplayOverlay();
this.clickPlay();
} else {
this.episodeHandler.clean();
}
}
}
isAutoplayForEpisode() {
return (window.location.href.includes("#autoplay")) ? true : false;
}
setPrevNext() {
let episodes = document.querySelector("#episodes > ul");
let selectedEpisode = episodes.querySelector(".active");
let nextEpisode = episodes.querySelector("li.active + li");
let prevEpisode = selectedEpisode.previousElementSibling;
let prevUrl = (prevEpisode) ? prevEpisode.querySelector("a").href : "";
let nextUrl = (nextEpisode) ? nextEpisode.querySelector("a").href : "";
this.episodeHandler.setPrev(prevUrl);
this.episodeHandler.setNext(nextUrl);
}
showAutoplayOverlay() {
let overlayElem = document.createElement("h1");
document.querySelector("#root").style.visibility = "hidden";
document.body.style.overflow = "hidden";
document.body.style.height = "100vh";
document.querySelector("footer").style.visibility = "hidden";
overlayElem.innerHTML = "Auto Playing ..."
overlayElem.style.position = "absolute";
document.body.style.display = "flex";
document.body.style.alignItems = "center";
document.body.style.justifyContent = "center";
overlayElem.style.zIndex = "999";
document.body.appendChild(overlayElem);
}
initElementsEpisodeOverview() {
let tableElem = document.querySelectorAll("#root > section > table > tbody > tr");
let episodeRowElemToHandle = [];
tableElem.forEach(episodeRowElem => {
if(episodeRowElem.querySelector(".vivo")) {
episodeRowElemToHandle.push(episodeRowElem);
}
});
this.addSkipControl();
this.addContinueButtons(episodeRowElemToHandle);
this.addProgessBars(episodeRowElemToHandle);
}
addSkipControl() {
let seasonUrl = this.getActiveSeasonUrl();
let onChange = (event) => {
let time = parseInt(event.target.value) || 0;
this.episodeHandler.setSkipForSeason(seasonUrl, time);
};
let divElem = document.createElement("div");
let labelElem = document.createElement("label");
let inputElem = document.createElement("input");
inputElem.type = "number";
divElem.appendChild(labelElem);
labelElem.innerHTML= "Intro überspringen (in Sekunden):"
divElem.appendChild(inputElem);
let locationElem = document.querySelector("#root > section > div.selectors");
locationElem.appendChild(divElem);
inputElem.value = this.episodeHandler.getSkipForSeason(seasonUrl) || "";
inputElem.addEventListener("change", onChange);
}
getActiveSeasonUrl() {
return document.querySelector("#seasons > ul > .active > a").href;
}
addProgessBars(elements) {
elements.forEach((episodeRowElem) => {
let url = episodeRowElem.querySelector("a").href;
let data = this.episodeHandler.getWatched(url);
let percentage = data.current * 100 / data.duration;
if(percentage) {
let episodeProgressbarElem = document.createElement("meter");
episodeProgressbarElem.value = percentage;
episodeProgressbarElem.max = 100;
episodeProgressbarElem.style.width = "100%";
episodeRowElem.appendChild(episodeProgressbarElem);
}
});
}
addContinueButtons(elements) {
elements.forEach((episodeRowElem) => {
let location = episodeRowElem.querySelector("[title='vivo']").parentElement;
let buttonElem = document.createElement("a");
buttonElem.innerHTML = "AutoPlay";
buttonElem.style.cursor = "pointer";
buttonElem.addEventListener("click", () => {
let url = episodeRowElem.querySelector("a").href;
this.episodeHandler.clean();
this.episodeHandler.setCurrent(url);
window.open(url + "#autoplay");
})
location.prepend(buttonElem);
});
}
isLoggedIn() {
let logoutButtonElem = document.querySelector("#root > header > section > a:nth-child(4)");
return (logoutButtonElem) ? true : false;
}
isEpisodeOverview() {
let isSerie = window.location.href.includes("serie");
return (isSerie && !this.isEpisodeSelected());
}
isEpisodeSelected() {
let checkElem = document.querySelector("#root > section > ul.hoster-tabs.top");
return (checkElem) ? true : false;
}
isVivoAvailable() {
let vivoButton = document.querySelector("#root > section > ul.hoster-tabs.top > li > a > i.vivo");
if(!vivoButton) {
return false;
} else {
return true;
}
}
clickPlay() {
let seasonUrl = this.getActiveSeasonUrl();
let skipTime = this.episodeHandler.getSkipForSeason(seasonUrl);
this.episodeHandler.setCurrentSkip(skipTime);
// setTimeout needed because loading time of js libs
setTimeout(() => {
let playerElem = document.querySelector("section.serie .hoster-player");
let clickEvent = new Event("click");
clickEvent.which = 1;
clickEvent.pageX = 1;
clickEvent.pageY = 1;
playerElem.dispatchEvent(clickEvent);
}, 1000)
}
closeOnPlay() {
setInterval(() => {
if(GM_getValue("playing")) {
window.close();
}
}, 1000);
}
}
class EpisodeHandler {
watch(episodeUrl, current, duration) {
let data = JSON.parse(GM_getValue(episodeUrl) || "{}");
data.watched = {current: current, duration: duration};
GM_setValue(episodeUrl, JSON.stringify(data));
}
getWatched(episodeUrl) {
let data = GM_getValue(episodeUrl);
if(!data) {
return false;
}
data = JSON.parse(data);
return data.watched;
}
// oursource
setSkipForSeason(seasonUrl, time) {
let data = JSON.parse(GM_getValue(seasonUrl) || "{}");
data.skipTime = time;
console.log(data);
GM_setValue(seasonUrl, JSON.stringify(data));
}
getSkipForSeason(seasonUrl) {
let data = GM_getValue(seasonUrl);
if(!data) {
return false;
}
data = JSON.parse(data);
return data.skipTime;
}
//outsource end
setCurrentSkip(time) {
GM_setValue("currentSkip", time);
}
getCurrentSkip() {
return GM_getValue("currentSkip") || 0;
}
getCurrent() {
return GM_getValue("current");
}
setCurrent(episodeUrl) {
GM_setValue("current", episodeUrl);
}
getPrev() {
return GM_getValue("prev");
}
setPrev(episodeUrl) {
GM_setValue("prev", episodeUrl);
}
getNext() {
return GM_getValue("next");
}
setNext(episodeUrl) {
GM_setValue("next", episodeUrl);
}
clean() {
GM_deleteValue("current");
GM_deleteValue("next");
GM_deleteValue("prev");
GM_deleteValue("playing");
GM_deleteValue("currentSkip");
}
}
(function() {
'use strict';
let vivoHandler = new VivoHandler();
let bsHandler = new BsHandler();
})();