Autodetection persists over multiple videos
This commit is contained in:
parent
82abee42bd
commit
4fe5ce6bcb
@ -41,7 +41,7 @@ var ExtensionConf = {
|
||||
ignoreEdgeMargin: 0.20, // we ignore anything that pokes over the black line this close to the edge
|
||||
// (relative to width of the sample)
|
||||
imageTestTreshold: 0.1, // when testing for image, this much pixels must be over blackbarTreshold
|
||||
edgeTolerancePx: 3, // black edge violation is performed this far from reported 'last black pixel'
|
||||
edgeTolerancePx: 2, // black edge violation is performed this far from reported 'last black pixel'
|
||||
edgeTolerancePercent: null // unused. same as above, except use % of canvas height instead of pixels
|
||||
},
|
||||
fallbackMode: {
|
||||
|
@ -1,6 +1,7 @@
|
||||
class VideoData {
|
||||
|
||||
constructor(video){
|
||||
this.arSetupComplete = false;
|
||||
this.video = video;
|
||||
|
||||
// POZOR: VRSTNI RED JE POMEMBEN (arDetect mora bit zadnji)
|
||||
@ -14,8 +15,17 @@ class VideoData {
|
||||
// this.player.dimensions
|
||||
}
|
||||
|
||||
firstTimeArdInit(){
|
||||
if(! this.arSetupComplete){
|
||||
this.arDetector = new ArDetector(this);
|
||||
}
|
||||
}
|
||||
|
||||
initArDetection() {
|
||||
this.arDetector.init();
|
||||
if(ths.arDetector)
|
||||
this.arDetector.init();
|
||||
else
|
||||
this.arDetector = new ArDetector(this);
|
||||
}
|
||||
|
||||
startArDetection() {
|
||||
@ -23,7 +33,15 @@ class VideoData {
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.arDetector.stop();
|
||||
if(this.arDetector){
|
||||
this.arDetector.stop();
|
||||
this.arDetector.destroy();
|
||||
}
|
||||
this.arDetector = null;
|
||||
if(this.resizer){
|
||||
this.resizer.destroy();
|
||||
}
|
||||
this.video = null;
|
||||
}
|
||||
|
||||
setLastAr(lastAr){
|
||||
|
@ -28,6 +28,10 @@ class ArDetector {
|
||||
this.setup(ExtensionConf.arDetect.hSamples, ExtensionConf.arDetect.vSamples);
|
||||
}
|
||||
|
||||
destroy(){
|
||||
this.debugCanvas.destroy();
|
||||
}
|
||||
|
||||
setup(cwidth, cheight){
|
||||
if(Debug.debug){
|
||||
console.log("[ArDetect::setup] Starting autodetection setup");
|
||||
@ -73,7 +77,7 @@ class ArDetector {
|
||||
|
||||
if(this.video.videoWidth === 0 || this.video.videoHeight === 0 ){
|
||||
if(! this.timer)
|
||||
this.setupTimer = setTimeout(_arSetup, 100);
|
||||
this.setupTimer = setTimeout(this.init(), 100);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -145,6 +149,8 @@ class ArDetector {
|
||||
this.debugCanvas.init({width: cwidth, height: cheight});
|
||||
// DebugCanvas.draw("test marker","test","rect", {x:5, y:5}, {width: 5, height: 5});
|
||||
}
|
||||
|
||||
this.conf.arSetupComplete = true;
|
||||
}
|
||||
|
||||
start(){
|
||||
@ -332,8 +338,8 @@ class ArDetector {
|
||||
|
||||
if(! this.video){
|
||||
if(Debug.debug || Debug.warnings_critical)
|
||||
console.log("[ArDetect::_ard_vdraw] Video went missing. Stopping current instance of automatic detection.")
|
||||
this.stop();
|
||||
console.log("[ArDetect::_ard_vdraw] Video went missing. Destroying current instance of videoData.")
|
||||
this.conf.destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -350,8 +356,8 @@ class ArDetector {
|
||||
|
||||
var how_far_treshold = 8; // how much can the edge pixel vary (*4)
|
||||
|
||||
if(this.video == null || this.video.ended ){
|
||||
// we slow down if ended or null. Detecting is pointless.
|
||||
if(this.video.ended ){
|
||||
// we slow down if ended. Detecting is pointless.
|
||||
|
||||
this.scheduleFrameCheck(ExtensionConf.arDetect.timer_paused);
|
||||
return false;
|
||||
@ -502,7 +508,7 @@ class ArDetector {
|
||||
// let's chec if we ever reset CSS. If we haven't, then we do so. If we did, then we don't.
|
||||
// while resetting the CSS, we also reset guardline top and bottom back to null.
|
||||
|
||||
if(! GlobalVars.arDetect.noLetterboxCanvasReset){
|
||||
if(! this.noLetterboxCanvasReset){
|
||||
this.conf.resizer.reset({type: "auto", ar: null});
|
||||
this.guardLine.top = null;
|
||||
this.guardLine.bottom = null;
|
||||
@ -518,7 +524,7 @@ class ArDetector {
|
||||
// css resetiral enkrat na video/pageload namesto vsakič, ko so za nekaj časa obrobe odstranejene
|
||||
// if we look further we need to reset this value back to false. Otherwise we'll only get CSS reset once
|
||||
// per video/pageload instead of every time letterbox goes away (this can happen more than once per vid)
|
||||
GlobalVars.arDetect.noLetterboxCanvasReset = false;
|
||||
this.noLetterboxCanvasReset = false;
|
||||
|
||||
// let's do a quick test to see if we're on a black frame
|
||||
// TODO: reimplement but with less bullshit
|
||||
@ -542,7 +548,7 @@ class ArDetector {
|
||||
if (fallbackMode && guardLineOut.blackbarFail) {
|
||||
this.conf.resizer.reset({type: "auto", ar: null});
|
||||
this.guardLine.reset();
|
||||
this.arDetect.noLetterboxCanvasReset = true;
|
||||
this.noLetterboxCanvasReset = true;
|
||||
|
||||
triggerTimeout = this.getTimeout(baseTimeout, startTime);
|
||||
this.scheduleFrameCheck(triggerTimeout); //no letterbox, no problem
|
||||
@ -565,7 +571,7 @@ class ArDetector {
|
||||
// If aspect ratio changes from narrower to wider, we first check for presence of pillarbox. Presence of pillarbox indicates
|
||||
// a chance of a logo on black background. We could cut easily cut too much. Because there's a somewhat significant chance
|
||||
// that we will cut too much, we rather avoid doing anything at all. There's gonna be a next chance.
|
||||
|
||||
try{
|
||||
if(guardLineOut.blackbarFail || guardLineOut.imageFail){
|
||||
if(this.edgeDetector.findBars(image, null, EdgeDetectPrimaryDirection.HORIZONTAL).status === 'ar_known'){
|
||||
|
||||
@ -573,7 +579,7 @@ class ArDetector {
|
||||
console.log("[ArDetect::_ard_vdraw] Detected blackbar violation and pillarbox. Resetting to default aspect ratio.");
|
||||
}
|
||||
|
||||
if(! guardLineResult){
|
||||
if(guardLineOut.blackbarFail){
|
||||
this.conf.resizer.reset({type: "auto", ar: null});
|
||||
this.guardLine.reset();
|
||||
}
|
||||
@ -584,6 +590,7 @@ class ArDetector {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}catch(e) {console.log("deeee",e)}
|
||||
|
||||
// pa poglejmo, kje se končajo črne letvice na vrhu in na dnu videa.
|
||||
// let's see where black bars end.
|
||||
|
@ -34,6 +34,10 @@ class DebugCanvas {
|
||||
console.log("debug canvas is:", this.canvas, "context:", this.context)
|
||||
}
|
||||
|
||||
destroy(){
|
||||
this.canvas.remove();
|
||||
}
|
||||
|
||||
setBuffer(buffer) {
|
||||
// this.imageBuffer = buffer.splice(0);
|
||||
this.imageBuffer = new Uint8ClampedArray(buffer);
|
||||
@ -77,8 +81,8 @@ class DebugCanvas {
|
||||
}
|
||||
|
||||
DebugCanvasClasses = {
|
||||
VIOLATION: {color: '#ff4400', colorRgb: [255, 68, 0], text: 'violation (general)'},
|
||||
WARN: {color: '#d08539', colorRgb: [208, 133, 57], text: 'lesser violation (general)'},
|
||||
VIOLATION: {color: '#ff0000', colorRgb: [255, 00, 0], text: 'violation (general)'},
|
||||
WARN: {color: '#d0d039', colorRgb: [208, 208, 57], text: 'lesser violation (general)'},
|
||||
GUARDLINE_BLACKBAR: {color: '#3333FF', colorRgb: [51, 51, 255], text: 'guardline/blackbar (expected value)'},
|
||||
GUARDLINE_IMAGE: {color: '#000088', colorRgb: [0, 0, 136], text: 'guardline/image (expected value)'},
|
||||
|
||||
|
@ -12,33 +12,69 @@ class PageInfo {
|
||||
}
|
||||
|
||||
rescan(count){
|
||||
try{
|
||||
var vids = document.getElementsByTagName('video');
|
||||
|
||||
if(!vids || vids.length == 0){
|
||||
this.hasVideos = false;
|
||||
|
||||
this.scheduleRescan();
|
||||
return;
|
||||
}
|
||||
|
||||
// debugger;
|
||||
|
||||
// add new videos
|
||||
for(var video of vids){
|
||||
var existing = this.videos.find( (x) => {
|
||||
if (x == video.video)
|
||||
return x;
|
||||
if (x.currentSrc == video.video.currentSrc){
|
||||
return x;
|
||||
}
|
||||
})
|
||||
// for(var video of vids){
|
||||
// var existing = this.videos.find( (x) => {
|
||||
// if (video && x == video.video)
|
||||
// return x;
|
||||
// if (video && x.currentSrc == video.video.currentSrc){
|
||||
// return x;
|
||||
// }
|
||||
// })
|
||||
|
||||
if(existing){
|
||||
video.video = existing;
|
||||
// if(existing){
|
||||
// video.video = existing;
|
||||
// } else {
|
||||
// this.videos.push(
|
||||
// new VideoData(video)
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
if(this.videos.length > 0){
|
||||
if(vids[0] == this.videos[0].video){
|
||||
// do nothing
|
||||
} else {
|
||||
this.videos.push(
|
||||
new VideoData(video)
|
||||
);
|
||||
this.videos[0].destroy();
|
||||
this.videos[0] = new VideoData(vids[0]);
|
||||
}
|
||||
} else {
|
||||
this.videos.push(new VideoData(vids[0]));
|
||||
}
|
||||
|
||||
console.log("Rescan complete. Total videos?", this.videos.length)
|
||||
}catch(e){
|
||||
console.log("rescan error:",e)
|
||||
}
|
||||
this.scheduleRescan();
|
||||
}
|
||||
|
||||
scheduleRescan(){
|
||||
try{
|
||||
if(this.rescanTimer){
|
||||
clearTimeout(this.rescanTimer);
|
||||
}
|
||||
|
||||
var ths = this;
|
||||
|
||||
|
||||
this.rescanTimer = setTimeout(function(){
|
||||
ths.rescanTimer = null;
|
||||
ths.rescan();
|
||||
ths = null;
|
||||
}, 1000)
|
||||
}catch(e){console.log("eee",e)}
|
||||
}
|
||||
|
||||
initArDetection(){
|
||||
|
@ -30,8 +30,13 @@ class Resizer {
|
||||
this.restore_wd = false;
|
||||
|
||||
this.lastAr = {type: 'original'};
|
||||
this.destroyed = false;
|
||||
}
|
||||
|
||||
destroy(){
|
||||
this.destroyed = true;
|
||||
this.stopCssWatcher();
|
||||
}
|
||||
|
||||
setAr(ar, lastAr){
|
||||
if(Debug.debug){
|
||||
@ -50,15 +55,17 @@ class Resizer {
|
||||
|
||||
if (! this.video) {
|
||||
// console.log("No video detected.")
|
||||
// this.videoData.destroy();
|
||||
this.videoData.destroy();
|
||||
}
|
||||
|
||||
|
||||
var dimensions = Scaler.calculateCrop(ar, this.video, this.conf.player.dimensions);
|
||||
|
||||
if(dimensions.error){
|
||||
if(! dimensions || dimensions.error){
|
||||
if(Debug.debug){
|
||||
console.log("[Resizer::setAr] failed to set AR due to problem with calculating crop. Error:", dimensions.error)
|
||||
console.log("[Resizer::setAr] failed to set AR due to problem with calculating crop. Error:", (dimensions ? dimensions.error : dimensions));
|
||||
}
|
||||
if(dimensions.error === 'no_video'){
|
||||
this.conf.destroy();
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -75,6 +82,9 @@ class Resizer {
|
||||
|
||||
var cssOffsets = this.computeOffsets(dimensions);
|
||||
this.applyCss(cssOffsets, stretchFactors);
|
||||
|
||||
if(! this.destroyed)
|
||||
this.startCssWatcher();
|
||||
}
|
||||
|
||||
setLastAr(override){
|
||||
@ -101,10 +111,18 @@ class Resizer {
|
||||
}
|
||||
|
||||
startCssWatcher(){
|
||||
this.cssWatcherTimeout = setInterval(this.cssWatcher, 200);
|
||||
// this.haltCssWatcher = false;
|
||||
if(!this.cssWatcherTimeout){
|
||||
if(Debug.debug)
|
||||
console.log("[Resizer.js] STARTING CSS WATCHER")
|
||||
|
||||
this.cssWatcherTimeout = setInterval(this.cssWatcher, 200, this);
|
||||
}
|
||||
}
|
||||
|
||||
stopCssWatcher(){
|
||||
if(Debug.debug) console.log("[Resizer.js] STOPPING CSS WATCHER!")
|
||||
|
||||
clearInterval(this.cssWatcherTimeout);
|
||||
}
|
||||
|
||||
@ -190,12 +208,20 @@ class Resizer {
|
||||
|
||||
applyCss(dimensions, stretchFactors){
|
||||
|
||||
if(this.video == undefined || this.video == null){
|
||||
if (! this.video ){
|
||||
if(Debug.debug)
|
||||
console.log("[Resizer::_res_applyCss] Video went missing, doing nothing.");
|
||||
this.conf.destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
// save stuff for quick tests (before we turn numbers into css values):
|
||||
this.currentVideoSettings = {
|
||||
validFor: this.conf.player.dimensions,
|
||||
videoWidth: dimensions.width,
|
||||
videoHeight: dimensions.height
|
||||
}
|
||||
|
||||
if(Debug.debug)
|
||||
console.log("[Resizer::_res_applyCss] Starting to apply css. this is what we're getting in:", dimensions);
|
||||
|
||||
@ -284,6 +310,9 @@ class Resizer {
|
||||
styleString += styleArray[i] + "; ";
|
||||
|
||||
this.setStyleString(styleString);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
setStyleString (styleString, count = 0) {
|
||||
@ -322,21 +351,31 @@ class Resizer {
|
||||
}
|
||||
}
|
||||
|
||||
cssWatcher(){
|
||||
|
||||
cssWatcher(ths){
|
||||
// this means we haven't set our CSS yet, or that we changed video.
|
||||
if(! this.currentCss.top)
|
||||
if(! ths.currentCss.top)
|
||||
return;
|
||||
|
||||
// this means video went missing.
|
||||
if(! this.video)
|
||||
// this means video went missing. videoData will be re-initialized when the next video is found
|
||||
if(! ths.video){
|
||||
ths.conf.destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
// // our current css is fucky? Null, undefined and 0 are invalid values.
|
||||
// if(! GlobalVars.currentCss.width || ! GlobalVars.currentCss.height )
|
||||
// return;
|
||||
|
||||
// first, a quick test:
|
||||
if (ths.currentVideoSettings.validFor == ths.conf.player.dimensions ){
|
||||
if (ths.currentVideoSettings.videoWidth != ths.video.offsetWidth ||
|
||||
ths.currentVideoSettings.videoHeight != ths.video.offsetHeight){
|
||||
ths.restore();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var styleArrayStr = this.video.getAttribute('style');
|
||||
var styleArrayStr = ths.video.getAttribute('style');
|
||||
|
||||
if (styleArrayStr){
|
||||
var styleArray = styleArrayStr.split(";");
|
||||
@ -349,24 +388,24 @@ class Resizer {
|
||||
|
||||
if (styleArray[i].startsWith("top:")){
|
||||
// don't force css restore if currentCss.top is not defined
|
||||
if(this.currentCss.top && styleArray[i] != this.currentCss.top){
|
||||
if(ths.currentCss.top && styleArray[i] != ths.currentCss.top){
|
||||
if(Debug.debug){
|
||||
console.log("[Resizer::_res_antiCssOverride] SOMEBODY TOUCHED MA SPAGHETT (our CSS got overriden, restoring our css)");
|
||||
console.log("[Resizer::_res_antiCssOverride] MA SPAGHETT: top:", this.currentCss.top, "left:", this.currentCss.left, "thing that touched ma spaghett", styleArrayStr);
|
||||
console.log("[Resizer::_res_antiCssOverride] MA SPAGHETT: top:", ths.currentCss.top, "left:", ths.currentCss.left, "thing that touched ma spaghett", styleArrayStr);
|
||||
}
|
||||
_res_restore();
|
||||
ths.restore();
|
||||
return;
|
||||
}
|
||||
stuffChecked++;
|
||||
}
|
||||
else if(styleArray[i].startsWith("left:")){
|
||||
// don't force css restore if currentCss.left is not defined
|
||||
if(this.currentCss.left && styleArray[i] != this.currentCss.left){
|
||||
if(ths.currentCss.left && styleArray[i] != ths.currentCss.left){
|
||||
if(Debug.debug){
|
||||
console.log("[Resizer::_res_antiCssOverride] SOMEBODY TOUCHED MA SPAGHETT (our CSS got overriden, restoring our css)");
|
||||
console.log("[Resizer::_res_antiCssOverride] MA SPAGHETT: width:", this.currentCss.width, "height:", this.currentCss.height, "thing that touched ma spaghett", styleArrayStr);
|
||||
console.log("[Resizer::_res_antiCssOverride] MA SPAGHETT: width:", ths.currentCss.width, "height:", ths.currentCss.height, "thing that touched ma spaghett", styleArrayStr);
|
||||
}
|
||||
_res_restore();
|
||||
ths.restore();
|
||||
return;
|
||||
}
|
||||
stuffChecked++;
|
||||
|
@ -57,21 +57,7 @@ class Scaler {
|
||||
}
|
||||
|
||||
static calculateCrop(mode, video, playerDimensions) {
|
||||
// if 'ar' is string, we'll handle that in legacy wrapper
|
||||
var ar = 0;
|
||||
if(isNaN(mode)){
|
||||
ar = this.modeToAr(mode);
|
||||
} else {
|
||||
ar = mode;
|
||||
}
|
||||
|
||||
// handle fuckie-wuckies
|
||||
if (! ar){
|
||||
return null;
|
||||
}
|
||||
|
||||
if(Debug.debug)
|
||||
console.log("[Scaler::calculateCrop] trying to set ar. args are: ar->",ar,"; playerDimensions->",playerDimensions.width, "×", playerDimensions.height, "| obj:", playerDimensions);
|
||||
|
||||
if(!video || video.videoWidth == 0 || video.videoHeight == 0){
|
||||
if(Debug.debug)
|
||||
@ -79,6 +65,25 @@ class Scaler {
|
||||
return {error: "no_video"};
|
||||
}
|
||||
|
||||
|
||||
// if 'ar' is string, we'll handle that in legacy wrapper
|
||||
var ar = 0;
|
||||
if(isNaN(mode)){
|
||||
ar = Scaler.modeToAr(mode);
|
||||
} else {
|
||||
ar = mode;
|
||||
}
|
||||
|
||||
// handle fuckie-wuckies
|
||||
if (! ar){
|
||||
if(Debug.debug)
|
||||
console.log("[Scaler::calculateCrop] no ar?", ar, " -- we were given this mode:", mode);
|
||||
return {error: "no_ar", ar: ar};
|
||||
}
|
||||
|
||||
if(Debug.debug)
|
||||
console.log("[Scaler::calculateCrop] trying to set ar. args are: ar->",ar,"; playerDimensions->",playerDimensions.width, "×", playerDimensions.height, "| obj:", playerDimensions);
|
||||
|
||||
if( (! playerDimensions) || playerDimensions.width === 0 || playerDimensions.height === 0 ){
|
||||
if(Debug.debug)
|
||||
console.log("[Scaler::calculateCrop] ERROR — no (or invalid) playerDimensions:",playerDimensions);
|
||||
|
Loading…
Reference in New Issue
Block a user