Get autodetection to work at least on a basic level

This commit is contained in:
Tamius Han 2024-11-07 02:26:19 +01:00
parent c235b52e3b
commit 15133e561f
7 changed files with 61 additions and 40 deletions

View File

@ -183,7 +183,7 @@ export default {
// {id: 'videoSettings', label: 'Video settings', icon: 'crop'}, // {id: 'videoSettings', label: 'Video settings', icon: 'crop'},
{id: 'extensionSettings', label: 'Site and Extension options', icon: 'cogs' }, {id: 'extensionSettings', label: 'Site and Extension options', icon: 'cogs' },
{id: 'playerDetection', label: 'Player detection', icon: 'television-play'}, {id: 'playerDetection', label: 'Player detection', icon: 'television-play'},
// {id: 'autodetectionSettings', label: 'Autodetection options', icon: ''}, {id: 'autodetectionSettings', label: 'Autodetection options', icon: ''},
// {id: 'advancedOptions', label: 'Advanced options', icon: 'cogs' }, // {id: 'advancedOptions', label: 'Advanced options', icon: 'cogs' },
// {id: 'debugging', label: 'Debugging', icon: 'bug-outline' } // {id: 'debugging', label: 'Debugging', icon: 'bug-outline' }
{id: 'changelog', label: 'What\'s new', icon: 'information-box-outline' }, {id: 'changelog', label: 'What\'s new', icon: 'information-box-outline' },

View File

@ -4,9 +4,10 @@ import Logger from '../Logger';
import Settings from '../Settings'; import Settings from '../Settings';
import VideoData from '../video-data/VideoData'; import VideoData from '../video-data/VideoData';
import { Corner } from './enums/corner.enum'; import { Corner } from './enums/corner.enum';
import { VideoPlaybackState } from './enums/video-playback-state.enum';
import { GlCanvas } from './gl/GlCanvas'; import { GlCanvas } from './gl/GlCanvas';
import { AardCanvasStore } from './interfaces/aard-canvas-store.interface'; import { AardCanvasStore } from './interfaces/aard-canvas-store.interface';
import { AardDetectionSample, generateSampleArray } from './interfaces/aard-detection-sample.interface'; import { AardDetectionSample, generateSampleArray, resetSamples } from './interfaces/aard-detection-sample.interface';
import { AardStatus, initAardStatus } from './interfaces/aard-status.interface'; import { AardStatus, initAardStatus } from './interfaces/aard-status.interface';
import { AardTestResults, initAardTestResults, resetAardTestResults } from './interfaces/aard-test-results.interface'; import { AardTestResults, initAardTestResults, resetAardTestResults } from './interfaces/aard-test-results.interface';
import { AardTimers, initAardTimers } from './interfaces/aard-timers.interface'; import { AardTimers, initAardTimers } from './interfaces/aard-timers.interface';
@ -210,7 +211,7 @@ import { AardTimers, initAardTimers } from './interfaces/aard-timers.interface';
* - - - - - - - - - - - - - - - - - - - - - * - - - - - - - - - - - - - - - - - - - - -
* *
*/ */
class Aard { export class Aard {
//#region configuration parameters //#region configuration parameters
private logger: Logger; private logger: Logger;
@ -376,7 +377,9 @@ class Aard {
private onAnimationFrame(ts: DOMHighResTimeStamp) { private onAnimationFrame(ts: DOMHighResTimeStamp) {
if (this.canTriggerFrameCheck()) { if (this.canTriggerFrameCheck()) {
resetAardTestResults(this.testResults); resetAardTestResults(this.testResults);
resetSamples(this.canvasSamples);
this.main(); this.main();
} else {
} }
this.animationFrame = window.requestAnimationFrame( (ts: DOMHighResTimeStamp) => this.onAnimationFrame(ts)); this.animationFrame = window.requestAnimationFrame( (ts: DOMHighResTimeStamp) => this.onAnimationFrame(ts));
} }
@ -427,7 +430,8 @@ class Aard {
this.settings.active.arDetect.canvasDimensions.sampleCanvas.height this.settings.active.arDetect.canvasDimensions.sampleCanvas.height
); );
} }
if (! this.testResults.imageLine.invalidated) { // Both need to be checked
if (! (this.testResults.imageLine.invalidated || this.testResults.guardLine.invalidated)) {
// TODO: ensure no aspect ratio changes happen // TODO: ensure no aspect ratio changes happen
this.testResults.lastStage = 2; this.testResults.lastStage = 2;
break; break;
@ -625,6 +629,10 @@ class Aard {
|| this.testResults.guardLine.bottom < 0 || this.testResults.guardLine.bottom < 0
|| this.testResults.guardLine.bottom > height || this.testResults.guardLine.bottom > height
) { ) {
// we also need to reset guardline if out-of-bounds was detected,
// otherwise edgeScan might not work correctly
this.testResults.guardLine.top = -1;
this.testResults.guardLine.bottom = -1;
this.testResults.guardLine.invalidated = true; this.testResults.guardLine.invalidated = true;
return; return;
} }
@ -1047,7 +1055,7 @@ class Aard {
// Detect upper edge // Detect upper edge
{ {
row = topStart; row = Math.max(topStart, 0);
x = 0; x = 0;
isImage = false; isImage = false;
finishedRows = 0; finishedRows = 0;
@ -1063,16 +1071,16 @@ class Aard {
// check for image, after we're done `x` points to alpha channel // check for image, after we're done `x` points to alpha channel
isImage = isImage =
imageData[rowOffset + x++] > this.testResults.blackLevel imageData[rowOffset + x] > this.testResults.blackLevel
|| imageData[rowOffset + x++] > this.testResults.blackLevel || imageData[rowOffset + x + 1] > this.testResults.blackLevel
|| imageData[rowOffset + x++] > this.testResults.blackLevel; || imageData[rowOffset + x + 2] > this.testResults.blackLevel;
if (!isImage) { if (!isImage) {
// TODO: maybe some day mark this pixel as checked by writing to alpha channel // TODO: maybe some day mark this pixel as checked by writing to alpha channel
i++; i++;
continue; continue;
} }
if (!this.canvasSamples.top[i]) { if (this.canvasSamples.top[i] === -1) {
this.canvasSamples.top[i] = row; this.canvasSamples.top[i] = row;
finishedRows++; finishedRows++;
} }
@ -1111,16 +1119,16 @@ class Aard {
// check for image, after we're done `x` points to alpha channel // check for image, after we're done `x` points to alpha channel
isImage = isImage =
imageData[rowOffset + x++] > this.testResults.blackLevel imageData[rowOffset + x] > this.testResults.blackLevel
|| imageData[rowOffset + x++] > this.testResults.blackLevel || imageData[rowOffset + x + 1] > this.testResults.blackLevel
|| imageData[rowOffset + x++] > this.testResults.blackLevel; || imageData[rowOffset + x + 2] > this.testResults.blackLevel;
if (!isImage) { if (!isImage) {
// TODO: maybe some day mark this pixel as checked by writing to alpha channel // TODO: maybe some day mark this pixel as checked by writing to alpha channel
i++; i++;
continue; continue;
} }
if (!this.canvasSamples.bottom[i]) { if (this.canvasSamples.bottom[i] === -1) {
this.canvasSamples.bottom[i] = row; this.canvasSamples.bottom[i] = row;
finishedRows++; finishedRows++;
} }
@ -1131,8 +1139,6 @@ class Aard {
if (finishedRows >= detectionLimit) { if (finishedRows >= detectionLimit) {
break; break;
} }
row++;
} }
} }
} }
@ -1306,7 +1312,7 @@ class Aard {
// didn't change meaningfully from the first, in which chance we aren't. If the brightness increased // didn't change meaningfully from the first, in which chance we aren't. If the brightness increased
// anywhere between 'not enough' and 'too much', we mark the measurement as invalid. // anywhere between 'not enough' and 'too much', we mark the measurement as invalid.
if (lastSubpixel - firstSubpixel > this.settings.active.arDetect.edgeDetection.gradientTestMinDelta) { if (lastSubpixel - firstSubpixel > this.settings.active.arDetect.edgeDetection.gradientTestMinDelta) {
this.canvasSamples.top[i] = -1; this.canvasSamples.bottom[i] = -1;
} }
} }
@ -1610,6 +1616,12 @@ class Aard {
this.testResults.aspectRatioUncertain = true; this.testResults.aspectRatioUncertain = true;
return; return;
} }
if (maxOffset > 2) {
this.testResults.imageLine.top = this.testResults.aspectRatioCheck.topCandidate === Infinity ? -1 : this.testResults.aspectRatioCheck.topCandidate;
this.testResults.imageLine.bottom = this.testResults.aspectRatioCheck.bottomCandidate === Infinity ? -1 : this.testResults.aspectRatioCheck.bottomCandidate;
this.testResults.guardLine.top = Math.max(this.testResults.imageLine.top - 2, 0);
this.testResults.guardLine.bottom = Math.max(this.testResults.imageLine.bottom + 2, this.canvasStore.main.height - 1);
}
this.testResults.aspectRatioUncertain = false; this.testResults.aspectRatioUncertain = false;
this.testResults.letterboxWidth = candidateAvg; this.testResults.letterboxWidth = candidateAvg;
this.testResults.letterboxOffset = diff; this.testResults.letterboxOffset = diff;

View File

@ -1,4 +1,4 @@
enum VideoPlaybackState { export enum VideoPlaybackState {
NotInitialized, NotInitialized,
Playing, Playing,
Paused, Paused,

View File

@ -1,3 +1,5 @@
import {VideoPlaybackState} from '../enums/video-playback-state.enum';
export interface AardStatus { export interface AardStatus {
aardActive: boolean, aardActive: boolean,
checkInProgress: boolean, checkInProgress: boolean,

View File

@ -74,7 +74,8 @@ export function resetAardTestResults(results: AardTestResults): void {
results.isFinished = false; results.isFinished = false;
results.lastStage = 0; results.lastStage = 0;
results.notLetterbox = false; results.notLetterbox = false;
results.guardLine.invalidated = false results.imageLine.invalidated = false;
results.guardLine.invalidated = false;
results.guardLine.cornerViolations[0] = false; results.guardLine.cornerViolations[0] = false;
results.guardLine.cornerViolations[1] = false; results.guardLine.cornerViolations[1] = false;
results.guardLine.cornerViolations[2] = false; results.guardLine.cornerViolations[2] = false;

View File

@ -1,7 +1,6 @@
import Debug from '../../conf/Debug'; import Debug from '../../conf/Debug';
import PlayerData from './PlayerData'; import PlayerData from './PlayerData';
import Resizer from '../video-transform/Resizer'; import Resizer from '../video-transform/Resizer';
import ArDetector from '../ar-detect/ArDetector';
import AspectRatioType from '../../../common/enums/AspectRatioType.enum'; import AspectRatioType from '../../../common/enums/AspectRatioType.enum';
import CropModePersistence from '../../../common/enums/CropModePersistence.enum'; import CropModePersistence from '../../../common/enums/CropModePersistence.enum';
import * as _ from 'lodash'; import * as _ from 'lodash';
@ -16,6 +15,7 @@ import { SiteSettings } from '../settings/SiteSettings';
import { Ar } from '../../../common/interfaces/ArInterface'; import { Ar } from '../../../common/interfaces/ArInterface';
import { ExtensionStatus } from './ExtensionStatus'; import { ExtensionStatus } from './ExtensionStatus';
import { RunLevel } from '../../enum/run-level.enum'; import { RunLevel } from '../../enum/run-level.enum';
import { Aard } from '../aard/Aard';
/** /**
* VideoData handles CSS for the video element. * VideoData handles CSS for the video element.
@ -70,7 +70,9 @@ class VideoData {
pageInfo: PageInfo; pageInfo: PageInfo;
player: PlayerData; player: PlayerData;
resizer: Resizer; resizer: Resizer;
arDetector: ArDetector;
aard: Aard;
eventBus: EventBus; eventBus: EventBus;
extensionStatus: ExtensionStatus; extensionStatus: ExtensionStatus;
//#endregion //#endregion
@ -240,7 +242,15 @@ class VideoData {
return; return;
} }
this.resizer = new Resizer(this); this.resizer = new Resizer(this);
this.arDetector = new ArDetector(this); // this starts Ar detection. needs optional parameter that prevents ArDetector from starting
console.log('before init aard');
try {
this.aard = new Aard(this); // this starts Ar detection. needs optional parameter that prevents ArDetector from starting
console.log('after init aard');
} catch (e) {
console.error('Failed to start Aard!', e);
}
this.logger.log('info', ['debug', 'init'], '[VideoData::ctor] Created videoData with vdid', this.vdid); this.logger.log('info', ['debug', 'init'], '[VideoData::ctor] Created videoData with vdid', this.vdid);
@ -358,10 +368,10 @@ class VideoData {
this.eventBus?.unsetUpstreamBus(); this.eventBus?.unsetUpstreamBus();
try { try {
this.arDetector.stop(); this.aard.stop();
this.arDetector.destroy(); // this.arDetector.destroy();
} catch (e) {} } catch (e) {}
this.arDetector = undefined; this.aard = undefined;
try { try {
this.resizer.destroy(); this.resizer.destroy();
} catch (e) {} } catch (e) {}
@ -419,7 +429,7 @@ class VideoData {
disable(options?: {fromPlayer?: boolean}) { disable(options?: {fromPlayer?: boolean}) {
this.enabled = false; this.enabled = false;
this.arDetector?.stop(); this.aard?.stop();
this.video.classList.remove(this.baseCssName); this.video.classList.remove(this.baseCssName);
this.video.classList.remove(this.userCssClassName); this.video.classList.remove(this.userCssClassName);
@ -662,12 +672,8 @@ class VideoData {
// throw {error: 'VIDEO_DATA_DESTROYED', data: {videoData: this}}; // throw {error: 'VIDEO_DATA_DESTROYED', data: {videoData: this}};
return; return;
} }
if (this.arDetector){ if (! this.aard){
this.arDetector.init(); this.aard = new Aard(this);
}
else{
this.arDetector = new ArDetector(this);
this.arDetector.init();
} }
} }
@ -686,24 +692,24 @@ class VideoData {
this.hasDrm = false; this.hasDrm = false;
} }
if (!this.arDetector) { if (!this.aard) {
this.initArDetection(); this.initArDetection();
} }
this.arDetector.start(); this.aard.start();
} catch (e) { } catch (e) {
this.logger.log('warn', 'debug', '[VideoData::startArDetection()] Could not start aard for some reason. Was the function was called too early?', e); this.logger.log('warn', 'debug', '[VideoData::startArDetection()] Could not start aard for some reason. Was the function was called too early?', e);
} }
} }
resumeAutoAr(){ resumeAutoAr(){
if(this.arDetector){ if(this.aard){
this.startArDetection(); this.startArDetection();
} }
} }
stopArDetection() { stopArDetection() {
if (this.arDetector) { if (this.aard) {
this.arDetector.stop(); this.aard.stop();
} }
} }
//#endregion //#endregion

View File

@ -286,10 +286,10 @@ class Resizer {
// handle autodetection stuff // handle autodetection stuff
if (ar.type === AspectRatioType.Automatic) { if (ar.type === AspectRatioType.Automatic) {
this.videoData.arDetector?.start(); this.videoData.aard?.start();
return; return;
} else if (ar.type !== AspectRatioType.AutomaticUpdate) { } else if (ar.type !== AspectRatioType.AutomaticUpdate) {
this.videoData.arDetector?.stop(); this.videoData.aard?.stop();
} }
if (ar.type !== AspectRatioType.AutomaticUpdate) { if (ar.type !== AspectRatioType.AutomaticUpdate) {
@ -357,11 +357,11 @@ class Resizer {
// //
// unpause when using other modes // unpause when using other modes
if ((ar.type !== AspectRatioType.Automatic && ar.type !== AspectRatioType.AutomaticUpdate) || this.stretcher.mode === StretchType.Basic) { if ((ar.type !== AspectRatioType.Automatic && ar.type !== AspectRatioType.AutomaticUpdate) || this.stretcher.mode === StretchType.Basic) {
this.videoData?.arDetector?.pause(); this.videoData?.aard?.stop();
} else { } else {
if (ar.type !== AspectRatioType.AutomaticUpdate) { if (ar.type !== AspectRatioType.AutomaticUpdate) {
if (this.lastAr.type === AspectRatioType.Automatic || this.lastAr.type === AspectRatioType.AutomaticUpdate) { if (this.lastAr.type === AspectRatioType.Automatic || this.lastAr.type === AspectRatioType.AutomaticUpdate) {
this.videoData?.arDetector?.unpause(); this.videoData?.aard?.stop();
} }
} }
} }