mirror of
https://github.com/koel/koel
synced 2024-11-10 06:34:14 +00:00
fix(metadata): add support for vorbis tags/comments in FileSynchronizer
This commit is contained in:
parent
b6465c61e7
commit
4c7e2644a3
5 changed files with 71 additions and 19 deletions
|
@ -49,14 +49,16 @@ class FileSynchronizer
|
|||
|
||||
public function getFileScanInformation(): ?SongScanInformation
|
||||
{
|
||||
$info = $this->getID3->analyze($this->filePath);
|
||||
$this->syncError = Arr::get($info, 'error.0') ?: (Arr::get($info, 'playtime_seconds') ? null : 'Empty file');
|
||||
$raw = $this->getID3->analyze($this->filePath);
|
||||
$this->syncError = Arr::get($raw, 'error.0') ?: (Arr::get($raw, 'playtime_seconds') ? null : 'Empty file');
|
||||
|
||||
if ($this->syncError) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$info = SongScanInformation::fromGetId3Info($info);
|
||||
$this->getID3->CopyTagsToComments($raw);
|
||||
$info = SongScanInformation::fromGetId3Info($raw);
|
||||
|
||||
$info->lyrics = $info->lyrics ?: $this->lrcReader->tryReadForMediaFile($this->filePath);
|
||||
|
||||
return $info;
|
||||
|
|
|
@ -28,7 +28,12 @@ final class SongScanInformation implements Arrayable
|
|||
public static function fromGetId3Info(array $info): self
|
||||
{
|
||||
// We prefer ID3v2 tags over ID3v1 tags.
|
||||
$tags = array_merge(Arr::get($info, 'tags.id3v1', []), Arr::get($info, 'tags.id3v2', []));
|
||||
$tags = array_merge(
|
||||
Arr::get($info, 'tags.id3v1', []),
|
||||
Arr::get($info, 'tags.id3v2', []),
|
||||
Arr::get($info, 'comments', []),
|
||||
);
|
||||
|
||||
$comments = Arr::get($info, 'comments', []);
|
||||
|
||||
$albumArtistName = self::getTag($tags, ['albumartist', 'album_artist', 'band']);
|
||||
|
@ -41,16 +46,28 @@ final class SongScanInformation implements Arrayable
|
|||
|
||||
$path = Arr::get($info, 'filenamepath');
|
||||
|
||||
$cover = [self::getTag($comments, 'cover', null)];
|
||||
|
||||
if ($cover[0] === null) {
|
||||
$cover = self::getTag($comments, 'picture', []);
|
||||
}
|
||||
|
||||
$lyrics = html_entity_decode(self::getTag($tags, [
|
||||
'unsynchronised_lyric',
|
||||
'unsychronised_lyric',
|
||||
'unsyncedlyrics',
|
||||
]));
|
||||
|
||||
return new self(
|
||||
title: html_entity_decode(self::getTag($tags, 'title', pathinfo($path, PATHINFO_FILENAME))),
|
||||
albumName: html_entity_decode(self::getTag($tags, 'album', Album::UNKNOWN_NAME)),
|
||||
artistName: html_entity_decode(self::getTag($tags, 'artist', Artist::UNKNOWN_NAME)),
|
||||
albumArtistName: html_entity_decode($albumArtistName),
|
||||
track: (int) self::getTag($tags, ['track', 'tracknumber', 'track_number']),
|
||||
disc: (int) self::getTag($tags, 'part_of_a_set', 1),
|
||||
lyrics: html_entity_decode(self::getTag($tags, ['unsynchronised_lyric', 'unsychronised_lyric'])),
|
||||
disc: (int) self::getTag($tags, ['discnumber', 'part_of_a_set'], 1),
|
||||
lyrics: $lyrics,
|
||||
length: (float) Arr::get($info, 'playtime_seconds'),
|
||||
cover: self::getTag($comments, 'picture', []),
|
||||
cover: $cover,
|
||||
path: $path,
|
||||
mTime: Helper::getModifiedTime($path),
|
||||
);
|
||||
|
|
|
@ -47,6 +47,37 @@ class FileSynchronizerTest extends TestCase
|
|||
self::assertEqualsWithDelta(10, $info->length, 0.1);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function testGetFileInfoVorbisCommentsFlac(): void
|
||||
{
|
||||
$flacPath = __DIR__ . '/../../songs/full-vorbis-comments.flac';
|
||||
$info = $this->fileSynchronizer->setFile($flacPath)->getFileScanInformation();
|
||||
|
||||
$expectedData = [
|
||||
'artist' => 'Koel',
|
||||
'album' => 'Koel Testing Vol. 1',
|
||||
'albumartist' => 'Koel',
|
||||
'title' => 'Amet',
|
||||
'track' => 5,
|
||||
'disc' => 3,
|
||||
'lyrics' => "Foo\r\nbar",
|
||||
'cover' => [
|
||||
'data' => file_get_contents(__DIR__ . '/../../blobs/cover.png'),
|
||||
'image_mime' => 'image/png',
|
||||
'image_width' => 512,
|
||||
'image_height' => 512,
|
||||
'picturetype' => 'Other',
|
||||
'datalength' => 7627,
|
||||
],
|
||||
'path' => realpath($flacPath),
|
||||
'mtime' => filemtime($flacPath),
|
||||
];
|
||||
|
||||
self::assertArraySubset($expectedData, $info->toArray());
|
||||
self::assertEqualsWithDelta(10, $info->length, 0.1);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function testSongWithoutTitleHasFileNameAsTitle(): void
|
||||
{
|
||||
$this->fileSynchronizer->setFile(__DIR__ . '/../../songs/blank.mp3');
|
||||
|
|
|
@ -219,22 +219,24 @@ class MediaSyncServiceTest extends TestCase
|
|||
public function testHtmlEntities(): void
|
||||
{
|
||||
$path = $this->path('/songs/blank.mp3');
|
||||
$analyzed = [
|
||||
'filenamepath' => $path,
|
||||
'tags' => [
|
||||
'id3v2' => [
|
||||
'title' => ['水谷広実'],
|
||||
'album' => ['小岩井こ Random'],
|
||||
'artist' => ['佐倉綾音 Unknown'],
|
||||
],
|
||||
],
|
||||
'encoding' => 'UTF-8',
|
||||
'playtime_seconds' => 100,
|
||||
];
|
||||
|
||||
$this->swap(
|
||||
getID3::class,
|
||||
Mockery::mock(getID3::class, [
|
||||
'analyze' => [
|
||||
'filenamepath' => $path,
|
||||
'tags' => [
|
||||
'id3v2' => [
|
||||
'title' => ['水谷広実'],
|
||||
'album' => ['小岩井こ Random'],
|
||||
'artist' => ['佐倉綾音 Unknown'],
|
||||
],
|
||||
],
|
||||
'encoding' => 'UTF-8',
|
||||
'playtime_seconds' => 100,
|
||||
],
|
||||
'CopyTagsToComments' => $analyzed,
|
||||
'analyze' => $analyzed,
|
||||
])
|
||||
);
|
||||
|
||||
|
|
BIN
tests/songs/full-vorbis-comments.flac
Normal file
BIN
tests/songs/full-vorbis-comments.flac
Normal file
Binary file not shown.
Loading…
Reference in a new issue