Fix aspect ratio calculations on height-compensated videos, episode 1

This commit is contained in:
Tamius Han 2020-12-19 03:18:14 +01:00
parent be82c4dae6
commit a9f99d93be
2 changed files with 25 additions and 16 deletions

View File

@ -71,7 +71,13 @@ class Scaler {
*
* Video width is normalized based on 100% of the parent. That means if the player AR
* is narrower than video ar, we need to pre-downscale the video. This scaling already
* undoes any zoom that style="height:123%" on the video element adds.
* undoes any zoom that style="height:123%" on the video element adds.
*
* There are few exceptions and additional caveatss:
* * AspectRatio.FitHeight: we don't want to pre-downscale the video at all, as things
* will be scaled to fit height as-is.
* * When player is wider than stream, we want to undo any height compensations site
* tacks on the video tag.
*
* Quick notes:
* * when I say 'video AR', I actually mean aspect ratio after we've compensated for
@ -81,11 +87,14 @@ class Scaler {
*/
const streamAr = this.conf.video.videoWidth / this.conf.video.videoHeight;
const playerAr = this.conf.player.dimensions.width / this.conf.player.dimensions.height;
const compensatedStreamAr = streamAr * this.conf.getHeightCompensationFactor();
const heightCompensationFactor = this.conf.getHeightCompensationFactor();
const compensatedStreamAr = streamAr * heightCompensationFactor;
let arCorrectionFactor = 1;
if (playerAr < compensatedStreamAr) {
arCorrectionFactor = this.conf.player.dimensions.width / this.conf.video.offsetWidth;
} else if (ar.type !== AspectRatio.Reset) {
arCorrectionFactor /= heightCompensationFactor;
}
if(!this.conf.video){

View File

@ -138,15 +138,14 @@ squeezeFactor: ${squeezeFactor}`, '\nvideo', this.conf.video);
const playerAr = this.conf.player.dimensions.width / this.conf.player.dimensions.height;
let arCorrectionFactor = 1;
if (playerAr < streamAr) {
arCorrectionFactor = this.conf.player.dimensions.width / this.conf.video.offsetWidth;
}
arCorrectionFactor = this.conf.player.dimensions.width / this.conf.video.offsetWidth;
return arCorrectionFactor;
}
calculateStretch(actualAr, playerArOverride) {
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;
const streamAr = this.conf.video.videoWidth / this.conf.video.videoHeight;
if (! actualAr){
actualAr = playerAr;
@ -157,7 +156,7 @@ squeezeFactor: ${squeezeFactor}`, '\nvideo', this.conf.video);
yFactor: 1
};
if (playerAr >= videoAr){
if (playerAr >= streamAr){
// player adds PILLARBOX
if(actualAr >= playerAr){
@ -166,18 +165,18 @@ squeezeFactor: ${squeezeFactor}`, '\nvideo', this.conf.video);
// actual > player > video — video is letterboxed
// solution: horizontal stretch according to difference between video and player AR
// vertical stretch according to difference between actual AR and player AR
stretchFactors.xFactor = playerAr / videoAr;
stretchFactors.yFactor = actualAr / videoAr;
stretchFactors.xFactor = playerAr / streamAr;
stretchFactors.yFactor = actualAr / streamAr;
this.logger.log('info', 'stretcher', "[Stretcher.js::calculateStretch] stretching strategy 1")
} else if ( actualAr >= videoAr) {
} else if ( actualAr >= streamAr) {
// VERIFIED WORKS
// player > actual > video — video is still letterboxed
// we need vertical stretch to remove black bars in video
// we need horizontal stretch to make video fit width
stretchFactors.xFactor = playerAr / videoAr;
stretchFactors.yFactor = actualAr / videoAr;
stretchFactors.xFactor = playerAr / streamAr;
stretchFactors.yFactor = actualAr / streamAr;
this.logger.log('info', 'stretcher', "[Stretcher.js::calculateStretch] stretching strategy 2")
} else {
@ -197,10 +196,10 @@ squeezeFactor: ${squeezeFactor}`, '\nvideo', this.conf.video);
// video > player > actual
// video is PILLARBOXED
stretchFactors.xFactor = actualAr / playerAr;
stretchFactors.yFactor = videoAr / playerAr;
stretchFactors.yFactor = streamAr / playerAr;
this.logger.log('info', 'stretcher', "[Stretcher.js::calculateStretch] stretching strategy 4")
} else if ( actualAr < videoAr ) {
} else if ( actualAr < streamAr ) {
// NEEDS CHECKING
// video > actual > player
@ -222,10 +221,11 @@ squeezeFactor: ${squeezeFactor}`, '\nvideo', this.conf.video);
}
}
// correct factors
const arCorrectionFactor = this.getArCorrectionFactor();
// correct factors, unless we're trying to reset
stretchFactors.xFactor *= arCorrectionFactor;
stretchFactors.yFactor *= arCorrectionFactor;
stretchFactors.arCorrectionFactor = this.getArCorrectionFactor();
return stretchFactors;
}