diff --git a/README.md b/README.md index e32c706..abe1f22 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ Core metadata: ```php use Kiwilan\Audio\Audio; -$audio = Audio::get('path/to/audio.mp3'); +$audio = Audio::read('path/to/audio.mp3'); $audio->getTitle(); // `?string` to get title $audio->getArtist(); // `?string` to get artist @@ -74,7 +74,7 @@ Raw tags: ```php use Kiwilan\Audio\Audio; -$audio = Audio::get('path/to/audio.mp3'); +$audio = Audio::read('path/to/audio.mp3'); $audio->getTags(); // `array` with all tags $title = $audio->getTag('title'); // `?string` to get title same as `$audio->getTitle()` @@ -90,7 +90,7 @@ Additional metadata: ```php use Kiwilan\Audio\Audio; -$audio = Audio::get('path/to/audio.mp3'); +$audio = Audio::read('path/to/audio.mp3'); $audio->getPath(); // `string` to get path $audio->hasCover(); // `bool` to know if has cover @@ -109,7 +109,7 @@ Raw audio: ```php use Kiwilan\Audio\Audio; -$audio = Audio::get('path/to/audio.mp3'); +$audio = Audio::read('path/to/audio.mp3'); $audio->toArray(); // `array` with all metadata ``` @@ -119,7 +119,7 @@ Advanced properties: ```php use Kiwilan\Audio\Audio; -$audio = Audio::get('path/to/audio.mp3'); +$audio = Audio::read('path/to/audio.mp3'); $audio->getReader(); // `?Id3Reader` reader based on `getID3` $audio->getWriter(); // `?Id3Writer` writer based on `getid3_writetags` @@ -139,7 +139,7 @@ You can update audio files metadata with `Audio::class`, but not all formats are ```php use Kiwilan\Audio\Audio; -$audio = Audio::get('path/to/audio.mp3'); +$audio = Audio::read('path/to/audio.mp3'); $audio->getTitle(); // `Title` $tag = $audio->update() @@ -163,7 +163,7 @@ $tag = $audio->update() ->cover('path/to/cover.jpg') // you can use file content `file_get_contents('path/to/cover.jpg')` ->save(); -$audio = Audio::get('path/to/audio.mp3'); +$audio = Audio::read('path/to/audio.mp3'); $audio->getTitle(); // `New Title` $audio->getCreationDate(); // `null` because `creationDate` is not supported by `MP3` ``` @@ -183,7 +183,7 @@ You can set tags manually with `tags` method, but you need to know the format of ```php use Kiwilan\Audio\Audio; -$audio = Audio::get('path/to/audio.mp3'); +$audio = Audio::read('path/to/audio.mp3'); $audio->getAlbumArtist(); // `Band` $tag = $audio->update() @@ -194,7 +194,7 @@ $tag = $audio->update() ->tagFormats(['id3v1', 'id3v2.4']) // optional ->save(); -$audio = Audio::get('path/to/audio.mp3'); +$audio = Audio::read('path/to/audio.mp3'); $audio->getAlbumArtist(); // `New Band` ``` @@ -203,7 +203,7 @@ $audio->getAlbumArtist(); // `New Band` ```php use Kiwilan\Audio\Audio; -$audio = Audio::get('path/to/audio.mp3'); +$audio = Audio::read('path/to/audio.mp3'); $audio->getAlbumArtist(); // `Band` $tag = $audio->update() @@ -211,7 +211,7 @@ $tag = $audio->update() ->albumArtist('New Band') // `albumArtist` will set `band` for `id3v2`, exception safe ->save(); -$audio = Audio::get('path/to/audio.mp3'); +$audio = Audio::read('path/to/audio.mp3'); $audio->getAlbumArtist(); // `New Band` ``` @@ -222,7 +222,7 @@ You can use `preventFailOnError` to prevent exception if you use unsupported for ```php use Kiwilan\Audio\Audio; -$audio = Audio::get('path/to/audio.mp3'); +$audio = Audio::read('path/to/audio.mp3'); $tag = $audio->update() ->tags([ @@ -238,7 +238,7 @@ Arrow functions are exception safe for properties but not for unsupported format ```php use Kiwilan\Audio\Audio; -$audio = Audio::get('path/to/audio.mp3'); +$audio = Audio::read('path/to/audio.mp3'); $tag = $audio->update() ->encoding('New encoding') // not supported by `id3v2`, BUT will not throw an exception @@ -253,7 +253,7 @@ Of course you can add cover with `tags` method. ```php use Kiwilan\Audio\Audio; -$audio = Audio::get('path/to/audio.mp3'); +$audio = Audio::read('path/to/audio.mp3'); $cover = 'path/to/cover.jpg'; $image = getimagesize($cover); @@ -285,7 +285,7 @@ Merge `tags` with arrow functions. ```php use Kiwilan\Audio\Audio; -$audio = Audio::get($path); +$audio = Audio::read($path); $tag = $audio->update() ->title('New Title') // will be merged with `tags` and override `title` key @@ -296,7 +296,7 @@ $tag = $audio->update() $tag->save(); -$audio = Audio::get($path); +$audio = Audio::read($path); expect($audio->getTitle())->toBe('New Title'); expect($audio->getAlbumArtist())->toBe('New Band'); ``` @@ -310,7 +310,7 @@ If you want to extract specific field which can be skipped by `Audio::class`, yo ```php use Kiwilan\Audio\Audio; -$audio = Audio::get('path/to/audio.mp3'); +$audio = Audio::read('path/to/audio.mp3'); $extras = $audio->getExtras(); $id3v2 = $extras['id3v2'] ?? []; @@ -321,7 +321,7 @@ $id3v2 = $extras['id3v2'] ?? []; ```php use Kiwilan\Audio\Audio; -$audio = Audio::get('path/to/audio.mp3'); +$audio = Audio::read('path/to/audio.mp3'); $audio->getAudio()->getFilesize(); // `?int` in bytes $audio->getAudio()->getExtension(); // `?string` (mp3, m4a, ...) @@ -343,7 +343,7 @@ $audio->getAudio()->getCompressionRatio(); // `?float` ```php use Kiwilan\Audio\Audio; -$audio = Audio::get('path/to/audio.mp3'); +$audio = Audio::read('path/to/audio.mp3'); $audio->getCover()->getContents(); // `?string` raw file $audio->getCover()->getMimeType(); // `?string` (image/jpeg, image/png, ...) @@ -474,7 +474,7 @@ In `Audio::class`, you have a property `extras` which contains all raw metadata, ```php use Kiwilan\Audio\Audio; -$audio = Audio::get('path/to/audio.mp3'); +$audio = Audio::read('path/to/audio.mp3'); $extras = $audio->getExtras(); $custom = null; @@ -494,7 +494,7 @@ You can check `extras` property to know if some metadata are available. ```php use Kiwilan\Audio\Audio; -$audio = Audio::get('path/to/audio.mp3'); +$audio = Audio::read('path/to/audio.mp3'); $extras = $audio->getExtras(); var_dump($extras); diff --git a/composer.json b/composer.json index 2c74a7b..346ddc6 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,8 @@ "wma", "wv", "wav", - "webm" + "webm", + "music" ], "homepage": "https://github.com/kiwilan/php-audio", "license": "MIT", diff --git a/src/Audio.php b/src/Audio.php index 0015c74..959a267 100755 --- a/src/Audio.php +++ b/src/Audio.php @@ -50,7 +50,7 @@ protected function __construct( protected array $raw_tags_all = [], ) {} - public static function get(string $path): self + public static function read(string $path): self { $fileExists = file_exists($path); if (! $fileExists) { @@ -82,6 +82,16 @@ public static function get(string $path): self return $self; } + /** + * @deprecated Use `read()` method instead. + * + * Get audio file from path. + */ + public static function get(string $path): self + { + return self::read($path); + } + /** * Get audio file path, like `/path/to/audio.mp3`. */ diff --git a/src/Core/AudioCore.php b/src/Core/AudioCore.php index 55e9ec0..51858e1 100644 --- a/src/Core/AudioCore.php +++ b/src/Core/AudioCore.php @@ -66,7 +66,6 @@ public static function toId3v2(AudioCore $core): Tag\Id3TagAudioV2 track_number: $core->track_number, year: (string) $core->year, copyright: $core->copyright, - text: $core->synopsis, unsynchronised_lyric: $core->lyrics, language: $core->language, ); diff --git a/src/Core/AudioCoreCover.php b/src/Core/AudioCoreCover.php index 574b188..68799cc 100644 --- a/src/Core/AudioCoreCover.php +++ b/src/Core/AudioCoreCover.php @@ -5,62 +5,26 @@ class AudioCoreCover { public function __construct( - protected ?string $data = null, - protected ?int $picture_type_id = null, - protected ?string $description = null, - protected ?string $mime = null, + public ?string $data = null, + public ?int $picture_type_id = null, + public ?string $description = null, + public ?string $mime = null, ) {} public static function make(string $pathOrData): self { $self = new self; - if (file_exists($pathOrData)) { - $image = getimagesize($pathOrData); - $self->data = base64_encode(file_get_contents($pathOrData)); - $self->picture_type_id = $image[2]; - $self->description = 'cover'; - $self->mime = $image['mime']; - - return $self; - } - - $image = getimagesizefromstring($pathOrData); - $self->data = base64_encode($pathOrData); + $image = file_exists($pathOrData) + ? getimagesize($pathOrData) + : getimagesizefromstring($pathOrData); + $self->data = file_exists($pathOrData) + ? base64_encode(file_get_contents($pathOrData)) + : base64_encode($pathOrData); $self->picture_type_id = $image[2]; - $self->mime = $image['mime']; $self->description = 'cover'; + $self->mime = $image['mime']; return $self; } - - public function data(): ?string - { - return $this->data; - } - - public function pictureTypeId(): ?int - { - return $this->picture_type_id; - } - - public function description(): ?string - { - return $this->description; - } - - public function mime(): ?string - { - return $this->mime; - } - - public function toArray(): array - { - return [ - 'data' => $this->data, - 'picture_type_id' => $this->picture_type_id, - 'description' => $this->description, - 'mime' => $this->mime, - ]; - } } diff --git a/src/Id3/Id3Writer.php b/src/Id3/Id3Writer.php index b0527db..ff171fe 100644 --- a/src/Id3/Id3Writer.php +++ b/src/Id3/Id3Writer.php @@ -27,7 +27,7 @@ protected function __construct( protected array $warnings = [], protected array $errors = [], protected bool $remove_old_tags = false, - protected bool $fail_on_error = false, + protected bool $skip_errors = true, protected array $tag_formats = [], protected bool $success = false, ) {} @@ -55,50 +55,62 @@ public function removeOtherTags(): self return $this; } - public function title(string $title): self + public function title(?string $title): self { $this->core->title = $title; return $this; } - public function artist(string $artist): self + public function artist(?string $artist): self { $this->core->artist = $artist; return $this; } - public function album(string $album): self + public function album(?string $album): self { $this->core->album = $album; return $this; } - public function albumArtist(string $album_artist): self + public function albumArtist(?string $album_artist): self { $this->core->album_artist = $album_artist; return $this; } - public function year(string|int $year): self + public function year(string|int|null $year): self { + if (! $year) { + $this->core->year = null; + + return $this; + } + $this->core->year = intval($year); return $this; } - public function genre(string $genre): self + public function genre(?string $genre): self { $this->core->genre = $genre; return $this; } - public function trackNumber(string|int $track_number): self + public function trackNumber(string|int|null $track_number): self { + if (! $track_number) { + $this->core->track_number = null; + + return $this; + } + if (is_int($track_number)) { $track_number = (string) $track_number; } @@ -108,8 +120,14 @@ public function trackNumber(string|int $track_number): self return $this; } - public function discNumber(string|int $disc_number): self + public function discNumber(string|int|null $disc_number): self { + if (! $disc_number) { + $this->core->disc_number = null; + + return $this; + } + if (is_int($disc_number)) { $disc_number = (string) $disc_number; } @@ -119,21 +137,21 @@ public function discNumber(string|int $disc_number): self return $this; } - public function composer(string $composer): self + public function composer(?string $composer): self { $this->core->composer = $composer; return $this; } - public function comment(string $comment): self + public function comment(?string $comment): self { $this->core->comment = $comment; return $this; } - public function lyrics(string $lyrics): self + public function lyrics(?string $lyrics): self { $this->core->lyrics = $lyrics; @@ -154,49 +172,64 @@ public function isNotCompilation(): self return $this; } - public function creationDate(string $creation_date): self + /** + * Not supported by `id3`. + */ + public function creationDate(?string $creation_date): self { $this->core->creation_date = $creation_date; return $this; } - public function copyright(string $copyright): self + public function copyright(?string $copyright): self { $this->core->copyright = $copyright; return $this; } - public function encodingBy(string $encoding_by): self + /** + * Not supported by `id3`. + */ + public function encodingBy(?string $encoding_by): self { $this->core->encoding_by = $encoding_by; return $this; } - public function encoding(string $encoding): self + /** + * Not supported by `id3`. + */ + public function encoding(?string $encoding): self { $this->core->encoding = $encoding; return $this; } - public function description(string $description): self + /** + * Not supported by `id3`. + */ + public function description(?string $description): self { $this->core->description = $description; return $this; } - public function synopsis(string $synopsis): self + /** + * Not supported by `id3`. + */ + public function synopsis(?string $synopsis): self { $this->core->synopsis = $synopsis; return $this; } - public function language(string $language): self + public function language(?string $language): self { $this->core->language = $language; @@ -209,10 +242,10 @@ public function language(string $language): self * Example: * * ```php - * $writer->tag('TXXX:CustomTag', 'CustomValue'); + * $audio->update()->tag('series-part', '1'); * ``` */ - public function tag(string $key, string $value): self + public function tag(string $key, string|int|bool|null $value): self { $this->custom_tags[$key] = $value; @@ -237,11 +270,11 @@ public function tags(array $tags): self } /** - * Fail on errors, by default it's `false`. + * Handle errors when writing tags. */ - public function failOnErrors(): self + public function handleErrors(): self { - $this->fail_on_error = true; + $this->skip_errors = false; return $this; } @@ -261,18 +294,21 @@ public function save(): bool $this->errors = $this->writer->errors; $this->warnings = $this->writer->warnings; - $this->handleErrors(); + $this->parseErrors(); return $this->success; } - private function handleErrors(): void + private function parseErrors(): void { $this->errors = $this->writer->errors; $this->warnings = $this->writer->warnings; $errors = implode(', ', $this->errors); $warnings = implode(', ', $this->warnings); + $errors = strip_tags($errors); + $warnings = strip_tags($warnings); + $supported = match ($this->audio->getFormat()) { AudioFormatEnum::flac => true, AudioFormatEnum::mp3 => true, @@ -280,37 +316,35 @@ private function handleErrors(): void default => false }; - if (! empty($this->errors)) { - $msg = 'Save tags failed.'; - - $errors = strip_tags($errors); - $errors = "Errors: {$errors}."; - if (! empty($this->errors)) { - $msg .= " {$errors}"; - } - - $warnings = "Warnings: {$warnings}."; - if (! empty($this->warnings)) { - $msg .= " {$warnings}"; - } + if (! $supported && ! $this->skip_errors) { + throw new \Exception("php-audio: format {$this->audio->getFormat()->value} is not supported."); + } - $isSuccess = $this->success ? 'true' : 'false'; - $success = "Success: {$isSuccess}"; - $msg .= " {$success}"; + if (! empty($this->errors)) { + error_log("php-audio: {$errors}"); + } - error_log($msg); + if (! empty($this->warnings)) { + error_log("php-audio: {$warnings}"); + } - if ($this->fail_on_error) { - throw new \Exception($msg); - } + if (empty($this->errors) && empty($this->warnings)) { + return; } - if (! $supported && $this->fail_on_error) { - throw new \Exception("Format {$this->audio->getFormat()->value} is not supported."); + $msg = 'php-audio: Save tags failed.'; + if ($errors) { + $msg .= " Errors: {$errors}."; + } + if ($warnings) { + $msg .= " Warnings: {$warnings}."; } + $isSuccess = $this->success ? 'true' : 'false'; + $msg .= " Success: {$isSuccess}."; + error_log($msg); - if (! empty($this->warnings)) { - error_log($warnings); + if (! $this->skip_errors) { + throw new \Exception($msg); } } @@ -392,6 +426,26 @@ private function parseTagFormats(): self return $this; } + private function attachCover(array &$tags): void + { + $coverFormatsAllowed = [AudioFormatEnum::mp3]; + // if ($this->core->getCover() && in_array($this->audio->getFormat(), $coverFormatsAllowed)) { + // // $tags = [ + // // ...$tags, + // // 'CTOC' => $old_tags['id3v2']['CTOC'], + // // 'CHAP' => $old_tags['id3v2']['CHAP'], + // // 'chapters' => $old_tags['id3v2']['chapters'], + // // ]; + // $tags['attached_picture'][0] = [ + // 'data' => base64_decode($this->core->getCover()->data()), + // 'picturetypeid' => $this->core->getCover()->picturetypeid(), + // 'description' => $this->core->getCover()->description(), + // 'mime' => $this->core->getCover()->mime(), + // ]; + // $this->core->setHasCover(true); + // } + } + /** * @param array $tags * @return array @@ -402,7 +456,7 @@ private function convertTags(array $tags): array $items = []; if (! empty($tags)) { foreach ($tags as $key => $tag) { - if ($tag && gettype($tag) === 'string') { + if (gettype($tag) === 'string') { $items[$key] = [$tag]; } } diff --git a/src/Id3/Tag/Id3TagAudioV2.php b/src/Id3/Tag/Id3TagAudioV2.php index b17debe..8ac7d18 100644 --- a/src/Id3/Tag/Id3TagAudioV2.php +++ b/src/Id3/Tag/Id3TagAudioV2.php @@ -17,7 +17,6 @@ public function __construct( readonly public ?string $track_number = null, readonly public ?string $year = null, readonly public ?string $copyright = null, - readonly public ?string $text = null, readonly public ?string $unsynchronised_lyric = null, readonly public ?string $language = null, ) {} @@ -28,6 +27,8 @@ public static function make(?array $metadata): ?self return null; } + $copyright = $metadata['copyright_message'] ?? $metadata['copyright'] ?? null; + $self = new self( album: self::parseTag($metadata, 'album'), artist: self::parseTag($metadata, 'artist'), @@ -40,8 +41,7 @@ public static function make(?array $metadata): ?self title: self::parseTag($metadata, 'title'), track_number: self::parseTag($metadata, 'track_number'), year: self::parseTag($metadata, 'year'), - copyright: self::parseTag($metadata, 'copyright_message'), - text: self::parseTag($metadata, 'text'), + copyright: $copyright, unsynchronised_lyric: self::parseTag($metadata, 'unsynchronised_lyric'), language: self::parseTag($metadata, 'language'), ); diff --git a/tests/AudioCoreTest.php b/tests/AudioCoreTest.php index 79d4ec9..9fab03a 100644 --- a/tests/AudioCoreTest.php +++ b/tests/AudioCoreTest.php @@ -5,7 +5,7 @@ use Kiwilan\Audio\Core\AudioCoreCover; it('can convert formats', function () { - $audio = Audio::get(MP3); + $audio = Audio::read(MP3); $core = new AudioCore( title: $audio->getTitle(), artist: $audio->getArtist(), @@ -51,5 +51,9 @@ $cover = AudioCoreCover::make(FOLDER); expect($core->toArray())->toBeArray(); - expect($cover->toArray())->toBeArray(); + + expect($cover->data)->toBeString(); + expect($cover->picture_type_id)->toBeInt(); + expect($cover->description)->toBeString(); + expect($cover->mime)->toBeString(); }); diff --git a/tests/AudioCoverTest.php b/tests/AudioCoverTest.php index cd68e29..39fe984 100644 --- a/tests/AudioCoverTest.php +++ b/tests/AudioCoverTest.php @@ -8,7 +8,7 @@ }); it('can extract cover', function (string $path) { - $audio = Audio::get($path); + $audio = Audio::read($path); $ext = pathinfo($path, PATHINFO_EXTENSION); $cover = $audio->getCover(); diff --git a/tests/AudioMetadataTest.php b/tests/AudioMetadataTest.php index 62c4661..83ca080 100644 --- a/tests/AudioMetadataTest.php +++ b/tests/AudioMetadataTest.php @@ -4,7 +4,7 @@ use Kiwilan\Audio\Models\AudioMetadata; it('can read mp3 info', function () { - $audio = Audio::get(MP3); + $audio = Audio::read(MP3); $metadata = $audio->getMetadata(); expect($metadata->getFileSize())->toBe(272737); @@ -32,7 +32,7 @@ }); it('can read basic info', function (string $path) { - $audio = Audio::get($path); + $audio = Audio::read($path); $metadata = $audio->getMetadata(); expect($metadata)->toBeInstanceOf(AudioMetadata::class); diff --git a/tests/AudioMp3Test.php b/tests/AudioMp3Test.php index 50b11cf..dd7fd70 100644 --- a/tests/AudioMp3Test.php +++ b/tests/AudioMp3Test.php @@ -8,7 +8,7 @@ use Kiwilan\Audio\Models\AudioMetadata; it('can read mp3 info', function () { - $audio = Audio::get(MP3); + $audio = Audio::read(MP3); expect($audio)->toBeInstanceOf(Audio::class); expect($audio->getPath())->toBe(MP3); @@ -79,7 +79,7 @@ }); it('can extract cover mp3', function () { - $audio = Audio::get(MP3); + $audio = Audio::read(MP3); $cover = $audio->getCover(); expect($cover)->toBeInstanceOf(AudioCover::class); @@ -95,7 +95,7 @@ }); it('can read file mp3 no meta', function () { - $audio = Audio::get(MP3_NO_META); + $audio = Audio::read(MP3_NO_META); expect($audio)->toBeInstanceOf(Audio::class); expect($audio->getTitle())->toBeNull(); @@ -113,5 +113,5 @@ }); it("can fail if file didn't exists", function () { - expect(fn () => Audio::get('tests/media/unknown.mp3'))->toThrow(Exception::class); + expect(fn () => Audio::read('tests/media/unknown.mp3'))->toThrow(Exception::class); }); diff --git a/tests/AudioTest.php b/tests/AudioTest.php index d743271..5b38efe 100644 --- a/tests/AudioTest.php +++ b/tests/AudioTest.php @@ -5,8 +5,13 @@ use Kiwilan\Audio\Id3\Id3Reader; use Kiwilan\Audio\Models\AudioMetadata; +it('can use get method', function () { + $audio = Audio::get(MP3); + expect($audio)->toBeInstanceOf(Audio::class); +}); + it('can read basic info', function (string $path) { - $audio = Audio::get($path); + $audio = Audio::read($path); $extension = pathinfo($path, PATHINFO_EXTENSION); $format = AudioFormatEnum::tryFrom($extension); @@ -35,32 +40,32 @@ })->with([...AUDIO]); it('can read disc number', function () { - $audio = Audio::get(M4A); + $audio = Audio::read(M4A); expect($audio->getDiscNumber())->toBe('1/2'); expect($audio->getDiscNumberInt())->toBe(1); }); it('can read encoding', function () { - $audio = Audio::get(M4V); + $audio = Audio::read(M4V); expect($audio->getEncoding())->toBe('Lavf60.3.100'); }); it('can read description', function () { - $audio = Audio::get(FLAC); + $audio = Audio::read(FLAC); expect($audio->getDescription())->toBe('http://www.p1pdd.com'); }); it('can read creation date', function () { - $audio = Audio::get(WV); + $audio = Audio::read(WV); expect($audio->getCreationDate())->toBe('2016'); }); it('can read file id3v1', function (string $path) { - $audio = Audio::get($path); + $audio = Audio::read($path); $extension = pathinfo($path, PATHINFO_EXTENSION); $format = AudioFormatEnum::tryFrom($extension); @@ -81,7 +86,7 @@ })->with([...AUDIO_ID3_V1]); it('can read wrong audio file', function () { - $audio = Audio::get(MD); + $audio = Audio::read(MD); expect($audio->isValid())->toBeFalse(); }); diff --git a/tests/AudiobookTest.php b/tests/AudiobookTest.php index 51ca8ce..be374ef 100644 --- a/tests/AudiobookTest.php +++ b/tests/AudiobookTest.php @@ -6,14 +6,42 @@ use Kiwilan\Audio\Models\AudioMetadata; it('can read audiobook', function () { - $audiobook = Audio::get(AUDIOBOOK_RH); + $audiobook = Audio::read(AUDIOBOOK_RH); expect($audiobook->getPath())->toContain('tests/media/audiobook_rh.m4b'); expect($audiobook->getExtension())->toBe('m4b'); expect($audiobook->getFormat())->toBe(AudioFormatEnum::m4b); expect($audiobook->getType())->toBe(AudioTypeEnum::quicktime); - expect($audiobook->getMetadata())->toBeInstanceOf(AudioMetadata::class); + expect($audiobook->isWritable())->toBeTrue(); + expect($audiobook->isValid())->toBeTrue(); + expect($audiobook->hasCover())->toBeTrue(); + + expect($audiobook->getTitle())->toBe('Assassin’s Apprentice'); + expect($audiobook->getArtist())->toBe('Robin Hobb'); + expect($audiobook->getAlbum())->toBe('Assassin’s Apprentice'); + expect($audiobook->getGenre())->toBe('Animals/Political/Epic/Military'); + expect($audiobook->getYear())->toBe(2024); + expect($audiobook->getTrackNumber())->toBe('1/1'); + expect($audiobook->getTrackNumberInt())->toBe(1); + expect($audiobook->getComment())->toBe('English'); + expect($audiobook->getAlbumArtist())->toBe('Robin Hobb'); + expect($audiobook->getComposer())->toBe('Paul Boehmer'); + expect($audiobook->getDiscNumber())->toBe('1'); + expect($audiobook->getDiscNumberInt())->toBe(1); + expect($audiobook->isCompilation())->toBeTrue(); + expect($audiobook->getCreationDate())->toBe('2024-09-30T12:00:00Z'); + expect($audiobook->getCopyright())->toBe('HarperCollins'); + expect($audiobook->getEncodingBy())->toBe('©2012 Robin Hobb (P)2012 HarperCollins Publishers Limited'); + expect($audiobook->getEncoding())->toBe('Audiobook Builder 2.2.9 (www.splasm.com), macOS 15.0'); + expect($audiobook->getDescription())->toBeString(); + expect($audiobook->getSynopsis())->toBeString(); + expect($audiobook->getLanguage())->toBe('English'); + expect($audiobook->getLyrics())->toBe('The Farseer #01'); +}); + +it('can read audiobook raw', function () { + $audiobook = Audio::read(AUDIOBOOK_RH); $raw = $audiobook->getRaw(); expect($raw['title'])->toBe('Assassin’s Apprentice'); @@ -67,36 +95,10 @@ expect($audiobook->getRawKey('album_artist'))->toBe('Robin Hobb'); expect($audiobook->getRawKey('series-part'))->toBe('1'); expect($audiobook->getRawKey('series'))->toBe('The Farseer'); - - expect($audiobook->isWritable())->toBeTrue(); - expect($audiobook->isValid())->toBeTrue(); - expect($audiobook->hasCover())->toBeTrue(); - - expect($audiobook->getTitle())->toBe('Assassin’s Apprentice'); - expect($audiobook->getArtist())->toBe('Robin Hobb'); - expect($audiobook->getAlbum())->toBe('Assassin’s Apprentice'); - expect($audiobook->getGenre())->toBe('Animals/Political/Epic/Military'); - expect($audiobook->getYear())->toBe(2024); - expect($audiobook->getTrackNumber())->toBe('1/1'); - expect($audiobook->getTrackNumberInt())->toBe(1); - expect($audiobook->getComment())->toBe('English'); - expect($audiobook->getAlbumArtist())->toBe('Robin Hobb'); - expect($audiobook->getComposer())->toBe('Paul Boehmer'); - expect($audiobook->getDiscNumber())->toBe('1'); - expect($audiobook->getDiscNumberInt())->toBe(1); - expect($audiobook->isCompilation())->toBeTrue(); - expect($audiobook->getCreationDate())->toBe('2024-09-30T12:00:00Z'); - expect($audiobook->getCopyright())->toBe('HarperCollins'); - expect($audiobook->getEncodingBy())->toBe('©2012 Robin Hobb (P)2012 HarperCollins Publishers Limited'); - expect($audiobook->getEncoding())->toBe('Audiobook Builder 2.2.9 (www.splasm.com), macOS 15.0'); - expect($audiobook->getDescription())->toBeString(); - expect($audiobook->getSynopsis())->toBeString(); - expect($audiobook->getLanguage())->toBe('English'); - expect($audiobook->getLyrics())->toBe('The Farseer #01'); }); it('can read audiobook file m4b', function (string $file) { - $audio = Audio::get($file); + $audio = Audio::read($file); expect($audio->getTitle())->toBe('P1PDD Saison 1'); expect($audio->getArtist())->toBe('Mr Piouf'); @@ -133,7 +135,7 @@ })->with([AUDIOBOOK]); it('can read audiobook file mp3', function (string $file) { - $audio = Audio::get($file); + $audio = Audio::read($file); expect(count($audio->getRaw()))->toBe(15); expect(count($audio->getRaw('id3v2')))->toBe(15); diff --git a/tests/ReaderTest.php b/tests/ReaderTest.php index c13aa8a..edd926d 100644 --- a/tests/ReaderTest.php +++ b/tests/ReaderTest.php @@ -7,7 +7,7 @@ use Kiwilan\Audio\Id3\Reader\Id3Comments; it('can read mp3 stream', function () { - $audio = Audio::get(MP3); + $audio = Audio::read(MP3); $streams = $audio->getId3Reader()->getAudio()->streams; expect($streams)->toBeArray(); @@ -26,7 +26,7 @@ }); it('can parse ID3 reader', function (string $path) { - $audio = Audio::get($path); + $audio = Audio::read($path); $reader = $audio->getId3Reader(); $raw = $reader->getRaw(); diff --git a/tests/WriterTest.php b/tests/WriterTest.php index a5b3899..8e2b865 100644 --- a/tests/WriterTest.php +++ b/tests/WriterTest.php @@ -5,7 +5,7 @@ use Kiwilan\Audio\Models\AudioCore; beforeEach(function () { - $audio = Audio::get(MP3_WRITER); + $audio = Audio::read(MP3_WRITER); $audio->update() ->title('Introduction') @@ -22,67 +22,92 @@ ->save(); }); -// it('can update tags', function () { -// $audio = Audio::get(MP3_WRITER); -// testMp3Writer($audio); +it('can update tags', function () { + $audio = Audio::read(MP3_WRITER); + testMp3Writer($audio); -// $audio->update() -// ->title('New Title') -// ->artist('New Artist') -// ->album('New Album') -// ->genre('New Genre') -// ->year(2022) -// ->trackNumber('2/10') -// ->albumArtist('New Album Artist') -// ->comment('New Comment') -// ->composer('New Composer') -// ->discNumber('2/2') -// ->isNotCompilation() -// ->lyrics('New Lyrics') -// ->creationDate('2021-01-01') -// ->copyright('New Copyright') -// ->encodingBy('New Encoding By') -// ->encoding('New Encoding') -// ->description('New Description') -// ->synopsis('New Synopsis') -// ->language('en') -// ->failOnErrors() -// ->save(); + $audio->update() + ->title('New Title') + ->artist('New Artist') + ->album('New Album') + ->genre('New Genre') + ->year(2022) + ->trackNumber('2/10') + ->albumArtist('New Album Artist') + ->comment('New Comment') + ->composer('New Composer') + ->discNumber('2/2') + ->isNotCompilation() + ->lyrics('New Lyrics') + ->creationDate('2021-01-01') + ->copyright('New Copyright') + ->encodingBy('New Encoding By') + ->encoding('New Encoding') + ->description('New Description') + ->synopsis('New Synopsis') + ->language('en') + ->copyright('New Copyright') + ->save(); -// $audio = Audio::get(MP3_WRITER); -// testMp3Writed($audio); -// }); + $audio = Audio::read(MP3_WRITER); + testMp3Writed($audio); + expect($audio->getLanguage())->toBe('en'); + expect($audio->getCopyright())->toBe('New Copyright'); +}); -// it('can update tags manually', function () { -// $audio = Audio::get(MP3_WRITER); -// testMp3Writer($audio); +it('can update only one tag', function () { + $audio = Audio::read(MP3_WRITER); + testMp3Writer($audio); -// $audio->update() -// ->tags([ -// 'title' => 'New Title', -// 'artist' => 'New Artist', -// 'album' => 'New Album', -// 'genre' => 'New Genre', -// 'year' => '2022', -// 'track_number' => '2/10', -// 'band' => 'New Album Artist', -// 'comment' => 'New Comment', -// 'composer' => 'New Composer', -// 'part_of_a_set' => '2/2', -// 'part_of_a_compilation' => false, -// 'unsynchronised_lyric' => 'New Lyrics', -// 'language' => 'en', -// 'copyright' => 'New Copyright', -// 'text' => 'New Text', -// ]) -// ->save(); + $audio->update() + ->title('New Title') + ->save(); -// $audio = Audio::get(MP3_WRITER); -// testMp3Writed($audio); -// }); + $audio = Audio::read(MP3_WRITER); + expect($audio->getTitle())->toBe('New Title'); + expect($audio->getArtist())->toBe('Mr Piouf'); + expect($audio->getAlbum())->toBe('P1PDD Le conclave de Troie'); + expect($audio->getGenre())->toBe('Roleplaying game'); + expect($audio->getYear())->toBe(2016); + expect($audio->getTrackNumber())->toBe('1'); + expect($audio->getComment())->toBe('http://www.p1pdd.com'); + expect($audio->getAlbumArtist())->toBe('P1PDD & Mr Piouf'); + expect($audio->getComposer())->toBe('P1PDD & Piouf'); + expect($audio->getDiscNumber())->toBe('1'); + expect($audio->isCompilation())->toBeTrue(); +}); + +it('can update tags manually', function () { + $audio = Audio::read(MP3_WRITER); + testMp3Writer($audio); + + $audio->update() + ->tags([ + 'title' => 'New Title', + 'artist' => 'New Artist', + 'album' => 'New Album', + 'genre' => 'New Genre', + 'year' => '2022', + 'track_number' => '2/10', + 'band' => 'New Album Artist', + 'comment' => 'New Comment', + 'composer' => 'New Composer', + 'part_of_a_set' => '2/2', + 'part_of_a_compilation' => false, + 'unsynchronised_lyric' => 'New Lyrics', + 'language' => 'en', + 'copyright' => 'New Copyright', + ]) + ->save(); + + $audio = Audio::read(MP3_WRITER); + testMp3Writed($audio); + expect($audio->getLanguage())->toBe('en'); + expect($audio->getCopyright())->toBe('New Copyright'); +}); // it('can update file', function (string $path) { -// $audio = Audio::get($path); +// $audio = Audio::read($path); // $random = (string) rand(1, 1000); // $tag = $audio->update() // ->title($random) @@ -107,7 +132,7 @@ // $core = $tag->getCore(); // $tag->save(); -// $audio = Audio::get($path); +// $audio = Audio::read($path); // expect($audio->getTitle())->toBe($random); // expect($audio->getArtist())->toBe('New Artist'); @@ -144,21 +169,21 @@ // })->with(AUDIO_WRITER); // it('can read use file content as cover', function (string $path) { -// $audio = Audio::get($path); +// $audio = Audio::read($path); // $tag = $audio->update() // ->cover(file_get_contents(FOLDER)); // $tag->save(); -// $audio = Audio::get($path); +// $audio = Audio::read($path); // $content = file_get_contents(FOLDER); // expect($tag->getCore()->getCover()->data())->toBe(base64_encode($content)); // })->with([MP3_WRITER]); // it('can read use tags', function (string $path) { -// $audio = Audio::get($path); +// $audio = Audio::read($path); // $random = (string) rand(1, 1000); // $image = getimagesize(FOLDER); @@ -181,7 +206,7 @@ // $tag->save(); -// $audio = Audio::get($path); +// $audio = Audio::read($path); // expect($audio->getTitle())->toBe($random); // $content = file_get_contents(FOLDER); @@ -189,7 +214,7 @@ // })->with([MP3_WRITER]); // it('can update use tags with tag formats', function (string $path) { -// $audio = Audio::get($path); +// $audio = Audio::read($path); // $random = (string) rand(1, 1000); // $tag = $audio->update() @@ -200,12 +225,12 @@ // $tag->save(); -// $audio = Audio::get($path); +// $audio = Audio::read($path); // expect($audio->getTitle())->toBe($random); // })->with([MP3_WRITER]); // it('can update with tags and handle native metadata', function (string $path) { -// $audio = Audio::get($path); +// $audio = Audio::read($path); // $tag = $audio->update() // ->isCompilation() @@ -217,14 +242,14 @@ // $tag->save(); -// $audio = Audio::get($path); +// $audio = Audio::read($path); // expect($audio->getTitle())->toBe('New Title'); // expect($audio->getAlbumArtist())->toBe('New Band'); // expect($audio->isCompilation())->toBeTrue(); // })->with([MP3_WRITER]); // it('can update with new path', function (string $path) { -// $audio = Audio::get($path); +// $audio = Audio::read($path); // $newPath = 'tests/output/new.mp3'; // $tag = $audio->update() @@ -233,12 +258,12 @@ // $tag->save(); -// $audio = Audio::get($newPath); +// $audio = Audio::read($newPath); // expect($audio->getTitle())->toBe('New Title'); // })->with([MP3_WRITER]); // it('can update with merged tags and core methods', function (string $path) { -// $audio = Audio::get($path); +// $audio = Audio::read($path); // $tag = $audio->update() // ->title('New Title') @@ -249,13 +274,13 @@ // $tag->save(); -// $audio = Audio::get($path); +// $audio = Audio::read($path); // expect($audio->getTitle())->toBe('New Title'); // expect($audio->getAlbumArtist())->toBe('New Band'); // })->with([MP3_WRITER]); // it('can use arrow function safe with unsupported tags', function (string $path) { -// $audio = Audio::get($path); +// $audio = Audio::read($path); // $tag = $audio->update() // ->title('New Title') @@ -263,12 +288,12 @@ // expect(fn () => $tag->save())->not()->toThrow(Exception::class); -// $audio = Audio::get($path); +// $audio = Audio::read($path); // expect($audio->getTitle())->toBe('New Title'); // })->with([MP3_WRITER]); // it('can use arrow function safe with unsupported formats', function (string $path) { -// $audio = Audio::get($path); +// $audio = Audio::read($path); // $tag = $audio->update() // ->title('New Title Alac'); @@ -277,7 +302,7 @@ // })->with([ALAC_WRITER]); // it('can get core before save', function (string $path) { -// $audio = Audio::get($path); +// $audio = Audio::read($path); // $tag = $audio->update() // ->title('New Title') @@ -290,7 +315,7 @@ // })->with([MP3_WRITER]); // it('can handle exceptions', function (string $path) { -// $audio = Audio::get($path); +// $audio = Audio::read($path); // $tag = $audio->update() // ->tags([ @@ -303,7 +328,7 @@ // })->with([MP3_WRITER]); // it('can skip exceptions', function (string $path) { -// $audio = Audio::get($path); +// $audio = Audio::read($path); // $tag = $audio->update() // ->tags([ @@ -314,13 +339,13 @@ // $tag->save(); -// $audio = Audio::get($path); +// $audio = Audio::read($path); // expect($audio->getTitle())->toBe('New Title'); // expect($audio->getAlbumArtist())->toBeNull(); // })->with([MP3_WRITER]); // it('can remove old tags', function (string $path) { -// $audio = Audio::get($path); +// $audio = Audio::read($path); // $tag = $audio->update() // ->title('New Title') @@ -329,13 +354,13 @@ // $tag->save(); -// $audio = Audio::get('tests/output/new.mp3'); +// $audio = Audio::read('tests/output/new.mp3'); // expect($audio->getTitle())->toBe('New Title'); // expect($audio->getAlbumArtist())->toBeNull(); // })->with([MP3]); // it('can use tags with cover', function (string $path) { -// $audio = Audio::get($path); +// $audio = Audio::read($path); // $tag = $audio->update() // ->tags([ @@ -345,7 +370,7 @@ // $tag->save(); -// $audio = Audio::get($path); +// $audio = Audio::read($path); // $content = file_get_contents(FOLDER); // expect($audio->getTitle())->toBe('New Title'); @@ -353,7 +378,7 @@ // })->with([MP3_WRITER]); // it('can change podcast description and language', function () { -// $audio = Audio::get(AUDIOBOOK); +// $audio = Audio::read(AUDIOBOOK); // $tag = $audio->update() // ->title('New Title') // ->podcastDescription('New Podcast Description') @@ -362,7 +387,7 @@ // }); // it('can not override tags', function (string $path) { -// $audio = Audio::get($path); +// $audio = Audio::read($path); // $tag = $audio->update() // ->getTitle('New Title') @@ -371,6 +396,6 @@ // $tag->save(); -// $audio = Audio::get('tests/output/new.mp3'); +// $audio = Audio::read('tests/output/new.mp3'); // expect($audio->getTitle())->toBe('Introduction'); // })->with([MP3]);