您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
From the creator of SpotOn, a Spotify Overhaul, I bring you this! Addition of a video playback progress-bar at bottom of an Instagram video (Currently set as purple, with a inverted background, but can be changed!). Video controls, an always on dark theme and some other neat features.
// ==UserScript== // @name InstaHaul // @icon https://t3.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url=http://instagram.com&size=256 // @version 1.0.1 // @license MIT // @author Kami // @nameplace https://github.com/SenpaiHunters/InstaHaul // @description From the creator of SpotOn, a Spotify Overhaul, I bring you this! Addition of a video playback progress-bar at bottom of an Instagram video (Currently set as purple, with a inverted background, but can be changed!). Video controls, an always on dark theme and some other neat features. // @match *://www.instagram.com/* // @exclude *://www.instagram.com/stories/* // @grant none // @run-at document-start // @namespace https://greasyfork.org/users/969665 // ==/UserScript== (function(vael, ie, ee, be, wm) { //===== CONFIGURATION BEGIN ===== var ProgressbarHeight = 4.5; //in pixels. set to zero to hide var ProgressbarColor = "backdrop-filter: invert(70%);"; //e.g. "#fff" or "#e0e0e0" or "cyan" var ProgressbarElapsedColor = "#7c3aed"; var disableVideoLoop = false; //===== CONFIGURATION END ===== function addBar(a, b) { if (disableVideoLoop) ie = this.parentNode.parentNode.parentNode.parentNode.lastElementChild; a = "aivp" + (new Date()).getTime(); b = a + "bar"; ee = document.createElement("DIV"); ee.id = a; ee.innerHTML = `<style> #${a} { position: absolute; opacity: .66; left: 0; right: 0; bottom: 0; height: ${ProgressbarHeight}px; background: ${ProgressbarColor} backdrop-filter: invert(100%); } #${b} { width: 0; height: 100%; background: ${ProgressbarElapsedColor} } </style><div id="${b}"></div>`; wm.set(this, be = ee.lastElementChild); this.parentNode.insertBefore(ee, this); this.removeEventListener("canplay", addBar); } wm = new WeakMap; vael = HTMLVideoElement.prototype.addEventListener; HTMLVideoElement.prototype.addEventListener = function() { var res; ((ve, tm, be) => { function updBar() { be.style.width = Math.ceil((ve.currentTime / ve.duration) * ee.offsetWidth) + "px"; } function startTimer(ev) { if (!be) be = wm.get(this); if (disableVideoLoop) ve.loop = false; if (!tm) tm = setInterval(updBar, 100); } function stopTimer(ev) { if (ev.type === "ended") { be.style.width = "100%"; if (disableVideoLoop) ie.click(); } clearInterval(tm); tm = 0; } res = vael.apply(ve, arguments); if (!ve.attributes["aivp_done"]) { ve.setAttribute("aivp_done", "1"); vael.call(ve, "canplay", addBar); vael.call(ve, "play", startTimer); vael.call(ve, "playing", startTimer); vael.call(ve, "waiting", stopTimer); vael.call(ve, "pause", stopTimer); vael.call(ve, "ended", stopTimer); } })(this); return res; }; })(); document.addEventListener('DOMContentLoaded', () => { document.body.style = "background-color: #000"; }); function main(){ let url = new URL('/?hl=en&theme=dark'); if(!url.searchParams.get("theme")){ url.searchParams.append("theme", "dark"); window.location.replace(url); } } (function() { 'use strict'; main(); })(); // Dark mode on Insta document.addEventListener('DOMContentLoaded', () => { document.body.style = "background-color: #000000"; }); function main(){ let url = new URL(window.location.href); if(!url.searchParams.get("theme")){ url.searchParams.append("theme", "dark"); window.location.replace(url); } } (function() { 'use strict'; main(); })(); (function() { 'use strict'; let videoObserver = new MutationObserver(function(mutations) { mutations = Array.from(mutations); function videoClassCount(removedNodes) { return Array.from(removedNodes) .filter(node => node.classList && node.classList.contains('_8jZFn')).length; } // Check for the play button to be removed, i.e. the video is being played let videoMutations = mutations .filter(m => m.removedNodes && videoClassCount(m.removedNodes) > 0); if(videoMutations.length === 0) return; videoMutations.forEach(m => { // The <video/> element should be before the removed button var video = m.previousSibling; if (video && video.tagName && video.tagName.toLowerCase() == 'video') { if (!video.controls) { // Add native video controls video.controls = 'controls'; // Remove overlay let article = video.closest('article'); article.querySelectorAll('.PyenC, .fXIG0').forEach(trash => { trash.parentNode.removeChild(trash); }); // Keep volume value in localStorage video.volume = localStorage.getItem('video_volume') || 1; video.onvolumechange = (event) => { localStorage.setItem('video_volume', event.target.volume); }; } if (!video.loop) { video.loop = true; } } }); }).observe(document.body, { childList: true, subtree: true, attributes: false, characterData: false }); })();