Additional fixes for #101 — if illegal video dimensions are detected, tell VideoData to reset/reapply aspect ratio when video starts playing again

This commit is contained in:
Tamius Han 2020-06-04 21:51:22 +02:00
parent cc53df5999
commit a4bca8af45
2 changed files with 30 additions and 22 deletions

View File

@ -20,6 +20,7 @@ class VideoData {
this.userCssClassName = `uw-fuck-you-and-do-what-i-tell-you_${this.vdid}`; this.userCssClassName = `uw-fuck-you-and-do-what-i-tell-you_${this.vdid}`;
this.videoLoaded = false; this.videoLoaded = false;
this.videoDimensionsLoaded = true;
this.dimensions = { this.dimensions = {
width: this.video.offsetWidth, width: this.video.offsetWidth,
@ -34,7 +35,7 @@ class VideoData {
// this one is in case extension loads after the video is loaded // this one is in case extension loads after the video is loaded
video.addEventListener('timeupdate', () => { video.addEventListener('timeupdate', () => {
this.onVideoLoaded() this.onVideoLoaded();
}); });
} }
@ -43,12 +44,16 @@ class VideoData {
this.logger.log('info', 'init', '%c[VideoData::onVideoLoaded] ——————————— Initiating phase two of videoData setup ———————————', 'color: #0f9'); this.logger.log('info', 'init', '%c[VideoData::onVideoLoaded] ——————————— Initiating phase two of videoData setup ———————————', 'color: #0f9');
this.videoLoaded = true; this.videoLoaded = true;
this.videoDimensionsLoaded = true;
try { try {
await this.setupStageTwo(); await this.setupStageTwo();
this.logger.log('info', 'init', '%c[VideoData::onVideoLoaded] ——————————— videoData setup stage two complete ———————————', 'color: #0f9'); this.logger.log('info', 'init', '%c[VideoData::onVideoLoaded] ——————————— videoData setup stage two complete ———————————', 'color: #0f9');
} catch (e) { } catch (e) {
this.logger.log('error', 'init', '%c[VideoData::onVideoLoaded] ——————————— Setup stage two failed. ———————————\n', 'color: #f00', e); this.logger.log('error', 'init', '%c[VideoData::onVideoLoaded] ——————————— Setup stage two failed. ———————————\n', 'color: #f00', e);
} }
} else if (!this.videoDimensionsLoaded) {
this.restoreCrop();
this.videoDimensionsLoaded = true;
} }
} }
@ -115,6 +120,24 @@ class VideoData {
} }
} }
restoreCrop() {
this.logger.log('info', 'debug', "%c[VideoData::restoreCrop] Recovering from illegal video dimensions. Resetting aspect ratio.", {background: '#afd', color: '#132'});
// if we have default crop set for this page, apply this.
// otherwise, reset crop
if (this.pageInfo.defaultCrop) {
this.resizer.setAr(this.pageInfo.defaultCrop);
} else {
this.resizer.reset();
try {
this.startArDetection();
} catch (e) {
this.logger.log('warn', 'debug', '[VideoData::restoreCrop] Autodetection not resumed. Reason:', e);
}
}
}
async fallbackChangeDetection() { async fallbackChangeDetection() {
while (!this.destroyed && !this.invalid) { while (!this.destroyed && !this.invalid) {
await this.sleep(500); await this.sleep(500);

View File

@ -267,28 +267,13 @@ class Resizer {
return; return;
} }
// we could have issued calculate crop too early. Instead of spending 30 minutes trying to fix this the proper way by // we could have issued calculate crop too early. Let's tell VideoData that there's something wrong
// reading documentation, let's fix it in 30 seconds with some brute force code // and exit this function. When <video> will receive onloadeddata or ontimeupdate (receiving either
// of the two means video is loaded or playing, and that means video has proper dimensions), it will
// try to reset or re-apply aspect ratio when the video is finally ready.
if (stretchFactors?.error === 'illegal_video_dimensions') { if (stretchFactors?.error === 'illegal_video_dimensions') {
let timeout = 10; // ms this.conf.videoDimensionsLoaded = false;
let iteration = 0; return;
let maxIterations = 15;
do {
if (iteration > maxIterations) {
this.logger.log('error', 'debug', `[Resizer::setAr] <rid:${this.resizerId}> Video dimensions remain illegal after ${maxIterations} retries`);
return;
}
// fire first few rechecks in quick succession, but start increasing timeout
// later down the line.
if (iteration > 0 && iteration % 0 == 0) {
timeout = Math.min(2 * timeout, 1000);
}
this.logger.log('info', 'debug', `[Resizer::setAr] <rid:${this.resizerId}> Sleeping for ${timeout} ms`);
await sleep(timeout);
stretchFactors = this.scaler.calculateCrop(ar);
iteration++;
} while (stretchFactors.error === 'illegal_video_dimensions');
this.logger.log('info', 'debug', `[Resizer::setAr] <rid:${this.resizerId}> Video dimensions have corrected themselves after retrying.`);
} }
} }