import Debug from '../../conf/Debug'; import PlayerData from './PlayerData'; import Resizer from '../video-transform/Resizer'; import ArDetector from '../ar-detect/ArDetector'; import AspectRatioType from '../../../common/enums/AspectRatioType.enum'; import * as _ from 'lodash'; import BrowserDetect from '../../conf/BrowserDetect'; import Logger from '../Logger'; import Settings from '../Settings'; import PageInfo from './PageInfo'; import { sleep } from '../../../common/js/utils'; import { hasDrm } from '../ar-detect/DrmDetecor'; class VideoData { //#region flags arSetupComplete: boolean = false; destroyed: boolean = false; invalid: boolean = false; videoStatusOk: boolean = false; videoLoaded: boolean = false; videoDimensionsLoaded: boolean = false; paused: boolean = false; //#endregion //#region misc stuff vdid: string; video: any; observer: ResizeObserver; mutationObserver: MutationObserver; mutationObserverConf: MutationObserverInit = { attributes: true, attributeFilter: ['class', 'style'], attributeOldValue: true, }; extensionMode: any; userCssClassName: string; validationId: number; dimensions: any; //#endregion //#region helper objects logger: Logger; settings: Settings; pageInfo: PageInfo; player: PlayerData; resizer: Resizer; arDetector: ArDetector; //#endregion constructor(video, settings, pageInfo){ this.vdid = (Math.random()*100).toFixed(); this.logger = pageInfo.logger; this.arSetupComplete = false; this.video = video; this.destroyed = false; this.settings = settings; this.pageInfo = pageInfo; this.extensionMode = pageInfo.extensionMode; this.videoStatusOk = false; this.userCssClassName = `uw-fuck-you-and-do-what-i-tell-you_${this.vdid}`; this.videoLoaded = false; this.videoDimensionsLoaded = true; this.validationId = null; this.dimensions = { width: this.video.offsetWidth, height: this.video.offsetHeight, }; this.setupStageOne(); } async onVideoLoaded() { if (!this.videoLoaded) { /** * video.readyState 101: * 0 — no info. Can't play. * 1 — we have metadata but nothing else * 2 — we have data for current playback position, but not future <--- meaning current frame, meaning Aard can work here or higher * 3 — we have a lil bit for the future * 4 — we'll survive to the end */ if (!this.video?.videoWidth || !this.video?.videoHeight || this.video.readyState < 2) { return; // onVideoLoaded is a lie in this case } this.logger.log('info', 'init', '%c[VideoData::onVideoLoaded] ——————————— Initiating phase two of videoData setup ———————————', 'color: #0f9'); this.videoLoaded = true; this.videoDimensionsLoaded = true; try { await this.setupStageTwo(); this.logger.log('info', 'init', '%c[VideoData::onVideoLoaded] ——————————— videoData setup stage two complete ———————————', 'color: #0f9'); } catch (e) { this.logger.log('error', 'init', '%c[VideoData::onVideoLoaded] ——————————— Setup stage two failed. ———————————\n', 'color: #f00', e); } } else if (!this.videoDimensionsLoaded) { this.logger.log('info', 'debug', "%c[VideoData::restoreCrop] Recovering from illegal video dimensions. Resetting aspect ratio.", "background: #afd, color: #132"); this.restoreCrop(); this.videoDimensionsLoaded = true; } } videoUnloaded() { this.videoLoaded = false; } async injectBaseCss() { try { if (!this.mutationObserver) { this.setupMutationObserver(); } await this.pageInfo.injectCss(` .uw-ultrawidify-base-wide-screen { margin: 0px 0px 0px 0px !important; width: initial !important; align-self: start !important; justify-self: start !important; max-height: initial !important; max-width: initial !important; } `); } catch (e) { console.error('Failed to inject base css!', e); } } unsetBaseClass() { this.mutationObserver.disconnect(); this.mutationObserver = undefined; this.video.classList.remove('uw-ultrawidify-base-wide-screen'); } //#region