AzuraCast/src/MediaProcessor/Command/ReadCommand.php

134 lines
3.6 KiB
PHP

<?php
declare(strict_types=1);
namespace App\MediaProcessor\Command;
use App\Entity;
use App\Utilities\Arrays;
use App\Utilities\Time;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use voku\helper\UTF8;
use const JSON_THROW_ON_ERROR;
class ReadCommand
{
public function __invoke(
SymfonyStyle $io,
OutputInterface $output,
string $path,
string $jsonOutput,
?string $artOutput
): int {
if (!is_file($path)) {
$io->error(sprintf('File not readable: %s', $path));
return 1;
}
$id3 = new \getID3();
$id3->option_md5_data = true;
$id3->option_md5_data_source = true;
$id3->encoding = 'UTF-8';
$info = $id3->analyze($path);
$id3->CopyTagsToComments($info);
if (!empty($info['error'])) {
$io->error(
sprintf(
'Cannot process media at path %s: %s',
pathinfo($path, PATHINFO_FILENAME),
json_encode($info['error'], JSON_THROW_ON_ERROR)
)
);
return 1;
}
$metadata = new Entity\Metadata();
if (is_numeric($info['playtime_seconds'])) {
$metadata->setDuration(
Time::displayTimeToSeconds($info['playtime_seconds']) ?? 0.0
);
}
$metaTags = [];
$toProcess = [
$info['comments'] ?? null,
$info['tags'] ?? null,
];
foreach ($toProcess as $tagSet) {
if (empty($tagSet)) {
continue;
}
foreach ($tagSet as $tagName => $tagContents) {
if (!empty($tagContents[0]) && !isset($metaTags[$tagName])) {
$tagValue = $tagContents[0];
if (is_array($tagValue)) {
// Skip pictures
if (isset($tagValue['data'])) {
continue;
}
$flatValue = Arrays::flattenArray($tagValue);
$tagValue = implode(', ', $flatValue);
}
$metaTags[$tagName] = $this->cleanUpString((string)$tagValue);
}
}
}
$metadata->setTags($metaTags);
$metadata->setMimeType($info['mime_type']);
file_put_contents(
$jsonOutput,
json_encode($metadata, JSON_THROW_ON_ERROR),
);
if (null !== $artOutput) {
$artwork = null;
if (!empty($info['attached_picture'][0])) {
$artwork = $info['attached_picture'][0]['data'];
} elseif (!empty($info['comments']['picture'][0])) {
$artwork = $info['comments']['picture'][0]['data'];
} elseif (!empty($info['id3v2']['APIC'][0]['data'])) {
$artwork = $info['id3v2']['APIC'][0]['data'];
} elseif (!empty($info['id3v2']['PIC'][0]['data'])) {
$artwork = $info['id3v2']['PIC'][0]['data'];
}
if (!empty($artwork)) {
file_put_contents(
$artOutput,
$artwork
);
}
}
return 0;
}
protected function cleanUpString(?string $original): string
{
$original ??= '';
$string = UTF8::encode('UTF-8', $original);
$string = UTF8::fix_simple_utf8($string);
return UTF8::clean(
$string,
true,
true,
true,
true,
true
);
}
}