все заметки

Прогресс бар для видео (chromium extension)

2020.08.14 (редактировано: 2023.03.25)

Расширение для тех, кто хочет постоянно видеть (а не при наведении на видео) сколько уже просмотренно, и сколько еще осталось посмотреть видеоролик.

chromium extension sourcecode

manifest.json

{\n\t"name": "all-video-progress-bar",\n\t"version": "2020.0.0.1",\n\t"description": "Progress bar for all <video>",\n\t"content_scripts": [{\n\t\t"matches": [\n\t\t\t"*://*/*"\n\t\t],\n\t\t"js": [\n\t\t\t"content_scripts.js"\n\t\t]\n\t}],\n\t"permissions": [\n\t\t"activeTab"\n\t],\n\t"browser_action": {},\n\t"manifest_version": 2\n}\n

content_scripts.js

/*\n* all-video-progress-bar v2020.0.0.1\n*\n* */\n\nvar doc = document.documentElement,\n\tbarHeight = 4,\n\ttag = 'all-video-progress-bar';\n\nfunction offset(element) {\n\tvar rect = element.getBoundingClientRect();\n\trect.offsetX = rect.left + window.pageXOffset - doc.clientLeft;\n\trect.offsetY = rect.top + window.pageYOffset - doc.clientTop + rect.height;\n\trect.duration = element.duration;\n\trect.currentTime = element.currentTime;\n\trect.secondpx = rect.width / element.duration;\n\treturn rect;\n}\n\n/*\nchanges to the DOM? new data with <VIDEO> tag?\n*/\nconst observer = new MutationObserver( list => {\n\tconst found = [];\n\n\tfor (const { addedNodes } of list) {\n\t\tfor (const node of addedNodes) {\n\t\t\tif (node.tagName && node.tagName === 'VIDEO') {\n\t\t\t\tfound.push(node);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (found.length) {\n\t\taddBar();\n\t}\n\n});\n\n/*\nStart observing the body\n*/\nobserver.observe(document.querySelector('body'), {\n\tchildList: true,\n\tsubtree: true\n});\n\nfunction addBar() {\n\n\tvar video = document.querySelectorAll('video');\n\n\tfor (let i = 0, ic = video.length; i < ic; i++) {\n\n\t\tif (video[i].getAttribute(tag)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tvideo[i].setAttribute(tag, true);\n\n\t\t['progress', 'play', 'loadeddata', 'canplay', 'load'].forEach(event => video[i].addEventListener(event, function () {\n\n\t\t\tif (video[i].getAttribute(tag + '-load')) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlet rect = offset(video[i]);\n\t\t\tif (isNaN(rect.duration)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvideo[i].setAttribute(tag + '-load', true);\n\n\t\t\tlet interval;\n\n\t\t\t// create drawn bar tag\n\t\t\tvar bar = document.createElement(tag);\n\t\t\tbar.setAttribute('style', 'position: absolute; display: block; height: ' + barHeight + 'px; border: 0; background: #FF0000; z-index: 10000;');\n\t\t\tdocument.body.append(bar);\n\n\t\t\t// drawn bar\n\t\t\tlet timer = function (time) {\n\n\t\t\t\tif (!document.body.contains(video[i])) {\n\t\t\t\t\tif (interval) clearInterval(interval);\n\t\t\t\t\tbar.style.width = '0px';\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\trect = offset(video[i]);\n\t\t\t\tbar.style.width = time * rect.secondpx + 'px';\n\t\t\t\tbar.style.top = (rect.offsetY - barHeight) + 'px';\n\t\t\t\tbar.style.left = rect.offsetX + 'px';\n\t\t\t\tbar.style.maxWidth = rect.width + 'px';\n\t\t\t};\n\n\t\t\tthis.addEventListener("abort", function () {\n\t\t\t\tif (interval) clearInterval(interval);\n\t\t\t\tbar.style.width = '0px';\n\t\t\t});\n\n\t\t\tthis.addEventListener("mouseover", function () {\n\t\t\t\tbar.style.display = 'none';\n\t\t\t});\n\n\t\t\tthis.addEventListener("mouseout", function () {\n\t\t\t\tif (!video[i].paused) {\n\t\t\t\t\tbar.style.display = 'block';\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// show bar & redrawn every 10 milliseconds\n\t\t\tthis.addEventListener("play", function (e) {\n\t\t\t\tbar.style.display = 'block';\n\t\t\t\tif (interval) clearInterval(interval);\n\n\t\t\t\tlet delay = parseInt(rect.duration);\n\t\t\t\tif (delay < 10) delay = 10;\n\n\t\t\t\tinterval = setInterval(function () {\n\t\t\t\t\ttimer(video[i].currentTime);\n\t\t\t\t}, delay);\n\t\t\t});\n\n\t\t\t// hide bar\n\t\t\tthis.addEventListener("pause", function () {\n\t\t\t\tif (interval) clearInterval(interval);\n\t\t\t\tbar.style.display = 'none';\n\t\t\t});\n\n\t\t\t// change width bar\n\t\t\tthis.addEventListener("seeking", function () {\n\t\t\t\tbar.style.width = video[i].currentTime * rect.secondpx + 'px';\n\t\t\t});\n\n\t\t\tthis.dispatchEvent(new Event("play"));\n\n\t\t}, {once: true}));\n\n\t\tvideo[i].dispatchEvent(new Event('load'));\n\t}\n}\n\naddBar();\n

github

extension result

  • Progress bar for Youtube video
  • Progress bar for Vimeo video
  • Progress bar for ...