Get zoom options to mostly work
This commit is contained in:
parent
32c11d1f61
commit
3d7b50a2e3
@ -1,6 +1,12 @@
|
||||
import AspectRatioType from '../enums/AspectRatioType.enum';
|
||||
|
||||
export enum ArVariant {
|
||||
Crop = undefined,
|
||||
Zoom = 1
|
||||
}
|
||||
|
||||
export interface Ar {
|
||||
type: AspectRatioType,
|
||||
ratio?: number
|
||||
ratio?: number,
|
||||
variant?: ArVariant
|
||||
}
|
||||
|
@ -43,6 +43,14 @@
|
||||
<h1>Zoom:</h1>
|
||||
</div>
|
||||
|
||||
<ZoomOptionsPanel
|
||||
:settings="settings"
|
||||
:eventBus="eventBus"
|
||||
:siteSettings="siteSettings"
|
||||
:isEditing="false"
|
||||
>
|
||||
</ZoomOptionsPanel>
|
||||
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
@ -1,6 +1,7 @@
|
||||
import AspectRatioType from '../../../common/enums/AspectRatioType.enum';
|
||||
import ExtensionMode from '../../../common/enums/ExtensionMode.enum';
|
||||
import { ExtensionEnvironment } from '../../../common/interfaces/SettingsInterface';
|
||||
import AspectRatioType from '@src/common/enums/AspectRatioType.enum';
|
||||
import ExtensionMode from '@src/common/enums/ExtensionMode.enum';
|
||||
import { ArVariant } from '@src/common/interfaces/ArInterface';
|
||||
import { ExtensionEnvironment } from '@src/common/interfaces/SettingsInterface';
|
||||
import EventBus from '../EventBus';
|
||||
import Logger from '../Logger';
|
||||
import Settings from '../Settings';
|
||||
@ -413,7 +414,7 @@ export class Aard {
|
||||
/**
|
||||
* Checks whether autodetection can run
|
||||
*/
|
||||
startCheck() {
|
||||
startCheck(arVariant?: ArVariant) {
|
||||
console.log('aard - starting checks')
|
||||
if (!this.videoData.player) {
|
||||
console.warn('Player not detected!');
|
||||
|
@ -16,7 +16,7 @@ import VideoData from '../video-data/VideoData';
|
||||
import EventBus from '../EventBus';
|
||||
import { _cp } from '../../../common/js/utils';
|
||||
import Settings from '../Settings';
|
||||
import { Ar } from '../../../common/interfaces/ArInterface';
|
||||
import { Ar, ArVariant } from '../../../common/interfaces/ArInterface';
|
||||
import { RunLevel } from '../../enum/run-level.enum';
|
||||
import * as _ from 'lodash';
|
||||
import getElementStyles from '../../util/getElementStyles';
|
||||
@ -26,6 +26,11 @@ if(Debug.debug) {
|
||||
console.log("Loading: Resizer.js");
|
||||
}
|
||||
|
||||
enum ResizerMode {
|
||||
Crop = 1,
|
||||
Zoom = 2
|
||||
};
|
||||
|
||||
/**
|
||||
* Resizer is the top class and is responsible for figuring out which component needs to crop, which
|
||||
* component needs to zoom, and which component needs to stretch.
|
||||
@ -83,9 +88,9 @@ class Resizer {
|
||||
//#endregion
|
||||
|
||||
cycleableAspectRatios: Ar[];
|
||||
cycleableZoomAspectRatios: Ar[];
|
||||
nextCycleOptionIndex = 0;
|
||||
|
||||
|
||||
//#region event bus configuration
|
||||
private eventBusCommands = {
|
||||
'set-ar': [{
|
||||
@ -93,7 +98,7 @@ class Resizer {
|
||||
this.manualZoom = false; // this only gets called from UI or keyboard shortcuts, making this action safe.
|
||||
|
||||
if (config.type !== AspectRatioType.Cycle) {
|
||||
this.setAr(config);
|
||||
this.setAr({...config, variant: ArVariant.Crop});
|
||||
} else {
|
||||
// if we manually switched to a different aspect ratio, cycle from that ratio forward
|
||||
const lastArIndex = this.cycleableAspectRatios.findIndex(x => x.type === this.lastAr.type && x.ratio === this.lastAr.ratio);
|
||||
@ -101,11 +106,29 @@ class Resizer {
|
||||
this.nextCycleOptionIndex = (lastArIndex + 1) % this.cycleableAspectRatios.length;
|
||||
}
|
||||
|
||||
this.setAr(this.cycleableAspectRatios[this.nextCycleOptionIndex]);
|
||||
this.setAr({...this.cycleableAspectRatios[this.nextCycleOptionIndex], variant: ArVariant.Crop});
|
||||
this.nextCycleOptionIndex = (this.nextCycleOptionIndex + 1) % this.cycleableAspectRatios.length;
|
||||
}
|
||||
}
|
||||
}],
|
||||
'set-ar-zoom': [{
|
||||
function: (config: any) => {
|
||||
this.manualZoom = false; // this only gets called from UI or keyboard shortcuts, making this action safe.
|
||||
|
||||
if (config.type !== AspectRatioType.Cycle) {
|
||||
this.setAr({...config, variant: ArVariant.Zoom});
|
||||
} else {
|
||||
// if we manually switched to a different aspect ratio, cycle from that ratio forward
|
||||
const lastArIndex = this.cycleableZoomAspectRatios.findIndex(x => x.type === this.lastAr.type && x.ratio === this.lastAr.ratio);
|
||||
if (lastArIndex !== -1) {
|
||||
this.nextCycleOptionIndex = (lastArIndex + 1) % this.cycleableZoomAspectRatios.length;
|
||||
}
|
||||
|
||||
this.setAr({...this.cycleableZoomAspectRatios[this.nextCycleOptionIndex], variant: ArVariant.Zoom});
|
||||
this.nextCycleOptionIndex = (this.nextCycleOptionIndex + 1) % this.cycleableZoomAspectRatios.length;
|
||||
}
|
||||
}
|
||||
}],
|
||||
'set-alignment': [{
|
||||
function: (config: any) => {
|
||||
this.setVideoAlignment(config.x, config.y);
|
||||
@ -188,6 +211,11 @@ class Resizer {
|
||||
.filter(x => [AspectRatioType.FitHeight, AspectRatioType.FitWidth, AspectRatioType.Fixed, AspectRatioType.Reset].includes(x?.arguments?.type))
|
||||
.map(x => x.arguments) as Ar[];
|
||||
|
||||
this.cycleableZoomAspectRatios =
|
||||
(this.settings?.active?.commands?.zoom ?? [])
|
||||
.filter(x => x.action === 'set-ar-zoom' && x.arguments?.type !== AspectRatioType.Cycle)
|
||||
.map(x => x.arguments) as Ar[];
|
||||
|
||||
this.nextCycleOptionIndex = 0;
|
||||
this.userCssClassName = videoData.userCssClassName;
|
||||
}
|
||||
@ -276,8 +304,27 @@ class Resizer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts and stops Aard as necessary. Returns 'true' if we can
|
||||
* stop setting aspect ratio early.
|
||||
* @param ar
|
||||
* @param resizerMode
|
||||
* @returns
|
||||
*/
|
||||
private handleAard(ar: Ar): boolean {
|
||||
if (ar.type === AspectRatioType.Automatic) {
|
||||
this.videoData.aard?.startCheck(ar.variant);
|
||||
return true;
|
||||
} else if (ar.type !== AspectRatioType.AutomaticUpdate) {
|
||||
this.videoData.aard?.stop();
|
||||
} else if (this.stretcher.stretch.type === StretchType.Basic) {
|
||||
this.videoData?.aard?.stop();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async setAr(ar: Ar, lastAr?: Ar) {
|
||||
if (this.destroyed) {
|
||||
if (this.destroyed || ar == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -294,11 +341,8 @@ class Resizer {
|
||||
}
|
||||
|
||||
// handle autodetection stuff
|
||||
if (ar.type === AspectRatioType.Automatic) {
|
||||
this.videoData.aard?.startCheck();
|
||||
if (this.handleAard(ar)) {
|
||||
return;
|
||||
} else if (ar.type !== AspectRatioType.AutomaticUpdate) {
|
||||
this.videoData.aard?.stop();
|
||||
}
|
||||
|
||||
if (ar.type !== AspectRatioType.AutomaticUpdate) {
|
||||
@ -312,10 +356,6 @@ class Resizer {
|
||||
|
||||
this.logger.log('info', 'debug', '%c[Resizer::setAr] <rid:'+this.resizerId+'> trying to set ar. New ar:', 'background-color: #4c3a2f, color: #ffa349', ar);
|
||||
|
||||
if (ar == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
let stretchFactors: VideoDimensions | any;
|
||||
|
||||
// reset zoom, but only on aspect ratio switch. We also know that aspect ratio gets converted to
|
||||
@ -324,6 +364,7 @@ class Resizer {
|
||||
(ar.type !== AspectRatioType.Fixed && ar.type !== AspectRatioType.Manual) // anything not these two _always_ changes AR
|
||||
|| ar.type !== this.lastAr.type // this also means aspect ratio has changed
|
||||
|| ar.ratio !== this.lastAr.ratio // this also means aspect ratio has changed
|
||||
|| ar.variant !== this.lastAr.variant
|
||||
) {
|
||||
this.zoom.reset();
|
||||
this.resetPan();
|
||||
@ -360,26 +401,11 @@ class Resizer {
|
||||
this.videoData.destroy();
|
||||
}
|
||||
|
||||
// pause AR on:
|
||||
// * ar.type NOT automatic
|
||||
// * ar.type is auto, but stretch is set to basic basic stretch
|
||||
//
|
||||
// unpause when using other modes
|
||||
if ((ar.type !== AspectRatioType.Automatic && ar.type !== AspectRatioType.AutomaticUpdate) || this.stretcher.stretch.type === StretchType.Basic) {
|
||||
this.videoData?.aard?.stop();
|
||||
} else {
|
||||
if (ar.type !== AspectRatioType.AutomaticUpdate) {
|
||||
if (this.lastAr.type === AspectRatioType.Automatic || this.lastAr.type === AspectRatioType.AutomaticUpdate) {
|
||||
this.videoData?.aard?.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// do stretch thingy
|
||||
if ([StretchType.NoStretch, StretchType.Conditional, StretchType.FixedSource].includes(this.stretcher.stretch.type)) {
|
||||
stretchFactors = this.scaler.calculateCrop(ar);
|
||||
|
||||
if(! stretchFactors || stretchFactors.error){
|
||||
if (!stretchFactors || stretchFactors.error){
|
||||
this.logger.log('error', 'debug', `[Resizer::setAr] <rid:${this.resizerId}> failed to set AR due to problem with calculating crop. Error:`, stretchFactors?.error);
|
||||
if (stretchFactors?.error === 'no_video'){
|
||||
this.videoData.destroy();
|
||||
@ -406,12 +432,11 @@ class Resizer {
|
||||
this.stretcher.stretch.type === StretchType.Conditional ? 'crop with conditional StretchType.' : 'crop with fixed stretch',
|
||||
'Stretch factors are:', stretchFactors
|
||||
);
|
||||
|
||||
} else if (this.stretcher.stretch.type === StretchType.Hybrid) {
|
||||
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.stretch.type === StretchType.Fixed) {
|
||||
stretchFactors = this.stretcher.calculateStretchFixed(ar.ratio)
|
||||
stretchFactors = this.stretcher.calculateStretchFixed(ar.ratio);
|
||||
} else if (this.stretcher.stretch.type === StretchType.Basic) {
|
||||
stretchFactors = this.stretcher.calculateBasicStretch();
|
||||
this.logger.log('info', 'debug', '[Resizer::setAr] Processed stretch factors for basic StretchType. Stretch factors are:', stretchFactors);
|
||||
@ -794,8 +819,10 @@ class Resizer {
|
||||
// conditions are true at the same time, we need to go 'chiny reckon' and recheck our player
|
||||
// element. Chances are our video is not getting aligned correctly
|
||||
if (
|
||||
(this.videoData.video.offsetWidth > this.videoData.player.dimensions.width && this.videoData.video.offsetHeight > this.videoData.player.dimensions.height) ||
|
||||
(this.videoData.video.offsetWidth < this.videoData.player.dimensions.width && this.videoData.video.offsetHeight < this.videoData.player.dimensions.height)
|
||||
(
|
||||
(this.videoData.video.offsetWidth > this.videoData.player.dimensions.width && this.videoData.video.offsetHeight > this.videoData.player.dimensions.height) ||
|
||||
(this.videoData.video.offsetWidth < this.videoData.player.dimensions.width && this.videoData.video.offsetHeight < this.videoData.player.dimensions.height)
|
||||
) && ar?.variant !== ArVariant.Zoom
|
||||
) {
|
||||
this.logger.log('warn', ['debugger', 'resizer'], `[Resizer::_res_computeOffsets] <rid:${this.resizerId}> We are getting some incredibly funny results here.\n\n`,
|
||||
`Video seems to be both wider and taller (or shorter and narrower) than player element at the same time. This is super duper not supposed to happen.\n\n`,
|
||||
|
@ -3,6 +3,7 @@ import AspectRatioType from '../../../common/enums/AspectRatioType.enum';
|
||||
import BrowserDetect from '../../conf/BrowserDetect';
|
||||
import VideoData from '../video-data/VideoData';
|
||||
import Logger from '../Logger';
|
||||
import { Ar, ArVariant } from '../../../common/interfaces/ArInterface';
|
||||
|
||||
|
||||
export enum CropStrategy {
|
||||
@ -100,7 +101,7 @@ class Scaler {
|
||||
return null;
|
||||
}
|
||||
|
||||
calculateCrop(ar: {type: AspectRatioType, ratio?: number}): VideoDimensions | {error: string, [x: string]: any} {
|
||||
calculateCrop(ar: Ar): VideoDimensions | {error: string, [x: string]: any} {
|
||||
/**
|
||||
* STEP 1: NORMALIZE ASPECT RATIO
|
||||
*
|
||||
@ -170,9 +171,15 @@ class Scaler {
|
||||
|
||||
this.logger.log('info', 'scaler', "[Scaler::calculateCrop] trying to set ar. args are: ar->",ar.ratio,"; this.conf.player.dimensions->",this.conf.player.dimensions.width, "×", this.conf.player.dimensions.height, "| obj:", this.conf.player.dimensions);
|
||||
|
||||
// If we encounter invalid players, we try to update its dimensions
|
||||
// ONCE before throwing an error
|
||||
if( (! this.conf.player.dimensions) || this.conf.player.dimensions.width === 0 || this.conf.player.dimensions.height === 0 ){
|
||||
this.logger.log('error', 'scaler', "[Scaler::calculateCrop] ERROR — no (or invalid) this.conf.player.dimensions:",this.conf.player.dimensions);
|
||||
return {error: "this.conf.player.dimensions_error"};
|
||||
this.conf.player.updatePlayer();
|
||||
|
||||
if( (! this.conf.player.dimensions) || this.conf.player.dimensions.width === 0 || this.conf.player.dimensions.height === 0 ){
|
||||
return {error: "this.conf.player.dimensions_error"};
|
||||
}
|
||||
}
|
||||
|
||||
// we can finally start computing required video dimensions now:
|
||||
@ -184,7 +191,7 @@ class Scaler {
|
||||
}
|
||||
|
||||
|
||||
this.logger.log('info', 'scaler', "[Scaler::calculateCrop] ar is " ,ar.ratio, ", file ar is", streamAr, ", this.conf.player.dimensions are ", this.conf.player.dimensions.width, "×", this.conf.player.dimensions.height, "| obj:", this.conf.player.dimensions);
|
||||
this.logger.log('info', 'scaler', "[Scaler::calculateCrop] ar is " ,ar.ratio, ", file ar is", streamAr, ",ar variant", ar.variant ,"\nthis.conf.player.dimensions are ", this.conf.player.dimensions.width, "×", this.conf.player.dimensions.height, "| obj:", this.conf.player.dimensions, this.conf.player.element);
|
||||
|
||||
const videoDimensions: VideoDimensions = {
|
||||
xFactor: 1,
|
||||
@ -199,7 +206,7 @@ class Scaler {
|
||||
}
|
||||
}
|
||||
|
||||
this.calculateCropCore(videoDimensions, ar.ratio, streamAr, playerAr)
|
||||
this.calculateCropCore(videoDimensions, ar.ratio, streamAr, playerAr, ar.variant)
|
||||
|
||||
return videoDimensions;
|
||||
}
|
||||
@ -212,7 +219,11 @@ class Scaler {
|
||||
* @param {*} streamAr
|
||||
* @param {*} playerAr
|
||||
*/
|
||||
calculateCropCore(videoDimensions: VideoDimensions, ar: number, streamAr: number, playerAr: number) {
|
||||
calculateCropCore(videoDimensions: VideoDimensions, ar: number, streamAr: number, playerAr: number, variant?: ArVariant) {
|
||||
if (variant === ArVariant.Zoom) {
|
||||
playerAr = ar;
|
||||
}
|
||||
|
||||
if (streamAr < playerAr) {
|
||||
if (streamAr < ar){
|
||||
// in this situation we have to crop letterbox on top/bottom of the player
|
||||
@ -254,8 +265,8 @@ class Scaler {
|
||||
const letterboxRatio = (1 - (playerAr / ar));
|
||||
|
||||
videoDimensions.relativeCropLimits = {
|
||||
top: ar > streamAr ? ( ar > playerAr ? (letterboxRatio * -0.5) : 0) : 0,
|
||||
left: ar < streamAr ? ( ar < playerAr ? (-0.5 / letterboxRatio) : 0) : 0,
|
||||
top: ar > streamAr ? ( ar >= playerAr ? (letterboxRatio * -0.5) : 0) : 0,
|
||||
left: ar < streamAr ? ( ar <= playerAr ? (-0.5 / letterboxRatio) : 0) : 0,
|
||||
}
|
||||
videoDimensions.preventAlignment = {
|
||||
x: ar > playerAr, // video is wider than player, so it's full width already
|
||||
|
Loading…
Reference in New Issue
Block a user