diff --git a/Web/Models/Entities/Media.php b/Web/Models/Entities/Media.php index d86e6441..b836955e 100644 --- a/Web/Models/Entities/Media.php +++ b/Web/Models/Entities/Media.php @@ -6,7 +6,9 @@ abstract class Media extends Postable { protected $fileExtension = "oct"; #octet stream xddd protected $upperNodeReferenceColumnName = "owner"; - + protected $processingPlaceholder = NULL; + protected $processingTime = 30; + function __destruct() { #Remove data, if model wasn't presisted @@ -22,6 +24,11 @@ abstract class Media extends Postable else return OPENVK_ROOT . "/storage/"; } + + protected function checkIfFileIsProcessed(): bool + { + throw new \LogicException("checkIfFileIsProcessed is not implemented"); + } abstract protected function saveFile(string $filename, string $hash): bool; @@ -41,6 +48,10 @@ abstract class Media extends Postable function getURL(): string { + if(!is_null($this->processingPlaceholder)) + if(!$this->isProcessed()) + return "/assets/packages/static/openvk/$this->processingPlaceholder.$this->fileExtension"; + $hash = $this->getRecord()->hash; switch(OPENVK_ROOT_CONF["openvk"]["preferences"]["uploads"]["mode"]) { @@ -68,6 +79,26 @@ abstract class Media extends Postable { return $this->getRecord()->description; } + + protected function isProcessed(): bool + { + if(is_null($this->processingPlaceholder)) + return true; + + if($this->getRecord()->processed) + return true; + + $timeDiff = time() - $this->getRecord()->last_checked; + if($timeDiff < $this->processingTime) + return false; + + $res = $this->checkIfFileIsProcessed(); + $this->stateChanges("last_checked", time()); + $this->stateChanges("processed", $res); + $this->save(); + + return $res; + } function isDeleted(): bool { @@ -89,7 +120,17 @@ abstract class Media extends Postable $this->stateChanges("hash", $hash); } - + + function save(): void + { + if(!is_null($this->processingPlaceholder)) { + $this->stateChanges("processed", 0); + $this->stateChanges("last_checked", time()); + } + + parent::save(); + } + function delete(bool $softly = true): void { $deleteQuirk = ovkGetQuirk("blobs.erase-upon-deletion"); diff --git a/Web/Models/Entities/Video.php b/Web/Models/Entities/Video.php index f57159b7..7bf1b010 100644 --- a/Web/Models/Entities/Video.php +++ b/Web/Models/Entities/Video.php @@ -14,6 +14,8 @@ class Video extends Media protected $tableName = "videos"; protected $fileExtension = "ogv"; + + protected $processingPlaceholder = "video/rendering"; protected function saveFile(string $filename, string $hash): bool { @@ -37,7 +39,7 @@ class Video extends Media throw new \DomainException("$filename does not contain any meaningful video streams"); try { - if(!is_dir($dirId = $this->pathFromHash($hash))) + if(!is_dir($dirId = dirname($this->pathFromHash($hash)))) mkdir($dirId); $dir = $this->getBaseDir(); @@ -53,7 +55,23 @@ class Video extends Media usleep(200100); return true; } - + + protected function checkIfFileIsProcessed(): bool + { + if($this->getType() != Video::TYPE_DIRECT) + return true; + + if(!file_exists($this->getFileName())) { + if((time() - $this->getRecord()->last_checked) > 3600) { + // TODO notify that video processor is probably dead + } + + return false; + } + + return true; + } + function getName(): string { return $this->getRecord()->name; @@ -83,6 +101,9 @@ class Video extends Media function getThumbnailURL(): string { if($this->getType() === Video::TYPE_DIRECT) { + if(!$this->isProcessed()) + return "/assets/packages/static/openvk/video/rendering.apng"; + return preg_replace("%\.[A-z]++$%", ".gif", $this->getURL()); } else { return $this->getVideoDriver()->getThumbnailURL(); diff --git a/Web/static/video/rendering.apng b/Web/static/video/rendering.apng new file mode 100644 index 00000000..417aa426 Binary files /dev/null and b/Web/static/video/rendering.apng differ diff --git a/Web/static/video/rendering.ogv b/Web/static/video/rendering.ogv new file mode 100644 index 00000000..938dc154 Binary files /dev/null and b/Web/static/video/rendering.ogv differ