Added thumbnailing for audio covers and external videos.
This commit is contained in:
parent
e81dc14740
commit
413a48e8bb
6 changed files with 73 additions and 4 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -4,3 +4,4 @@
|
||||||
/.debug
|
/.debug
|
||||||
/config.ini
|
/config.ini
|
||||||
/public/robots.txt
|
/public/robots.txt
|
||||||
|
/lib/index-dev
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 99a4e0c3027a7b29c58e0e0164cb831a03461527
|
Subproject commit 1a8344c1c31cb62726305d079384045582315f64
|
|
@ -41,6 +41,48 @@ final class v1_0 implements \Uiharu\IApi {
|
||||||
$router->post('/metadata', [$this, 'postMetadata']);
|
$router->post('/metadata', [$this, 'postMetadata']);
|
||||||
$router->get('/metadata/batch', [$this, 'getMetadataBatch']);
|
$router->get('/metadata/batch', [$this, 'getMetadataBatch']);
|
||||||
$router->post('/metadata/batch', [$this, 'postMetadataBatch']);
|
$router->post('/metadata/batch', [$this, 'postMetadataBatch']);
|
||||||
|
$router->get('/metadata/thumb/audio', [$this, 'getThumbAudio']);
|
||||||
|
$router->get('/metadata/thumb/video', [$this, 'getThumbVideo']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getThumbAudio($response, $request) {
|
||||||
|
$targetUrl = (string)$request->getParam('url');
|
||||||
|
|
||||||
|
if(empty($targetUrl))
|
||||||
|
return 400;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$parsedUrl = Url::parse($targetUrl);
|
||||||
|
} catch(InvalidArgumentException $ex) {
|
||||||
|
return 404;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$parsedUrl->isWeb())
|
||||||
|
return 400;
|
||||||
|
|
||||||
|
$response->setContentType('image/png');
|
||||||
|
$response->setCacheControl('public', 'max-age=31536000', 'immutable');
|
||||||
|
$response->setContent(FFMPEG::grabFirstAudioCover($parsedUrl));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getThumbVideo($response, $request) {
|
||||||
|
$targetUrl = (string)$request->getParam('url');
|
||||||
|
|
||||||
|
if(empty($targetUrl))
|
||||||
|
return 400;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$parsedUrl = Url::parse($targetUrl);
|
||||||
|
} catch(InvalidArgumentException $ex) {
|
||||||
|
return 404;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$parsedUrl->isWeb())
|
||||||
|
return 400;
|
||||||
|
|
||||||
|
$response->setContentType('image/png');
|
||||||
|
$response->setCacheControl('public', 'max-age=31536000', 'immutable');
|
||||||
|
$response->setContent(FFMPEG::grabFirstVideoFrame($parsedUrl));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getMetadata($response, $request) {
|
public function getMetadata($response, $request) {
|
||||||
|
|
|
@ -2,8 +2,25 @@
|
||||||
namespace Uiharu;
|
namespace Uiharu;
|
||||||
|
|
||||||
use stdClass;
|
use stdClass;
|
||||||
|
use Imagick;
|
||||||
|
use Index\IO\Stream;
|
||||||
|
use Index\IO\ProcessStream;
|
||||||
|
|
||||||
final class FFMPEG {
|
final class FFMPEG {
|
||||||
|
public static function grabFirstVideoFrame(string $url): Stream {
|
||||||
|
return new ProcessStream(
|
||||||
|
sprintf('ffmpeg -i %s -ss 00:00:00.000 -vframes 1 -c:v png -f image2pipe -', escapeshellarg($url)),
|
||||||
|
'rb'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function grabFirstAudioCover(string $url): Stream {
|
||||||
|
return new ProcessStream(
|
||||||
|
sprintf('ffmpeg -i %s -an -c:v png -f image2pipe -', escapeshellarg($url)),
|
||||||
|
'rb'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public static function probe(string $url): ?object {
|
public static function probe(string $url): ?object {
|
||||||
return json_decode(
|
return json_decode(
|
||||||
shell_exec(
|
shell_exec(
|
||||||
|
|
|
@ -68,10 +68,16 @@ class WebLookupMediaResult extends WebLookupResult implements \Uiharu\IHasMediaI
|
||||||
}
|
}
|
||||||
|
|
||||||
public function hasPreviewImage(): bool {
|
public function hasPreviewImage(): bool {
|
||||||
return $this->isImage();
|
return $this->isImage() || $this->isVideo() || $this->isAudio();
|
||||||
}
|
}
|
||||||
public function getPreviewImage(): string {
|
public function getPreviewImage(): string {
|
||||||
return (string)$this->url;
|
$url = (string)$this->url;
|
||||||
|
if($this->isVideo())
|
||||||
|
return '//' . $_SERVER['HTTP_HOST'] . '/metadata/thumb/video?url=' . rawurlencode($url);
|
||||||
|
if($this->isAudio())
|
||||||
|
return '//' . $_SERVER['HTTP_HOST'] . '/metadata/thumb/audio?url=' . rawurlencode($url);
|
||||||
|
|
||||||
|
return $url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getConfidence(): float {
|
public function getConfidence(): float {
|
||||||
|
|
|
@ -14,7 +14,10 @@ define('UIH_SOURCE', UIH_ROOT . '/src');
|
||||||
define('UIH_LIBRARY', UIH_ROOT . '/lib');
|
define('UIH_LIBRARY', UIH_ROOT . '/lib');
|
||||||
define('UIH_VERSION', '20230125');
|
define('UIH_VERSION', '20230125');
|
||||||
|
|
||||||
require_once UIH_LIBRARY . '/index/index.php';
|
define('UIH_NDX_PATH', UIH_LIBRARY . '/index');
|
||||||
|
define('UIH_NDX_PATH_DEV', UIH_LIBRARY . '/index-dev');
|
||||||
|
|
||||||
|
require_once (UIH_DEBUG && is_dir(UIH_NDX_PATH_DEV) ? UIH_NDX_PATH_DEV : UIH_NDX_PATH) . '/index.php';
|
||||||
|
|
||||||
Autoloader::addNamespace(__NAMESPACE__, UIH_SOURCE);
|
Autoloader::addNamespace(__NAMESPACE__, UIH_SOURCE);
|
||||||
Environment::setDebug(UIH_DEBUG);
|
Environment::setDebug(UIH_DEBUG);
|
||||||
|
|
Loading…
Reference in a new issue