diff --git a/package.json b/package.json index f421378..2725202 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ultravidify", - "version": "4.2.1", + "version": "4.2.3", "description": "Aspect ratio fixer for youtube that works around some people's disability to properly encode 21:9 (and sometimes, 16:9) videos.", "author": "Tamius Han ", "scripts": { @@ -13,7 +13,7 @@ "build-edge:dev": "cross-env NODE_ENV=development BROWSER=edge webpack --hide-modules", "build-zip": "node scripts/build-zip.js", "watch": "npm run build -- --watch", - "watch-chrome": "npm run build-chrome-- --watch", + "watch-chrome": "npm run build-chrome -- --watch", "watch-edge": "npm run build-edge -- --watch", "watch:dev": "cross-env HMR=true npm run build:dev -- --watch", "watch-chrome:dev": "cross-env HMR=true npm run build-chrome:dev -- --watch", diff --git a/src/ext/conf/Debug.js b/src/ext/conf/Debug.js index 2c6cb5d..9c3e9bf 100644 --- a/src/ext/conf/Debug.js +++ b/src/ext/conf/Debug.js @@ -1,6 +1,6 @@ // Set prod to true when releasing -const _prod = true; -// const _prod = false; +// const _prod = true; +const _prod = false; var Debug = { // performanceMetrics: true, // should not be affected by debug.debug in order to allow benchmarking of the impact logging in console has @@ -19,7 +19,7 @@ var Debug = { // flushStoredSettings: false, // playerDetect: true, // periodic: true, - // videoRescan: true, + // // videoRescan: true, // mousemove: true, // arDetect: { // edgeDetect: true diff --git a/src/ext/lib/ar-detect/ArDetector.js b/src/ext/lib/ar-detect/ArDetector.js index 37bbe18..8a35f14 100644 --- a/src/ext/lib/ar-detect/ArDetector.js +++ b/src/ext/lib/ar-detect/ArDetector.js @@ -765,22 +765,34 @@ class ArDetector { if(Debug.debug && Debug.debugArDetect){ console.log(`%c[ArDetect::frameCheck] Triggering aspect ration change! new ar: ${newAr}`, "color: #aaf"); } - this.processAr(newAr); // we also know edges for guardline, so set them. // we need to be mindful of fallbackMode though - if (!this.fallbackMode) { - this.guardLine.setBlackbar({top: edgePost.guardLineTop, bottom: edgePost.guardLineBottom}); - } else { - if (this.conf.player.dimensions){ - this.guardLine.setBlackbarManual({ - top: this.settings.active.arDetect.fallbackMode.noTriggerZonePx, - bottom: this.conf.player.dimensions.height - this.settings.active.arDetect.fallbackMode.noTriggerZonePx - 1 - },{ - top: edgePost.guardLineTop + this.settings.active.arDetect.guardLine.edgeTolerancePx, - bottom: edgePost.guardLineBottom - this.settings.active.arDetect.guardLine.edgeTolerancePx - }) + // if edges are okay and not invalid, we also + // allow automatic aspect ratio correction. If edges + // are bogus, we remain aspect ratio unchanged. + try { + if (!this.fallbackMode) { + // throws error if top/bottom are invalid + this.guardLine.setBlackbar({top: edgePost.guardLineTop, bottom: edgePost.guardLineBottom}); + } else { + if (this.conf.player.dimensions){ + this.guardLine.setBlackbarManual({ + top: this.settings.active.arDetect.fallbackMode.noTriggerZonePx, + bottom: this.conf.player.dimensions.height - this.settings.active.arDetect.fallbackMode.noTriggerZonePx - 1 + },{ + top: edgePost.guardLineTop + this.settings.active.arDetect.guardLine.edgeTolerancePx, + bottom: edgePost.guardLineBottom - this.settings.active.arDetect.guardLine.edgeTolerancePx + }) + } } + + this.processAr(newAr); + } catch (e) { + // edges weren't gucci, so we'll just reset + // the aspect ratio to defaults + this.guardline.reset(); + this.conf.resizer.setAr({type: AspectRatio.Automatic, ratio: this.getDefaultAr()}); } // } diff --git a/src/ext/lib/ar-detect/GuardLine.js b/src/ext/lib/ar-detect/GuardLine.js index 09016f1..5d4cd89 100644 --- a/src/ext/lib/ar-detect/GuardLine.js +++ b/src/ext/lib/ar-detect/GuardLine.js @@ -34,9 +34,7 @@ class GuardLine { // to odstrani vse neveljavne nastavitve in vse možnosti, ki niso smiselne // this removes any configs with invalid values or values that dont make sense if (bbTop < 0 || bbBottom >= this.conf.canvas.height ){ - console.log("%c[GuardLine::setBlackbar] INVALID SETTINGS IN GUARDLINE","background: #000; color: #fff") - this.reset(); - return; + throw "INVALID_SETTINGS_IN_GUARDLINE" } this.blackbar = { diff --git a/src/ext/lib/ar-detect/edge-detect/EdgeDetect.js b/src/ext/lib/ar-detect/edge-detect/EdgeDetect.js index d369a2a..74a7d47 100644 --- a/src/ext/lib/ar-detect/edge-detect/EdgeDetect.js +++ b/src/ext/lib/ar-detect/edge-detect/EdgeDetect.js @@ -247,91 +247,91 @@ class EdgeDetect{ var bottomEdgeCount = 0; try { - for (const sample of samples.res_top){ - blackEdgeViolation = false; // reset this - - // determine our bounds. Note that sample.col is _not_ corrected for imageData, but halfSample is - sampleStart = (sample.col << 2) - this.halfSample; - - if(sampleStart < 0) - sampleStart = 0; - - sampleEnd = sampleStart + this.sampleWidthBase; - if(sampleEnd > this.conf.canvasImageDataRowLength) - sampleEnd = this.conf.canvasImageDataRowLength; - - // calculate row offsets for imageData array - sampleRow_black = (sample.black - this.settings.active.arDetect.edgeDetection.edgeTolerancePx - 1) * this.conf.canvasImageDataRowLength; - sampleRow_color = (sample.black + this.settings.active.arDetect.edgeDetection.edgeTolerancePx) * this.conf.canvasImageDataRowLength; - - // že ena kršitev črnega roba pomeni, da kandidat ni primeren - // even a single black edge violation means the candidate is not an edge - loopEnd = sampleRow_black + sampleEnd; + for (const sample of samples.res_top){ + blackEdgeViolation = false; // reset this + + // determine our bounds. Note that sample.col is _not_ corrected for imageData, but halfSample is + sampleStart = (sample.col << 2) - this.halfSample; + + if(sampleStart < 0) + sampleStart = 0; + + sampleEnd = sampleStart + this.sampleWidthBase; + if (sampleEnd > this.conf.canvasImageDataRowLength) + sampleEnd = this.conf.canvasImageDataRowLength; + + // calculate row offsets for imageData array + sampleRow_black = (sample.black - this.settings.active.arDetect.edgeDetection.edgeTolerancePx - 1) * this.conf.canvasImageDataRowLength; + sampleRow_color = (sample.black + this.settings.active.arDetect.edgeDetection.edgeTolerancePx) * this.conf.canvasImageDataRowLength; + + // že ena kršitev črnega roba pomeni, da kandidat ni primeren + // even a single black edge violation means the candidate is not an edge + loopEnd = sampleRow_black + sampleEnd; - if(Debug.debugCanvas.enabled){ - blackEdgeViolation = this._blackbarTest_dbg(image, sampleRow_black + sampleStart, loopEnd); - } else { - blackEdgeViolation = this._blackbarTest(image, sampleRow_black + sampleStart, loopEnd); - } + if (Debug.debugCanvas.enabled){ + blackEdgeViolation = this._blackbarTest_dbg(image, sampleRow_black + sampleStart, loopEnd); + } else { + blackEdgeViolation = this._blackbarTest(image, sampleRow_black + sampleStart, loopEnd); + } - // če je bila črna črta skrunjena, preverimo naslednjega kandidata - // if we failed, we continue our search with the next candidate - if (blackEdgeViolation) { - continue; - } - - detections = 0; - loopEnd = sampleRow_color + sampleEnd; + // če je bila črna črta skrunjena, preverimo naslednjega kandidata + // if we failed, we continue our search with the next candidate + if (blackEdgeViolation) { + continue; + } + + detections = 0; + loopEnd = sampleRow_color + sampleEnd; - if(Debug.debugCanvas.enabled) { - this._imageTest_dbg(image, sampleRow_color + sampleStart, loopEnd, sample.black, edgeCandidatesTop) - } else { - this._imageTest(image, sampleRow_color + sampleStart, loopEnd, sample.black, edgeCandidatesTop); - } - } - - for (const sample of samples.res_bottom){ - blackEdgeViolation = false; // reset this - - // determine our bounds. Note that sample.col is _not_ corrected for imageData, but this.halfSample is - sampleStart = (sample.col << 2) - this.halfSample; - - if(sampleStart < 0) - sampleStart = 0; - - sampleEnd = sampleStart + this.sampleWidthBase; - if(sampleEnd > this.conf.canvasImageDataRowLength) - sampleEnd = this.conf.canvasImageDataRowLength; - - // calculate row offsets for imageData array - sampleRow_black = (sample.black + this.settings.active.arDetect.edgeDetection.edgeTolerancePx + 1) * this.conf.canvasImageDataRowLength; - sampleRow_color = (sample.black - this.settings.active.arDetect.edgeDetection.edgeTolerancePx) * this.conf.canvasImageDataRowLength; - - // že ena kršitev črnega roba pomeni, da kandidat ni primeren - // even a single black edge violation means the candidate is not an edge - loopEnd = sampleRow_black + sampleEnd; - - if(Debug.debugCanvas.enabled){ - blackEdgeViolation = this._blackbarTest_dbg(image, sampleRow_black + sampleStart, loopEnd); - } else { - blackEdgeViolation = this._blackbarTest(image, sampleRow_black + sampleStart, loopEnd); + if (Debug.debugCanvas.enabled) { + this._imageTest_dbg(image, sampleRow_color + sampleStart, loopEnd, sample.black, edgeCandidatesTop) + } else { + this._imageTest(image, sampleRow_color + sampleStart, loopEnd, sample.black, edgeCandidatesTop); + } } - // če je bila črna črta skrunjena, preverimo naslednjega kandidata - // if we failed, we continue our search with the next candidate - if (blackEdgeViolation) { - continue; - } - - detections = 0; - loopEnd = sampleRow_color + sampleEnd; + for (const sample of samples.res_bottom){ + blackEdgeViolation = false; // reset this + + // determine our bounds. Note that sample.col is _not_ corrected for imageData, but this.halfSample is + sampleStart = (sample.col << 2) - this.halfSample; + + if(sampleStart < 0) + sampleStart = 0; + + sampleEnd = sampleStart + this.sampleWidthBase; + if(sampleEnd > this.conf.canvasImageDataRowLength) + sampleEnd = this.conf.canvasImageDataRowLength; + + // calculate row offsets for imageData array + sampleRow_black = (sample.black + this.settings.active.arDetect.edgeDetection.edgeTolerancePx + 1) * this.conf.canvasImageDataRowLength; + sampleRow_color = (sample.black - this.settings.active.arDetect.edgeDetection.edgeTolerancePx) * this.conf.canvasImageDataRowLength; + + // že ena kršitev črnega roba pomeni, da kandidat ni primeren + // even a single black edge violation means the candidate is not an edge + loopEnd = sampleRow_black + sampleEnd; + + if(Debug.debugCanvas.enabled){ + blackEdgeViolation = this._blackbarTest_dbg(image, sampleRow_black + sampleStart, loopEnd); + } else { + blackEdgeViolation = this._blackbarTest(image, sampleRow_black + sampleStart, loopEnd); + } + + // če je bila črna črta skrunjena, preverimo naslednjega kandidata + // if we failed, we continue our search with the next candidate + if (blackEdgeViolation) { + continue; + } + + detections = 0; + loopEnd = sampleRow_color + sampleEnd; - if(Debug.debugCanvas.enabled) { - this._imageTest_dbg(image, sampleRow_color + sampleStart, loopEnd, sample.black, edgeCandidatesBottom); - } else { - this._imageTest(image, sampleRow_color + sampleStart, loopEnd, sample.black, edgeCandidatesBottom); + if(Debug.debugCanvas.enabled) { + this._imageTest_dbg(image, sampleRow_color + sampleStart, loopEnd, sample.black, edgeCandidatesBottom); + } else { + this._imageTest(image, sampleRow_color + sampleStart, loopEnd, sample.black, edgeCandidatesBottom); + } } - } } catch (e) { console.log("\n\nuwu fucky wucky:", e, "\n\n") } @@ -623,7 +623,9 @@ class EdgeDetect{ if (reverseSearchDirection) { increment = -this.conf.canvasImageDataRowLength; - arrayStart = bottom - this.conf.canvasImageDataRowLength; + // don't subtract this.conf.canvasImageDataRowLength — it has already been accounted for + // when we calculated bottom and top + arrayStart = bottom; arrayEnd = top; // this is a hack so we get pointer-like things rather than values diff --git a/src/ext/lib/comms/CommsServer.js b/src/ext/lib/comms/CommsServer.js index b8f44d0..51a982a 100644 --- a/src/ext/lib/comms/CommsServer.js +++ b/src/ext/lib/comms/CommsServer.js @@ -220,10 +220,13 @@ class CommsServer { this.server.injectCss(message.cssString, sender); return; } - if (message.cmd === 'remove-css') { + if (message.cmd === 'remove-css' || message.cmd === 'eject-css') { this.server.removeCss(message.cssString, sender); return; } + if (message.cmd === 'replace-css') { + this.server.replaceCss(message.oldCssString, message.newCssString, sender); + } if (message.forwardToContentScript) { if (Debug.debug && Debug.comms) { diff --git a/src/ext/lib/video-data/PageInfo.js b/src/ext/lib/video-data/PageInfo.js index 5aeac23..fc2726c 100644 --- a/src/ext/lib/video-data/PageInfo.js +++ b/src/ext/lib/video-data/PageInfo.js @@ -41,6 +41,28 @@ class PageInfo { this.currentZoomScale = 1; } + injectCss(cssString) { + this.comms.sendMessage({ + cmd: 'inject-css', + cssString: cssString + }); + } + + ejectCss(cssString) { + this.comms.sendMessage({ + cmd: 'eject-css', + cssString: cssString + }); + } + + replaceCss(oldCssString, newCssString) { + this.comms.sendMessage({ + cmd: 'replace-css', + newCssString, + oldCssString + }); + } + destroy() { if(Debug.debug || Debug.init){ console.log("[PageInfo::destroy] destroying all videos!") diff --git a/src/ext/lib/video-data/VideoData.js b/src/ext/lib/video-data/VideoData.js index f738985..adf3bfb 100644 --- a/src/ext/lib/video-data/VideoData.js +++ b/src/ext/lib/video-data/VideoData.js @@ -13,6 +13,18 @@ class VideoData { this.pageInfo = pageInfo; this.extensionMode = pageInfo.extensionMode; + this.vdid = (Math.random()*100).toFixed(); + this.userCssClassName = `uw-fuck-you-and-do-what-i-tell-you_${this.vdid}`; + + + // We'll replace cssWatcher (in resizer) with mutationObserver + const observerConf = { + attributes: true, + // attributeFilter: ['style', 'class'], + attributeOldValue: true, + }; + this.observer = new MutationObserver(this.onVideoDimensionsChanged); + this.observer.observe(video, observerConf); // POZOR: VRSTNI RED JE POMEMBEN (arDetect mora bit zadnji) // NOTE: ORDERING OF OBJ INITIALIZATIONS IS IMPORTANT (arDetect needs to go last) @@ -30,12 +42,38 @@ class VideoData { this.resizer.reset(); - this.vdid = (Math.random()*100).toFixed(); if (Debug.init) { console.log("[VideoData::ctor] Created videoData with vdid", this.vdid,"\nextension mode:", this.extensionMode); } this.pageInfo.initMouseActionHandler(this); + + this.video.classList.add(this.userCssClassName); // this also needs to be applied BEFORE we initialize resizer! + } + + onVideoDimensionsChanged(mutationList, observer) { + for (let mutation of mutationList) { + if (mutation.type === 'attributes') { + console.log("video attributes were changed:", mutation) + if (mutation.attributeName === 'class') { + if (!this.video.classList.contains(this.userCssClassName)) { + console.log("class changed!") + // force the page to include our class in classlist, if the classlist has been removed + this.video.classList.add(this.userCssClassName); + + // } else if () { + // this bug should really get + } else { + this.restoreAr(); + } + } else if (mutation.attributeName === 'style' && mutation.attributeOldValue !== this.video.getAttribute('style')) { + console.log("style changed") + // if size of the video has changed, this may mean we need to recalculate/reapply + // last calculated aspect ratio + this.restoreAr(); + } + } + } } firstTimeArdInit(){ diff --git a/src/ext/lib/video-transform/Resizer.js b/src/ext/lib/video-transform/Resizer.js index 33977a3..3681d85 100644 --- a/src/ext/lib/video-transform/Resizer.js +++ b/src/ext/lib/video-transform/Resizer.js @@ -24,8 +24,6 @@ class Resizer { this.stretcher = new Stretcher(this.conf); this.zoom = new Zoom(this.conf); - this.cssCheckDisabled = false; - // load up default values this.correctedVideoDimensions = {}; this.currentCss = {}; @@ -33,16 +31,6 @@ class Resizer { this.currentPlayerStyleString = ""; this.currentCssValidFor = {}; - // restore watchdog. While true, applyCss() tries to re-apply new css until this value becomes false again - // value becomes false when width and height of