Warning: fopen(/www/sites/update.greasyfork.icu/index/store/forever/5e506c6c2402b4a0107743d5fc3c11b3.js): failed to open stream: No space left on device in /www/sites/update.greasyfork.icu/index/scriptControl.php on line 65
// ==UserScript== // @name Enhanced Video Playing Experience for Viu.com // @version 1.2 // @description Automatically Full HD Video Quality (Paid Member) and Disable Auto Playing when the page is randomly reloaded // @match https://www.viu.com/ott/*/vod/* // @icon https://www.google.com/s2/favicons?domain=viu.com // @grant unsafeWindow // @grant window.onurlchange // @namespace https://greasyfork.org/users/371179 // @downloadURL none // ==/UserScript== (function $$() { 'use strict'; if (!document || !document.documentElement) return window.requestAnimationFrame($$); const uWin = window.unsafeWindow || window; if ([document.hidden, window.requestAnimationFrame, Object.defineProperty, window.performance].some(x => x === undefined)) throw 'Your browser is too outdated.'; var navStart = performance.timeOrigin || performance.timing.navigationStart || null; if (navStart === null) throw 'Your browser is too outdated.'; navStart = Math.ceil(navStart); var lastPlayingStatus = null; var settings = {} var falseReloaded = false; var lastUserClickAt = 0; var lastUserClickStatus = 0; var forceQuality = "1080"; const __jver__ = "20210617b"; const isPassiveOptionEnable = window.queueMicrotask?true:false; //here just a simple trick for checking browser is modern or not function pageInit() { var _userPaused = null; Object.defineProperty(settings, 'userPaused', { get() { return _userPaused; }, set(nv) { _userPaused = nv; console.log('[viu] userPaused: ', _userPaused); } }) function doSomething(obj) { //for viu page auto reload ( it is confirmed that the page could randomly reload) if (!obj) return; let { version, datetime, pageVisible, withVideo, userPaused } = obj; if (version != __jver__) return; const isReload = (t) => (t > 0 && t - 2 < navStart && t + 480 > navStart); // max 155ms => 155*3=465 => 480ms if (isReload(datetime) && withVideo) { console.log('[viu] reloaded page', obj) if (userPaused || !pageVisible) settings.userPaused = true; } console.log('[viu] reload time diff: ' + (navStart - datetime) + ' => ' + isReload(datetime)) } var _saveObj = localStorage.__zvpp_unload1__; if (typeof _saveObj == 'string' && _saveObj.length > 0) { var _jObj = null; try { _jObj = JSON.parse(_saveObj); } catch (e) {} if (_jObj) { doSomething(_jObj); } } delete localStorage.__viu_js_fewunaznqjrx__ delete localStorage.__viu_js_fewunaznqjr2__ delete localStorage.__viu_js_fewunaznqjra__ delete localStorage.__zvpp_unload1__ if (localStorage.__zvpp_ver__ !== __jver__) { for (var k in localStorage) { if (k.indexOf('__zvpp_') === 0) localStorage.removeItem(k) } localStorage.__zvpp_ver__ = __jver__ } } function getVideoFromEvent(evt) { return (evt && evt.target && evt.target.nodeName == 'VIDEO') ? evt.target : null; } function hasOffsetParent(v) { return v && v.offsetParent !== null && v.offsetParent.nodeType === 1; //is DOM valid on the page } function noAutoStart(evt) { const video = getVideoFromEvent(evt); if (video) { if (lastUserClickStatus===2) { //do nothing for user click } else if (settings.userPaused === true) { video.autoplay = false; video.pause(); } else { if (lastPlayingStatus === true && document.hidden === true) {} else if (document.hidden === true) { video.autoplay = false; video.pause(); } } } } const delayCall = function(p, f, d) { if (delayCall[p] > 0) clearTimeout(delayCall[p]) delayCall[p] = setTimeout(f, d) } function loader(detection) { return function() { let oldHref = document.location.href, bodyDOM = document.querySelector("body"); const observer = new MutationObserver(function(mutations) { if (oldHref != document.location.href) { oldHref = document.location.href; detection(); window.requestAnimationFrame(function() { let tmp = document.querySelector("body"); if (tmp != bodyDOM) { bodyDOM = tmp; observer.observe(bodyDOM, config); } }) } }); const config = { childList: true, subtree: true }; observer.observe(bodyDOM, config); } } const anyRecentClick=()=>lastUserClickAt + 5000 > +new Date; function pageEnableAutoQualityAtStart() { //default 1080p var cid = 0; var mDate = 0; const TIMEOUT = 8000; // just in case DOM is not found var gn = function(evt) { const video = getVideoFromEvent(evt); if (!video) return; delayCall('$$video_init', function() { if (video.hasAttribute('_viu_js_hooked')) return; video.setAttribute('_viu_js_hooked', '') video.addEventListener('playing', function(evt) { const video = getVideoFromEvent(evt); if (!video) return; delayCall('$$video_playing_switch', function() { if (video.paused === false && hasOffsetParent(video)) { if (document.hidden !== true && settings.userPaused === true) settings.userPaused = false; } }, 300); }, true) video.addEventListener('pause', function(evt) { const video = getVideoFromEvent(evt); if (!video) return; delayCall('$$video_playing_switch', function() { if (video.paused === true && hasOffsetParent(video)) { if (document.hidden !== true && (settings.userPaused === null || settings.userPaused === false)) settings.userPaused = true; } }, 300); }, true) }, 800); //call when the first video event fires if(lastUserClickStatus===1 && lastUserClickAt+5000 > +new Date){ //url change: 2598 1443 1542 1975 //without url change : 561 console.log(`[viu] click and video status change ${+new Date -lastUserClickAt}`) //user perform action and video status changed lastUserClickStatus=2; } if(lastUserClickStatus!=2){ // clear lastUserClickStatus delayCall('$$user_click_action_w38',function(){ if(lastUserClickStatus!==2) lastUserClickStatus=0; },300) }else{ // extend duration of status 2 for 800ms delayCall('$$user_click_action_w38',function(){ if(lastUserClickStatus===2) lastUserClickStatus=0; },800) } //disable autostart noAutoStart(evt); mDate = +new Date + TIMEOUT; var jn = function(btn1080) { //button is found const bool = btn1080.matches(':not([aria-disabled=""]):not([aria-disabled="true"]):not([aria-checked="true"]):not([aria-checked=""])'); if (bool) { btn1080.click(); } } var zn = function() { //query when the video is loading/loaded/ready... if (cid > 0 && mDate < +new Date) { cid = clearInterval(cid); return; } var btn1080 = document.querySelector(`.vjs-menu-item[data-r="${forceQuality}"]`); if (!btn1080) return; if (cid > 0) cid = clearInterval(cid); if (btn1080.matches('[__userscript_viu_loaded]')) return true; btn1080.setAttribute('__userscript_viu_loaded', 'true'); window.requestAnimationFrame(() => jn(btn1080)); // prevent too fast } if (cid > 0) cid = clearInterval(cid); if (!zn()) cid = setInterval(zn, 33); } document.addEventListener('loadstart', gn, true) document.addEventListener('durationchange', gn, true) document.addEventListener('loadedmetadata', gn, true) document.addEventListener('loadeddata', gn, true) //document.addEventListener('progress', gn, true) document.addEventListener('canplay', gn, true) //document.addEventListener('canplaythrough', gn, true) } const detection1 = function() { console.log('[viu] viu.com reloaded url - detection #1') } const detection2 = function() { console.log('[viu] viu.com reloaded url - detection #2') } const detection3 = function(info) { console.log('[viu] viu.com reloaded url - detection #3', info) } function handleBeforeUnload(event) { //core event handler for detection of false reloading console.log('[viu] viu.com reloaded url - detection #4') const video = document.querySelector('video#viu-player_html5_api') || document.querySelector('video'); var saveObj = {}; saveObj.version = __jver__; saveObj.datetime = +new Date(); saveObj.pageVisible = !(document.hidden === true); saveObj.withVideo = (video && video.nodeName == "VIDEO") saveObj.userPaused = (settings.userPaused === true); localStorage.__zvpp_unload1__ = JSON.stringify(saveObj); navStart = (+new Date) - 1; // Cancel the event //event.preventDefault(); //return (event.returnValue = ""); // Legacy method for cross browser support } function handleVisibilityChange() { //enable if document.hidden exists const video = document.querySelector('video#viu-player_html5_api') || document.querySelector('video'); // just in case if (!video) lastPlayingStatus = null; if (document.hidden === false) { console.log('[viu] page show') } else if (document.hidden === true) { console.log('[viu] page hide') if (video) lastPlayingStatus = !video.paused } else { lastPlayingStatus = null; } } function isMenuBtn(evt) { return evt && evt.target && evt.target.nodeType === 1 && (evt.target.className || "").indexOf('vjs-menu-item') === 0; } function setQualityAfterClick() { delayCall('$$change_video_quality', function() { let attr = document.querySelector('.vjs-menu-item.vjs-selected[data-r]').getAttribute('data-r'); if (+attr > 0) { forceQuality = (+attr).toString(); console.log(`[viu] video quality set at ${attr}`) } }, 300) } pageInit(); pageEnableAutoQualityAtStart(); if (window.onurlchange === null) window.addEventListener('urlchange', detection3, true); // feature is supported window.addEventListener("load", loader(detection1), true); uWin.addEventListener("load", loader(detection2), true); uWin.addEventListener("beforeunload", handleBeforeUnload, true); if (typeof document.hidden !== "undefined") document.addEventListener("visibilitychange", handleVisibilityChange, true); function handleMouseDown(evt) { lastUserClickAt = +new Date; lastUserClickStatus =1; delayCall('$$user_click_action_w38',function(){ if(lastUserClickStatus===1) lastUserClickStatus=0; },5000) if (isMenuBtn(evt)) setQualityAfterClick(); } document.addEventListener("mousedown", handleMouseDown, isPassiveOptionEnable?{ passive: true, capture: true }:true) // Your code here... })(unsafeWindow || window);