diff --git a/.gitignore b/.gitignore index 809f3e2..f0e3313 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,7 @@ build/ /dist /dist-zip /uw-git_keys + +*.pem + +*.kate-swp diff --git a/README.md b/README.md index 3c3f825..9023f82 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ## 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). +[Firefox](https://addons.mozilla.org/en/firefox/addon/ultrawidify/), [Chrome](https://chrome.google.com/webstore/detail/ultrawidify/dndehlekllfkaijdlokmmicgnlanfjbi), [Edge](https://github.com/xternal7/ultrawidify#microsoft-edge) (Chromium-based only) ## TL;DR @@ -51,7 +51,7 @@ 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) -This extension also has a version for Microsoft Edge, but that requires a bit more effort. [See notes first](#edge-speficic-limitations-important). +Opera users and users of the new, Chromium-based Edge can install Ultrawidify from Chrome Web Store as well. # Beggathon (donations) @@ -245,6 +245,12 @@ However, I do plan on implementing this feature. Hopefully by the end of the yea ### Installing the current, github version +## Get pre-built version: + +TODO + +## Build from source + Requirements: npm, node. 1. Clone this repo @@ -259,26 +265,24 @@ TODO: see if #3 already loads the extension in FF 5. Select `${ultrawidify_folder}/dist/manifest.json` -# Edge-specific limitations (IMPORTANT!) +# Microsoft Edge -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). +With the advent of the new Chromium-based Edge, this extension should work just fine. I don't actively test in Edge, though, so your mileage may vary. -As a result, you'll have to download the extension and install it manually. This approach has some downsides. +## Chromium-based -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) +1. Visit [edge://extensions](edge://extensions/) +2. Go to [Chrome Web Store](https://chrome.google.com/webstore/detail/ultrawidify/dndehlekllfkaijdlokmmicgnlanfjbi) +3. Click 'Allow extensions from other stores' on the blue popup bar at the top of the screen +4. Install Ultrawidify +5. Enjoy -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. +I might reconsider publishing extension for Chromium-based Microsoft Edge once it's released. Releasing in MS Store appears to be impossible at current time as extension submissions don't appear to be open at all (unless you got a special invite or something). -**It's also worth noting that I'm not actively maintaining the Edge fork, so it's a few versions behind.** +## Old Edge -## 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) +1. Get [Chromium-based Edge](https://www.microsoftedgeinsider.com/en-us/) +2. See steps above # Changelog diff --git a/package.json b/package.json index 0562f98..9e9476b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ultravidify", - "version": "4.4.1", + "version": "4.4.2", "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": { @@ -9,6 +9,10 @@ "build-chrome": "cross-env NODE_ENV=production BROWSER=chrome webpack --hide-modules", "build-edge": "cross-env NODE_ENV=production BROWSER=edge webpack --hide-modules", "build:dev": "cross-env NODE_ENV=development BROWSER=firefox webpack --hide-modules", + "build-testing": "cross-env NODE_ENV=development BROWSER=firefox CHANNEL=testing webpack --hide-modules", + "build-nightly": "cross-env NODE_ENV=development BROWSER=firefox CHANNEL=nightly webpack --hide-modules", + "build-testing-chrome": "cross-env NODE_ENV=development BROWSER=chrome CHANNEL=testing webpack --hide-modules", + "build-nightly-chrome": "cross-env NODE_ENV=development BROWSER=chrome CHANNEL=nightly webpack --hide-modules", "build-chrome:dev": "cross-env NODE_ENV=development BROWSER=chrome webpack --hide-modules", "build-edge:dev": "cross-env NODE_ENV=development BROWSER=edge webpack --hide-modules", "build-all": "rm ./dist-zip/uw-amo-source.zip; mv ./dist-zip/*.zip ./dist-zip/old/; npm run build; node scripts/build-zip.js ff; npm run build-chrome; node scripts/build-zip.js chrome; ./scripts/prepare-amo-source.sh", diff --git a/scripts/build-and-deploy.sh b/scripts/build-and-deploy.sh new file mode 100755 index 0000000..ae7c2d0 --- /dev/null +++ b/scripts/build-and-deploy.sh @@ -0,0 +1,86 @@ +#!/bin/bash +# env variables to set: +# +# FORCE_BUILD set this variable to "true" if you wanna force build, even if build was +# triggered without any commits pushed to the directory +# +# BUILD_SCRIPT build-testing or build-nightly, could be any other from package.json tho +# +# RELEASE_SERVER target server (where to push built zips after they've been built) +# RELEASE_DIRECTORY base directory on the target server +# BUILD_CHANNEL_DIRECTORY directory for uploads, inside the release directory +# +# AMO_API_KEY needed if you want to sign and push extension to addons.mozilla.org +# AMO_API_SECRET -||- + +echo "============= STARTING BUILD SCRIPT =============" +pwd +whoami +echo " ::: env dump" +echo " -> FORCE_BUILD: $FORCE_BUILD" +echo " -> BUILD_SCRIPT: $BUILD_SCRIPT" +echo " -> RELEASE_SERVER: $RELEASE_SERVER" +echo " -> RELEASE_DIRECTORY: $RELEASE_DIRECTORY" +echo " -> BUILD_CHANNEL_DIRECTORY: $BUILD_CHANNEL_DIRECTORY" + +# don't build if nothing has changed, unless overriden via env variable +if [ ! -z "$GIT_COMMIT" ] ; then + if [ ! -z "$GIT_PREVIOUS_COMMIT" ] ; then + if [ "$GIT_COMMIT" == "$GIT_PREVIOUS_COMMIT" ] ; then + if [ $FORCE_BUILD == true ] ; then + echo "--------------------------------------------" + echo " Nothing has changed. Aborting build." + echo "--------------------------------------------" + exit 0; + fi + fi + fi +fi + +npm ci + +rm -rf ./dist-zip || true # no big deal if ./dist-zip doesn't exist + +# +# build firefox +# +npm run "${BUILD_SCRIPT}" +node scripts/build-zip.js ff +if [ ! -z "${AMO_API_KEY}" ] ; then + if [ ! -z "${AMO_API_SECRET}" ] ; then + web-ext sign --source-dir ./dist --api-key "${AMO_API_KEY}" --api-secret "${AMO_API_SECRET}" + fi +fi + +# +# build chrome +# +npm run "${BUILD_SCRIPT}-chrome" +node scripts/build-zip.js chrome + +# +#./scripts/build-crx.sh +# + +###################################### +# UPLOAD TO WEB SERVER +###################################### + +# # add ssh key, if not added +# if [ -z "$SSH_AUTH_SOCK" ] ; then +# eval `ssh-agent -s` +# ssh-add +# fi + +# # push all built stuff to the server +# scp -r ./build-zip/* "ultrawidify-uploader@${RELEASE_SERVER}:${RELEASE_DIRECTORY}${BUILD_CHANNEL_DIRECTORY}" + + + +###################################### +# Build finished message +###################################### + +echo "--------------------------------------------" +echo " BUILD FINISHED SUCCESSFULLY" +echo "--------------------------------------------" diff --git a/scripts/build-crx.sh b/scripts/build-crx.sh new file mode 100755 index 0000000..17ae75a --- /dev/null +++ b/scripts/build-crx.sh @@ -0,0 +1,45 @@ +#!/bin/bash -e +# +# Purpose: Pack a Chromium extension directory into crx format +# gotten from: https://web.archive.org/web/20180114090616/https://developer.chrome.com/extensions/crx#scripts +# +# Script assumes we're in basedir of the repository and that extension has been built and zipped to /dist-zip +# using the crx name we want (same name as zip, except different extension) +# +# also this doesn't check for errors ever so +# + +echo "entering dist-zip" +cd ./dist-zip + +zip=`ls | grep chrome.zip` +name="${zip%.*}" +crx="$name.crx" +key="../keys/chrome-nightly.pem" # this is also good for testing build +pub="$name.pub" +sig="$name.sig" +trap 'rm -f "$pub" "$sig" "$zip"' EXIT + +# signature +openssl sha1 -sha1 -binary -sign "$key" < "$zip" > "$sig" + +# public key +openssl rsa -pubout -outform DER < "$key" > "$pub" 2>/dev/null + +byte_swap () { + # Take "abcdefgh" and return it as "ghefcdab" + echo "${1:6:2}${1:4:2}${1:2:2}${1:0:2}" +} + +crmagic_hex="4372 3234" # Cr24 +version_hex="0200 0000" # 2 +pub_len_hex=$(byte_swap $(printf '%08x\n' $(ls -l "$pub" | awk '{print $5}'))) +sig_len_hex=$(byte_swap $(printf '%08x\n' $(ls -l "$sig" | awk '{print $5}'))) +( + echo "$crmagic_hex $version_hex $pub_len_hex $sig_len_hex" | xxd -r -p + cat "$pub" "$sig" "$zip" +) > "$crx" +echo "Wrote $crx" + +echo "exiting dist-zip" +cd .. \ No newline at end of file diff --git a/scripts/build-zip.js b/scripts/build-zip.js index 9f1380a..d7bca36 100644 --- a/scripts/build-zip.js +++ b/scripts/build-zip.js @@ -9,7 +9,7 @@ const DEST_ZIP_DIR = path.join(__dirname, '../dist-zip'); const extractExtensionData = () => { - const extPackageJson = require('../src/manifest.json'); + const extPackageJson = require('../dist/manifest.json'); return { name: extPackageJson.name, @@ -17,9 +17,9 @@ const extractExtensionData = () => { } }; -const makeDestZipDirIfNotExists = () => { - if(!fs.existsSync(DEST_ZIP_DIR)) { - fs.mkdirSync(DEST_ZIP_DIR); +const makeDirIfNotExists = (dir) => { + if(!fs.existsSync(dir)) { + fs.mkdirSync(dir); } } @@ -42,13 +42,26 @@ const buildZip = (src, dist, zipFilename) => { const main = () => { const browser = process.argv[2]; + const testingOrNightly = process.argv[3]; const {name, version} = extractExtensionData(); - const zipFilename = `${name}-${version}-${browser}.zip`; - - makeDestZipDirIfNotExists(); - buildZip(DEST_DIR, DEST_ZIP_DIR, zipFilename) + // collapse spaces and dashes into single dash + const baseFilename = `${name.replace(/[ -]+/g, '-')}-${version}`; + + let realZipDir; + + if (!!testingOrNightly) { + realZipDir = path.join(DEST_ZIP_DIR, baseFilename); + } else { + realZipDir = DEST_ZIP_DIR; + } + + const zipFilename = `${baseFilename}-${browser}.zip`; + + makeDirIfNotExists(realZipDir); + + buildZip(DEST_DIR, realZipDir, zipFilename) .then(() => console.info('OK')) .catch(console.err); }; diff --git a/scripts/remove-evals.js b/scripts/remove-evals.js index 1004efe..10b826b 100644 --- a/scripts/remove-evals.js +++ b/scripts/remove-evals.js @@ -5,7 +5,6 @@ const fs = require('fs'); const BUNDLE_DIR = path.join(__dirname, '../dist'); const bundles = [ - 'background.js', 'popup/popup.js', 'options/options.js', ]; diff --git a/src/common/components/ActionAlt.vue b/src/common/components/ActionAlt.vue index 47cf2e2..5964ac2 100644 --- a/src/common/components/ActionAlt.vue +++ b/src/common/components/ActionAlt.vue @@ -5,7 +5,7 @@
- 🗙 + 🗙 🗙     🖉     {{action.name}} diff --git a/src/common/enums/stretch.enum.js b/src/common/enums/stretch.enum.js index a5c0915..130f92b 100644 --- a/src/common/enums/stretch.enum.js +++ b/src/common/enums/stretch.enum.js @@ -3,6 +3,8 @@ var Stretch = Object.freeze({ Basic: 1, Hybrid: 2, Conditional: 3, + Fixed: 4, + FixedSource: 5, Default: -1 }); diff --git a/src/ext/conf/ActionList.js b/src/ext/conf/ActionList.js index c41f906..8032ea1 100644 --- a/src/ext/conf/ActionList.js +++ b/src/ext/conf/ActionList.js @@ -72,6 +72,20 @@ var ActionList = { },{ name: 'Thin borders', arg: Stretch.Conditional, + },{ + name: 'Fixed (source)', + arg: Stretch.FixedSource, + customArg: true, + scopes: { + page: true, + } + },{ + name: 'Fixed (displayed)', + arg: Stretch.Fixed, + customArg: true, + scopes: { + page: true, + } },{ name: 'Default', arg: Stretch.Default, diff --git a/src/ext/conf/ExtConfPatches.js b/src/ext/conf/ExtConfPatches.js index 4c2ff52..8912888 100644 --- a/src/ext/conf/ExtConfPatches.js +++ b/src/ext/conf/ExtConfPatches.js @@ -1,5 +1,6 @@ // How to use: // version: {ExtensionConf object, but only properties that get overwritten} +import Stretch from '../../common/enums/stretch.enum'; const ExtensionConfPatch = [ { @@ -146,6 +147,7 @@ const ExtensionConfPatch = [ show: true, } }, { + userAdded: true, name: 'Persist crop while on page', label: 'Until page load', cmd: [{ @@ -164,6 +166,7 @@ const ExtensionConfPatch = [ show: true, } }, { + userAdded: true, name: 'Persist crop for current session', label: 'Current session', cmd: [{ @@ -241,6 +244,61 @@ const ExtensionConfPatch = [ } } } + }, { + forVersion: '4.4.1.1', + sites: { + "www.disneyplus.com": { + DOM: { + player: { + periodicallyRefreshPlayerElement: true, + } + } + }, + } + }, { + forVersion: '4.4.2', + updateFn: (userOptions, defaultOptions) => { + try { + userOptions.actions.push( + { + name: 'Stretch source to 4:3', + label: '4:3 stretch (src)', + cmd: [{ + action: 'set-stretch', + arg: Stretch.FixedSource, + customArg: 1.33, + }], + scopes: { + page: { + show: true + } + }, + playerUi: { + show: true, + path: 'crop' + } + }, { + name: 'Stretch source to 16:9', + label: '16:9 stretch (src)', + cmd: [{ + action: 'set-stretch', + arg: Stretch.FixedSource, + customArg: 1.77, + }], + scopes: { + page: { + show: true, + } + }, + playerUi: { + show: true, + path: 'crop' + } + }); + } catch (e) { + console.error("PROBLEM APPLYING SETTINGS", e); + } + } } ]; diff --git a/src/ext/conf/ExtensionConf.js b/src/ext/conf/ExtensionConf.js index f014e23..052c2d8 100644 --- a/src/ext/conf/ExtensionConf.js +++ b/src/ext/conf/ExtensionConf.js @@ -285,6 +285,7 @@ var ExtensionConf = { path: 'crop' } }, { + userAdded: true, name: 'Set aspect ratio to 16:9', label: '16:9', cmd: [{ @@ -312,6 +313,7 @@ var ExtensionConf = { path: 'crop' } }, { + userAdded: true, name: 'Set aspect ratio to 21:9 (2.39:1)', label: '21:9', cmd: [{ @@ -339,6 +341,7 @@ var ExtensionConf = { path: 'crop' } }, { + userAdded: true, name: 'Set aspect ratio to 18:9', label: '18:9', cmd: [{ @@ -651,6 +654,41 @@ var ExtensionConf = { show: true, } } + }, // NEW OPTIONS + { + name: 'Stretch source to 4:3', + label: '4:3 stretch (src)', + cmd: [{ + action: 'set-stretch', + arg: Stretch.FixedSource, + customArg: 1.33, + }], + scopes: { + page: { + show: true, + } + }, + playerUi: { + show: true, + path: 'crop' + } + }, { + name: 'Stretch source to 16:9', + label: '16:9 stretch (src)', + cmd: [{ + action: 'set-stretch', + arg: Stretch.FixedSource, + customArg: 1.77, + }], + scopes: { + page: { + show: true, + } + }, + playerUi: { + show: true, + path: 'crop' + } }, // // A L I G N M E N T @@ -920,8 +958,8 @@ var ExtensionConf = { } } }, -], -whatsNewChecked: true, + ], + whatsNewChecked: true, // ----------------------------------------- // ::: SITE CONFIGURATION ::: // ----------------------------------------- @@ -1083,6 +1121,13 @@ whatsNewChecked: true, }, css: 'video {\n width: 100% !important;\n height: 100% !important;\n}', }, + "www.disneyplus.com": { + DOM: { + player: { + periodicallyRefreshPlayerElement: true, + } + } + }, "imgur.com": { mode: -1, autoar: -1, diff --git a/src/ext/lib/comms/CommsClient.js b/src/ext/lib/comms/CommsClient.js index cd8c7d9..1f96ed1 100644 --- a/src/ext/lib/comms/CommsClient.js +++ b/src/ext/lib/comms/CommsClient.js @@ -65,7 +65,7 @@ class CommsClient { this.pageInfo.setVideoAlignment(message.arg, message.playing); this.pageInfo.restoreAr(); } else if (message.cmd === "set-stretch") { - this.pageInfo.setStretchMode(message.arg, message.playing); + this.pageInfo.setStretchMode(message.arg, message.playing, message.customArg); } else if (message.cmd === 'set-keyboard') { this.pageInfo.setKeyboardShortcutsEnabled(message.arg) } else if (message.cmd === "autoar-start") { diff --git a/src/ext/lib/video-data/PageInfo.js b/src/ext/lib/video-data/PageInfo.js index 6e055a9..024a6c7 100644 --- a/src/ext/lib/video-data/PageInfo.js +++ b/src/ext/lib/video-data/PageInfo.js @@ -490,18 +490,18 @@ class PageInfo { } } - setStretchMode(sm, playingOnly){ + setStretchMode(stretchMode, playingOnly, fixedStretchRatio){ // TODO: find a way to only change aspect ratio for one video if (playingOnly) { for(var vd of this.videos){ if (vd.isPlaying()) { - vd.setStretchMode(sm) + vd.setStretchMode(stretchMode, fixedStretchRatio) } } } else { for(var vd of this.videos){ - vd.setStretchMode(sm) + vd.setStretchMode(stretchMode, fixedStretchRatio) } } } diff --git a/src/ext/lib/video-data/PlayerData.js b/src/ext/lib/video-data/PlayerData.js index 950466d..168ce55 100644 --- a/src/ext/lib/video-data/PlayerData.js +++ b/src/ext/lib/video-data/PlayerData.js @@ -45,6 +45,13 @@ class PlayerData { this.dimensions = undefined; this.overlayNode = undefined; + this.periodicallyRefreshPlayerElement = false; + try { + this.periodicallyRefreshPlayerElement = this.settings.active.sites[window.location.host].DOM.player.periodicallyRefreshPlayerElement; + } catch (e) { + // no biggie — that means we don't have any special settings for this site. + } + // this happens when we don't find a matching player element if (!this.element) { this.invalid = true; @@ -98,19 +105,19 @@ class PlayerData { } try { - const ths = this; - this.observer = new MutationObserver((m,o) => this.onPlayerDimensionsChanged(m,o,ths)); + const ths = this; + this.observer = new MutationObserver((m,o) => this.onPlayerDimensionsChanged(m,o,ths)); - const observerConf = { - attributes: true, - // attributeFilter: ['style', 'class'], - attributeOldValue: true, - }; - - this.observer.observe(this.element, observerConf); - } catch (e) { - console.error("failed to set observer",e ) - } + const observerConf = { + attributes: true, + // attributeFilter: ['style', 'class'], + attributeOldValue: true, + }; + + this.observer.observe(this.element, observerConf); + } catch (e) { + console.error("failed to set observer",e ) + } // legacy mode still exists, but acts as a fallback for observers and is triggered less // frequently in order to avoid too many pointless checks this.legacyChangeDetection(); @@ -120,6 +127,9 @@ class PlayerData { while (!this.halted) { await this.sleep(1000); try { + if (this.periodicallyRefreshPlayerElement) { + this.forceRefreshPlayerElement(); + } if (this.checkPlayerSizeChange()) { this.videoData.resizer.restore(); } diff --git a/src/ext/lib/video-data/VideoData.js b/src/ext/lib/video-data/VideoData.js index d343f6d..11eb481 100644 --- a/src/ext/lib/video-data/VideoData.js +++ b/src/ext/lib/video-data/VideoData.js @@ -2,6 +2,7 @@ import Debug from '../../conf/Debug'; import PlayerData from './PlayerData'; import Resizer from '../video-transform/Resizer'; import ArDetector from '../ar-detect/ArDetector'; +import AspectRatio from '../../../common/enums/aspect-ratio.enum'; class VideoData { @@ -300,6 +301,11 @@ class VideoData { if (this.invalid) { return; } + + if (ar.type === AspectRatio.Fixed || ar.type === AspectRatio.FitHeight || ar.type === AspectRatio.FitHeight) { + this.player.forceRefreshPlayerElement(); + } + this.resizer.setAr(ar, lastAr); } @@ -353,11 +359,11 @@ class VideoData { this.resizer.restore(); } - setStretchMode(stretchMode){ + setStretchMode(stretchMode, fixedStretchRatio){ if (this.invalid) { return; } - this.resizer.setStretchMode(stretchMode); + this.resizer.setStretchMode(stretchMode, fixedStretchRatio); } setZoom(zoomLevel, no_announce){ diff --git a/src/ext/lib/video-transform/Resizer.js b/src/ext/lib/video-transform/Resizer.js index dd87f6b..5b6c1af 100644 --- a/src/ext/lib/video-transform/Resizer.js +++ b/src/ext/lib/video-transform/Resizer.js @@ -242,7 +242,9 @@ class Resizer { } // do stretch thingy - if (this.stretcher.mode === Stretch.NoStretch || this.stretcher.mode === Stretch.Conditional){ + if (this.stretcher.mode === Stretch.NoStretch + || this.stretcher.mode === Stretch.Conditional + || this.stretcher.mode === Stretch.FixedSource){ var stretchFactors = this.scaler.calculateCrop(ar); if(! stretchFactors || stretchFactors.error){ @@ -255,15 +257,23 @@ class Resizer { } return; } - if(this.stretcher.mode === Stretch.Conditional){ - this.stretcher.applyConditionalStretch(stretchFactors, ar.ratio); - } - this.logger.log('info', 'debug', "[Resizer::setAr] Processed stretch factors for ", this.stretcher.mode === Stretch.NoStretch ? 'stretch-free crop.' : 'crop with conditional stretch.', 'Stretch factors are:', stretchFactors); + if (this.stretcher.mode === Stretch.Conditional){ + this.stretcher.applyConditionalStretch(stretchFactors, ar.ratio); + } else if (this.stretcher.mode === Stretch.FixedSource) { + this.stretcher.applyStretchFixedSource(stretchFactors); + } + this.logger.log('info', 'debug', "[Resizer::setAr] Processed stretch factors for ", + this.stretcher.mode === Stretch.NoStretch ? 'stretch-free crop.' : + this.stretcher.mode === Stretch.Conditional ? 'crop with conditional stretch.' : 'crop with fixed stretch', + 'Stretch factors are:', stretchFactors + ); } else if (this.stretcher.mode === Stretch.Hybrid) { var stretchFactors = this.stretcher.calculateStretch(ar.ratio); this.logger.log('info', 'debug', '[Resizer::setAr] Processed stretch factors for hybrid stretch/crop. Stretch factors are:', stretchFactors); + } else if (this.stretcher.mode === Stretch.Fixed) { + var stretchFactors = this.stretchFactors.calculateStretchFixed(ar.ratio) } else if (this.stretcher.mode === Stretch.Basic) { var stretchFactors = this.stretcher.calculateBasicStretch(); this.logger.log('info', 'debug', '[Resizer::setAr] Processed stretch factors for basic stretch. Stretch factors are:', stretchFactors); @@ -296,8 +306,8 @@ class Resizer { return this.lastAr; } - setStretchMode(stretchMode){ - this.stretcher.setStretchMode(stretchMode); + setStretchMode(stretchMode, fixedStretchRatio){ + this.stretcher.setStretchMode(stretchMode, fixedStretchRatio); this.restore(); } @@ -459,8 +469,6 @@ class Resizer { '\nwdiff, hdiffAfterZoom:', wdiffAfterZoom, 'x', hdiffAfterZoom, '\n\n---- data out ----\n', 'translate:', translate); - console.trace(); - return translate; } diff --git a/src/ext/lib/video-transform/Stretcher.js b/src/ext/lib/video-transform/Stretcher.js index b54f94d..2a5f48f 100644 --- a/src/ext/lib/video-transform/Stretcher.js +++ b/src/ext/lib/video-transform/Stretcher.js @@ -15,12 +15,16 @@ class Stretcher { this.logger = videoData.logger; this.settings = videoData.settings; this.mode = this.settings.getDefaultStretchMode(window.location.hostname); + this.fixedStretchRatio = undefined; } - setStretchMode(stretchMode) { + setStretchMode(stretchMode, fixedStretchRatio) { if (stretchMode === Stretch.Default) { this.mode = this.settings.getDefaultStretchMode(window.location.hostname); } else { + if (stretchMode === Stretch.Fixed || stretchMode == Stretch.FixedSource) { + this.fixedStretchRatio = fixedStretchRatio; + } this.mode = stretchMode; } } @@ -95,9 +99,43 @@ class Stretcher { }; } - calculateStretch(actualAr) { - var playerAr = this.conf.player.dimensions.width / this.conf.player.dimensions.height; - var videoAr = this.conf.video.videoWidth / this.conf.video.videoHeight; + applyStretchFixedSource(postCropStretchFactors) { + const videoAr = this.conf.video.videoWidth / this.conf.video.videoHeight; + const playerAr = this.conf.player.dimensions.width / this.conf.player.dimensions.height; + + const squezeFactor = this.fixedStretchRatio / videoAr; + + // Whether squeezing happens on X or Y axis depends on whether required AR is wider or narrower than + // the player, in which the video is displayed + // * we squeeze X axis, if target AR is narrower than player size + // * we squeeze Y axis, if target AR is wider than the player size + + this.logger.log('info', 'stretcher', `[Stretcher::applyStretchFixedSource] here's what we got: +postCropStretchFactors: x=${postCropStretchFactors.xFactor} y=${postCropStretchFactors.yFactor} +fixedStretchRatio: ${this.fixedStretchRatio} +videoAr: ${videoAr} +playerAr: ${playerAr} +squeezeFactor: ${squezeFactor}`, '\nvideo', this.conf.video); + + + if (this.fixedStretchRatio < playerAr) { + postCropStretchFactors.xFactor *= squezeFactor; + } else { + postCropStretchFactors.yFactor *= squezeFactor; + } + + this.logger.log('info', 'stretcher', `[Stretcher::applyStretchFixedSource] here's what we'll apply:\npostCropStretchFactors: x=${postCropStretchFactors.x} y=${postCropStretchFactors.y}`); + + return postCropStretchFactors; + } + + calculateStretchFixed(actualAr) { + return this.calculateStretch(actualAr, this.fixedStretchRatio); + } + + calculateStretch(actualAr, playerArOverride) { + const playerAr = playerArOverride || this.conf.player.dimensions.width / this.conf.player.dimensions.height; + const videoAr = this.conf.video.videoWidth / this.conf.video.videoHeight; if (! actualAr){ actualAr = playerAr; @@ -158,7 +196,7 @@ class Stretcher { // video is letterboxed by player // actual is pillarboxed by video stretchFactors.xFactor = actualAr / playerAr; - stretchFActors.yFactor = actualAr / playerAr; + stretchFactors.yFactor = actualAr / playerAr; this.logger.log('info', 'stretcher', "[Stretcher.js::calculateStretch] stretching strategy 5") } else { diff --git a/src/manifest.json b/src/manifest.json index 4ea382a..46818da 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 2, "name": "Ultrawidify", "description": "Removes black bars on ultrawide videos and offers advanced options to fix aspect ratio.", - "version": "4.4.1", + "version": "4.4.2", "applications": { "gecko": { "id": "{cf02b1a7-a01a-4e37-a609-516a283f1ed3}" diff --git a/src/options/controls-settings/AddEditActionPopup.vue b/src/options/controls-settings/AddEditActionPopup.vue index 10a929f..b390da7 100644 --- a/src/options/controls-settings/AddEditActionPopup.vue +++ b/src/options/controls-settings/AddEditActionPopup.vue @@ -229,7 +229,7 @@ export default { }, saveSettings() { if (this.currentCmdIndex < 0) { - this.settings.active.actions.push(this.action); + this.settings.active.actions.push({...this.action, ...{userAdded: true}}); } this.settings.save(); this.close(); diff --git a/src/popup/panels/VideoPanel.vue b/src/popup/panels/VideoPanel.vue index 3e66185..a75d401 100644 --- a/src/popup/panels/VideoPanel.vue +++ b/src/popup/panels/VideoPanel.vue @@ -22,6 +22,7 @@ >
+
You can change or add additional aspect ratios on the settings page (in 'actions&shortcuts' menu).

What's new

Full changelog for older versions is available here.

-

4.4.1

+

4.4.2

diff --git a/webpack.config.js b/webpack.config.js index 2f3c359..ce396ac 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -84,6 +84,40 @@ const config = { jsonContent['content_security_policy'] = "script-src 'self' 'unsafe-eval'; object-src 'self'"; } + if (process.env.CHANNEL === 'nightly') { + jsonContent.name = "Ultrawidify - nightly"; + jsonContent.description = "FOR TESTING ONLY -- THIS BUILD USES ONLY THE FRESHEST COMMITS FROM GITHUB AND MAY THEREFORE BE COMPLETELY BROKEN"; + + // version numbers for nightly builds: YYMM.DD.BUILD_NUMBER + jsonContent.version = `${new Date() + .toISOString() // YYYY-MM-DDTHH:MM:SS... + .split('T')[0] // gives YYYY-MM-DD + .substr(2) // YYYY -> YY + .replace('-', '') // YY-MM-DD -> YYMM-DD + .replace('-', '.') // YYMM-DD -> YYMM.DD + }.${process.env.BUILD_NUMBER}`; + jsonContent.browser_action.default_title = "Ultrawidify Nightly"; + + // because we don't want web-ext to submit this as proper release + delete jsonContent.applications; + } else if (process.env.CHANNEL === 'testing') { + jsonContent.name = "Ultrawidify - testing"; + jsonContent.description = "FOR TESTING ONLY -- this build is intended for testing a fix of certain bugs. It's not fit for normal use."; + + // version numbers for nightly builds: YYMM.DD.BUILD_NUMBER + jsonContent.version = `${new Date() + .toISOString() // YYYY-MM-DDTHH:MM:SS... + .split('T')[0] // gives YYYY-MM-DD + .substr(2) // YYYY -> YY + .replace('-', '') // YY-MM-DD -> YYMM-DD + .replace('-', '.') // YYMM-DD -> YYMM.DD + }.${process.env.BUILD_NUMBER}`; + jsonContent.browser_action.default_title = "Ultrawidify Testing"; + + // because we don't want web-ext to submit this as proper release + delete jsonContent.applications; + } + if (process.env.BROWSER !== 'firefox') { jsonContent.version = jsonContent.version.replace(/[a-zA-Z-]/g, ''); }