diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..155183d --- /dev/null +++ b/.babelrc @@ -0,0 +1,26 @@ +{ + "plugins": [ + ], + "presets": [ + ["@babel/preset-env", { + "useBuiltIns": false, + "targets": { + "esmodules": true, + }, + }] + ] +} +// { +// "plugins": [ +// "@babel/plugin-proposal-optional-chaining" +// ], +// "presets": [ +// ["@babel/preset-env", { +// "useBuiltIns": "usage", +// "targets": { +// // https://jamie.build/last-2-versions +// "browsers": ["> 0.25%", "not ie 11", "not op_mini all"] +// } +// }] +// ] +// } diff --git a/.gitignore b/.gitignore index 606fb8d..809f3e2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ -ultrawidify.zip -ultrawidify-git.zip old/ build/ +/node_modules +/*.log +/dist +/dist-zip +/uw-git_keys diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..070b6cb --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,23 @@ +image: node:current + +cache: + paths: + - node_modules/ + - .yarn + +stages: + - prep + - build + - pack + +install deps: + stage: prep + script: yarn install + +build: + stage: build + script: npm run build + +create zip: + stage: pack + script: npm run build-zip \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index a053d23..42e9f96 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,10 +5,19 @@ "version": "0.2.0", "configurations": [ { - "type": "node", + "name": "Launch addon", + "type": "firefox", "request": "launch", - "name": "Launch Program", - "program": "${file}" + "port":6000, + "reAttach": true, + "addonType": "webExtension", + "addonPath": "${workspaceFolder}/dist", } - ] + ], + "firefox": { + "executable": "/usr/bin/firefox-developer-edition", + "firefoxArgs": [ + "--start-debugger-server" + ] + } } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index f91baed..0531e48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,38 @@ # Changelog +## v4.x + +### Plans for the future + +* Allow users to set autodetection sensitivity +* Settings page looks ugly af right now. Maybe fix it some time later + +### v4.0.0 (upcoming) + +* Using vue for popup and settings page +* Editable shortcuts +* Per-site controls +* You can now select which specific video on the page you control, provided each video is in its separate iframe +* Basic mode added +* Rewrote keyboard shortcuts and changed how they're handled. Massively. +* Fixed the bug where saving settings wouldn't work +* Fixed the bug where autodetection didn't calculate aspect ratio correctly. This bug would manifest in this extension cropping too much video even in cases where edge between letterbox and video was clearly defined. +* Implemented/improved black frame detection +* Autodetection now differentiates between legitimate letterbox and linear gradients. This should prevent incorrect auto-cropping on videos that look similar to IGN's [Hollow Knight](https://www.youtube.com/watch?v=hg25ONutphA) review. + ## v3.x -### v3.2.2 +~~### v3.3.0~~ + +~~This will probably get promoted to 4.0, continuing the trend of version something.3 not happening. Eulul~~ + +* ~~Basic mode added~~ +* ~~Per-site controls in popup (to control embedded videos)~~ +* ~~Rewrote keyboard shortcuts and changed how they're handled. Massively.~~ + +Never happened, got bumped to 4.0.0. + +### v3.2.2 (current) * Pan event listener now gets properly unbound * Fixed 'reset zoom' button in popup diff --git a/README-AMO.md b/README-AMO.md new file mode 100644 index 0000000..2769728 --- /dev/null +++ b/README-AMO.md @@ -0,0 +1,21 @@ +# Build guide for AMO + +## Build platform + +The extension is built on a PC running Manjaro Linux. Yarn is the package manager of choice. + +Yarn version: 1.16.0 +Node version: v11.15.0 + + +## Installing dependencies + +`yarn install --frozen-lockfile` + +According to Yarn documentation, that should install the exact version of dependencies that the extension is using. + +## Reproducing build + +`npm run build` + +The compiled code pops up in /dist. \ No newline at end of file diff --git a/README.md b/README.md index 99f2306..f2c8d1e 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,20 @@ # Ultrawidify — aspect ratio fixer for youtube and netflix +## Super TL;DR: I'm just looking for the install links, thanks + +[Firefox](https://addons.mozilla.org/en/firefox/addon/ultrawidify/), [Chrome](https://chrome.google.com/webstore/detail/ultrawidify/dndehlekllfkaijdlokmmicgnlanfjbi), [Edge](#edge-speficic-limitations-important). + ## TL;DR If you own an ultrawide monitor, you have probably noticed that sometimes videos aren't encoded properly — they feature black bars on all four sides. This could happen because someone was incompetent (note: as far as youtube is concerned, improperly rendered videos might be due to youtube's implementation of certain new features). The extension kinda fixes that by doing this: ![Demo](img-demo/example-httyd2.png "Should these black bars be here? No [...] But an ultrawide user never forgets.") + + ## Known issues * Netflix autodetection not working in Chrome, wontfix as issue is fundamentally unfixable. -* Keyboard shortcut for automatic detection (A) doesn't really work for some reason. * Everything reported in [issues](https://github.com/xternal7/ultrawidify/issues) ### Limitations @@ -17,7 +22,8 @@ If you own an ultrawide monitor, you have probably noticed that sometimes videos * Unclear how extension handles sites with more than one video per page. * Autodetection is only correct 95% of the time, most of the time. * That new stretching mode wasn't thoroughly tested yet. Issues may be present. (Same with zoom) -* Enabling extension everywhere (as opposed to whitelisted sites) could break some websites. +* Enabling extension everywhere (as opposed to whitelisted sites) could break some websites. +* Edge has ### Features @@ -45,9 +51,15 @@ You can download this extension from Firefox' and Chrome's extension stores: * [Firefox](https://addons.mozilla.org/en/firefox/addon/ultrawidify/) * [Chrome](https://chrome.google.com/webstore/detail/ultrawidify/dndehlekllfkaijdlokmmicgnlanfjbi) -### Beggathon +This extension also has a version for Microsoft Edge, but that requires a bit more effort. [See notes first](#edge-speficic-limitations-important). -Working on this extension takes time, coffee and motivation. If you want to buy me a beer or something, you can [use this link to send me motivation](https://www.paypal.me/tamius). **Any donations are well appreciated.** +# Beggathon (donations) + +If you want to support this project, please consider a donation. Working on this extension takes time, money, coffee and motivation. Sometimes also [a very precise amount of alco](https://xkcd.com/323/). + +You can make a donation [via Paypal](https://www.paypal.me/tamius). + +**Any donation — no matter how big or small — is well appreciated. Thanks.**   @@ -211,6 +223,8 @@ is currently not possible. Settings page for this extension has been disabled so However, I do plan on implementing this feature. Hopefully by the end of the year, but given how consistently I've been breaking self-imposed deadlines and goals for this extension don't hold your breath. After all, [Hofstadter's a bitch](https://en.wikipedia.org/wiki/Hofstadter%27s_law). + + ## Plans for the future 1. Handle porting of extension settings between versions. @@ -220,24 +234,54 @@ However, I do plan on implementing this feature. Hopefully by the end of the yea 5. figure the best way to do GUI (injecting buttons into the player bar is not a good way. Been there, done that, each site has its own way and some appear to be impossible). ~~Might get bumped to be released alongside #2~~no it wont lol 6. Improvements to automatic aspect ratio detection + ## Installing ### Permanent install / stable [Latest stable for Firefox — download from AMO](https://addons.mozilla.org/en/firefox/addon/ultrawidify/) -[Latest stafle for Chrome — download from Chrome store](https://chrome.google.com/webstore/detail/ultrawidify/dndehlekllfkaijdlokmmicgnlanfjbi) +[Latest stable for Chrome — download from Chrome store](https://chrome.google.com/webstore/detail/ultrawidify/dndehlekllfkaijdlokmmicgnlanfjbi) ### Installing the current, github version +Requirements: npm, yarn. + 1. Clone this repo +2. run `yarn install` +3. run `npm run watch:dev` + +TODO: see if #3 already loads the extension in FF + 2. Open up Firefox 3. Go to `about:debugging` 4. Add temporary addon -5. Browse to wherever you saved it and select manifest.json +5. Select `${ultrawidify_folder}/dist/manifest.json` -## Changelog + +# Edge-specific limitations (IMPORTANT!) + +For various reasons — most notably, I refuse to pay Microsoft €14 for the privilege of developing shit for their outright broken browser (and in addition to that, the extension needs to go through review process as well) — this extension isn't going to appear on Microsoft Store. (And I do not permit anyone else to do that in my name either). Full rant on why I've made this decision can be found [here](https://github.com/xternal7/ultrawidify/issues/14#issuecomment-424903335). + +As a result, you'll have to download the extension and install it manually. This approach has some downsides. + +1. You'll get this popup after starting Edge. If you've already opened Youtube or Netflix, **you will have to reload the page (or navigate to somewhere else) in order for extension to start.** +![slika](https://user-images.githubusercontent.com/12505802/46114175-05912200-c1e1-11e8-91c7-2217f5bf79e3.png) + +2. Certain WebExtension APIs that I rely on are outright broken in Edge. This bug would cause global extension settings (tab: Extension settings) and per-site settings (tab: Site settings) to reset to default values every time you'd open the popup. As a result, _Extension settings_ and _Site settings_ tabs are disabled in Edge: +![Feast on dem popup](https://user-images.githubusercontent.com/12505802/46113923-d1693180-c1df-11e8-82f0-ad64cbc57558.png) +Unfortunate consequence of this is that you won't be able to enable this extension for sites other than Youtube and Netflix, but then again. Let's be honest. You're only using Edge for Netflix, so that's probably no big deal for you. + +**It's also worth noting that I'm not actively maintaining the Edge fork, so it's a few versions behind.** + +## Installing Ultrawidify in M$ Edge + +1. Download the zip file from [here](https://github.com/xternal7/ultrawidify/tree/master/releases/edge) +2. Extract contents of the zip file in some folder. It really doesn't matter where, just keep it somewhere that won't be in your way when using your computer. +3. Follow the steps in [this guide](https://docs.microsoft.com/en-us/microsoft-edge/extensions/guides/adding-and-removing-extensions) + +# Changelog see changelog.md -todo: add link to changelog.md here \ No newline at end of file +todo: add link to changelog.md here diff --git a/js/conf/Debug.js b/js/conf/Debug.js deleted file mode 100644 index 3228b30..0000000 --- a/js/conf/Debug.js +++ /dev/null @@ -1,49 +0,0 @@ -// Set prod to true when releasing -_prod = true; -// _prod = false; - -Debug = { - init: true, - debug: false, - keyboard: true, - debugResizer: true, - debugArDetect: true, - debugStorage: false, - comms: false, - // showArDetectCanvas: true, - flushStoredSettings: true, - // flushStoredSettings: false, - playerDetectDebug: true, - periodic: true, - videoRescan: true, - arDetect: { - edgeDetect: true - }, - canvas: { - debugDetection: true - }, - debugCanvas: { - // enabled: true, - // guardLine: true - enabled: false, - guardLine: false - } -} - -if(_prod){ - __disableAllDebug(Debug); -} - -function __disableAllDebug(obj) { - for(key in obj) { - if (obj.hasOwnProperty(key) ){ - if(obj[key] instanceof Object) - __disableAllDebug(obj[key]); - else - obj[key] = false; - } - } -} - -if(Debug.debug) - console.log("Guess we're debugging ultrawidify then. Debug.js must always load first, and others must follow.\nLoading: Debug.js"); diff --git a/js/conf/ExtensionConf.js b/js/conf/ExtensionConf.js deleted file mode 100644 index 41c003d..0000000 --- a/js/conf/ExtensionConf.js +++ /dev/null @@ -1,246 +0,0 @@ -if(Debug.debug) - console.log("Loading: ExtensionConf.js"); - -var ExtensionConf = { - extensionMode: "whitelist", // how should this extension work? - // 'blacklist' - work everywhere except blacklist - // 'whitelist' - only work on whitelisted sites - // 'disabled' - work nowhere - arDetect: { - mode: "blacklist", // how should autodetection work? - // 'blacklist' - work by default, problem sites need to be blocked - // 'whitelist' - only work if site has been specifically approved - // 'disabled' - don't work at all - disabledReason: "", // if automatic aspect ratio has been disabled, show reason - allowedMisaligned: 0.05, // top and bottom letterbox thickness can differ by this much. - // Any more and we don't adjust ar. - allowedArVariance: 0.075, // amount by which old ar can differ from the new (1 = 100%) - timer_playing: 666, // we trigger ar this often (in ms) under this conditions - timer_paused: 3000, - timer_error: 3000, - timer_minimumTimeout: 5, // but regardless of above, we wait this many msec before retriggering - autoDisable: { // settings for automatically disabling the extension - maxExecutionTime: 6000, // if execution time of main autodetect loop exceeds this many milliseconds, - // we disable it. - consecutiveTimeoutCount: 5, // we only do it if it happens this many consecutive times - - // FOR FUTURE USE - consecutiveArResets: 5 // if aspect ratio reverts immediately after AR change is applied, we disable everything - }, - hSamples: 640, - vSamples: 360, - // samplingInterval: 10, // we sample at columns at (width/this) * [ 1 .. this - 1] - blackLevel_default: 10, // everything darker than 10/255 across all RGB components is considered black by - // default. blackLevel can decrease if we detect darker black. - blackbarTreshold: 16, // if pixel is darker than blackLevel + blackbarTreshold, we count it as black - // on 0-255. Needs to be fairly high (8 might not cut it) due to compression - // artifacts in the video itself - variableBlackbarTresholdOptions: { // In case of poor bitrate videos, jpeg artifacts may cause us issues - // FOR FUTURE USE - enabled: true, // allow increasing blackbar threshold - disableArDetectOnMax: true, // disable autodetection when treshold goes over max blackbar treshold - maxBlackbarTreshold: 48, // max threshold (don't increase past this) - thresholdStep: 8, // when failing to set aspect ratio, increase treshold by this much - increaseAfterConsecutiveResets: 2 // increase if AR resets this many times in a row - }, - staticSampleCols: 9, // we take a column at [0-n]/n-th parts along the width and sample it - randomSampleCols: 0, // we add this many randomly selected columns to the static columns - staticSampleRows: 9, // forms grid with staticSampleCols. Determined in the same way. For black frame checks - guardLine: { // all pixels on the guardline need to be black, or else we trigger AR recalculation - // (if AR fails to be recalculated, we reset AR) - enabled: true, - ignoreEdgeMargin: 0.20, // we ignore anything that pokes over the black line this close to the edge - // (relative to width of the sample) - imageTestTreshold: 0.1, // when testing for image, this much pixels must be over blackbarTreshold - edgeTolerancePx: 2, // black edge violation is performed this far from reported 'last black pixel' - edgeTolerancePercent: null // unused. same as above, except use % of canvas height instead of pixels - }, - fallbackMode: { - enabled: true, - safetyBorderPx: 5, // determines the thickness of safety border in fallback mode - noTriggerZonePx: 8 // if we detect edge less than this many pixels thick, we don't correct. - }, - arSwitchLimiter: { // to be implemented - switches: 2, // we can switch this many times - period: 2.0 // per this period - }, - edgeDetection: { - sampleWidth: 8, // we take a sample this wide for edge detection - detectionTreshold: 4, // sample needs to have this many non-black pixels to be a valid edge - singleSideConfirmationTreshold: 0.3, // we need this much edges (out of all samples, not just edges) in order - // to confirm an edge in case there's no edges on top or bottom (other - // than logo, of course) - logoTreshold: 0.15, // if edge candidate sits with count greater than this*all_samples, it can't be logo - // or watermark. - edgeTolerancePx: 2, // we check for black edge violation this far from detection point - edgeTolerancePercent: null, // we check for black edge detection this % of height from detection point. unused - middleIgnoredArea: 0.2, // we ignore this % of canvas height towards edges while detecting aspect ratios - minColsForSearch: 0.5, // if we hit the edge of blackbars for all but this many columns (%-wise), we don't - // continue with search. It's pointless, because black edge is higher/lower than we - // are now. (NOTE: keep this less than 1 in case we implement logo detection) - edgeTolerancePx: 1, // tests for edge detection are performed this far away from detected row - }, - pillarTest: { - ignoreThinPillarsPx: 5, // ignore pillars that are less than this many pixels thick. - allowMisaligned: 0.05 // left and right edge can vary this much (%) - }, - textLineTest: { - nonTextPulse: 0.10, // if a single continuous pulse has this many non-black pixels, we aren't dealing - // with text. This value is relative to canvas width (%) - pulsesToConfirm: 10, // this is a treshold to confirm we're seeing text. - pulsesToConfirmIfHalfBlack: 5, // this is the treshold to confirm we're seeing text if longest black pulse - // is over 50% of the canvas width - testRowOffset: 0.02 // we test this % of height from detected edge - } - }, - arChange: { - samenessTreshold: 0.025, // if aspect ratios are within 2.5% within each other, don't resize - }, - zoom: { - minLogZoom: -1, - maxLogZoom: 3, - announceDebounce: 200 // we wait this long before announcing new zoom - }, - miscFullscreenSettings: { - videoFloat: "center", - mousePan: { - enabled: false - }, - defaultAr: "original", - }, - stretch: { - initialMode: 0, // 0 - no stretch, 1 - basic, 2 - hybrid, 3 - conditional - conditionalDifferencePercent: 0.05 // black bars less than this wide will trigger stretch - // if mode is set to '1'. 1.0=100% - }, - resizer: { - setStyleString: { - maxRetries: 3, - retryTimeout: 200 - } - }, - pageInfo: { - timeouts: { - urlCheck: 200, - rescan: 1500 - } - }, - colors:{ - // criticalFail: "background: #fa2; color: #000" - }, - keyboard: { - shortcuts: { - // automatic - "a": { - action: "auto-ar", - }, - //#region crop - "r": { - action: "crop", - arg: "reset" - }, - "w": { - action: "crop", - arg: "fitw" - }, - "e": { - action: "crop", - arg: "fith" - }, - "s": { - action: "crop", - arg: 1.78 - }, - "d": { - action: "crop", - arg: 2.39 - }, - "x": { - action: "crop", - arg: 2.0 - }, - "q": { - action: "crop", - arg: 2.35 - }, - //#endregion - //#region zoom - "z": { - action: "zoom", - arg: 0.1 - }, - "u": { - action: "zoom", - arg: -0.1 - }, - "p": { - action: "pan", - arg: 'toggle' // possible: 'enable', 'disable', 'toggle' - }, - "shiftKey_shift": { - action: "pan", - arg: 'toggle', - keyup: { - action: 'pan', - arg: 'toggle' - } - }, - "shift": { - action: "", - arg: "", - keyup: { - action: 'pan', - arg: 'toggle', - } - } - //#endregion - }, - modKeys: ["ctrlKey", "shiftKey", "altKey"] - }, - // ----------------------------------------- - // ::: SITE CONFIGURATION ::: - // ----------------------------------------- - // Nastavitve za posamezno stran - // Config for a given page: - // - // : { - // status: