Skip to content

Commit

Permalink
fixes for 4.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
ewilan-riviere committed Oct 3, 2024
1 parent e081da4 commit d43d294
Show file tree
Hide file tree
Showing 14 changed files with 191 additions and 108 deletions.
137 changes: 63 additions & 74 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Audio files can use different formats, this package aims to provide a simple way

## Requirements

- PHP >= 8.1
- PHP `8.1` minimum
- Optional for update
- `FLAC`: `flac` (with `apt`, `brew` or `scoop`)
- `OGG`: `vorbis-tools` (with `apt` or `brew`) / `extras/icecast` (with `scoop`)
Expand Down Expand Up @@ -58,15 +58,15 @@ $audio->getAlbumArtist(); // `?string` to get album artist
$audio->getComposer(); // `?string` to get composer
$audio->getDiscNumber(); // `?string` to get disc number
$audio->isCompilation(); // `bool` to know if is compilation
$audio->getCreationDate(); // `?string` to get creation date (audiobook)
$audio->getCopyright(); // `?string` to get copyright (audiobook)
$audio->getCreationDate(); // `?string` to get creation date
$audio->getCopyright(); // `?string` to get copyright
$audio->getEncoding(); // `?string` to get encoding
$audio->getDescription(); // `?string` to get description (audiobook)
$audio->getPodcastDescription(); // `?string` to get podcast description (audiobook)
$audio->getDescription(); // `?string` to get description
$audio->getSynopsis(); // `?string` to get synopsis
$audio->getLanguage(); // `?string` to get language
$audio->getLyrics(); // `?string` (audiobook)
$audio->getStik(); // `?string` (audiobook)
$audio->getLyrics(); // `?string`
$audio->getDuration(); // `?float` to get duration in seconds
$audio->getDurationHuman(); // `?string` to get duration in human readable format
```

Raw tags:
Expand All @@ -76,13 +76,12 @@ use Kiwilan\Audio\Audio;

$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()`
$raw_all = $audio->getRawAll(); // `array` with all tags
$raw = $audio->getRaw(); // `array` with main tag
$title = $audio->getRawKey('title'); // `?string` to get title same as `$audio->getTitle()`

$formats = $audio->getAudioFormats(); // `array` with all audio formats

$format = $audio->getTags('id3v2'); // `?array` with all tags with format `id3v2`
$title = $audio->getTag('title', 'id3v2'); // `?string` to get title with format `id3v2`
$format = $audio->getRaw('id3v2'); // `?array` with all tags with format `id3v2`
$title = $audio->getRawKey('title', 'id3v2'); // `?string` to get title with format `id3v2`
```

Additional metadata:
Expand All @@ -93,18 +92,15 @@ use Kiwilan\Audio\Audio;
$audio = Audio::read('path/to/audio.mp3');

$audio->getPath(); // `string` to get path
$audio->getExtension(); // `string` to get extension
$audio->hasCover(); // `bool` to know if has cover
$audio->isValid(); // `bool` to know if file is valid audio file
$audio->isWritable(); // `bool` to know if file is writable
$audio->getFormat(); // `AudioFormatEnum` to get format (mp3, m4a, ...)
$audio->getType(); // `?AudioTypeEnum` ID3 type (id3, riff, asf, quicktime, matroska, ape, vorbiscomment)
$audio->getExtras(); // `array` with raw metadata (could contains some metadata not parsed)
```

Raw audio:

> [!NOTE]
>
> Cover is removed from `toArray()` method, you can use `getCover()` method to get cover metadata.
You can use `toArray()` method to get raw info:

```php
use Kiwilan\Audio\Audio;
Expand All @@ -121,10 +117,8 @@ use Kiwilan\Audio\Audio;

$audio = Audio::read('path/to/audio.mp3');

$audio->getReader(); // `?Id3Reader` reader based on `getID3`
$audio->getWriter(); // `?Id3Writer` writer based on `getid3_writetags`
$audio->getStat(); // `AudioStat` (from `stat` function)
$audio->getAudio(); // `?AudioMetadata` with audio metadata
$audio->getId3Reader(); // `?Id3Reader` reader based on `getID3`
$audio->getMetadata(); // `?AudioMetadata` with audio metadata
$audio->getCover(); // `?AudioCover` with cover metadata
```

Expand All @@ -142,7 +136,7 @@ use Kiwilan\Audio\Audio;
$audio = Audio::read('path/to/audio.mp3');
$audio->getTitle(); // `Title`

$tag = $audio->update()
$tag = $audio->write()
->title('New Title')
->artist('New Artist')
->album('New Album')
Expand All @@ -154,12 +148,12 @@ $tag = $audio->update()
->composer('New Composer')
->creationDate('2021-01-01')
->description('New Description')
->synopsis('New Synopsis')
->discNumber('2/2')
->encodingBy('New Encoding By')
->encoding('New Encoding')
->isCompilation()
->lyrics('New Lyrics')
->stik('New Stik')
->cover('path/to/cover.jpg') // you can use file content `file_get_contents('path/to/cover.jpg')`
->save();

Expand All @@ -178,6 +172,7 @@ You can set tags manually with `tags` method, but you need to know the format of
>
> If you use `tags` method, you have to use key used by metadata container. For example, if you want to set album artist in `id3v2`, you have to use `band` key. If you want to know which key to use check `src/Models/AudioCore.php` file.
>
> You can't use other methods with `tags()` method.
> If your key is not supported, `save` method will throw an exception, unless you use `preventFailOnErrors`.
```php
Expand All @@ -186,7 +181,7 @@ use Kiwilan\Audio\Audio;
$audio = Audio::read('path/to/audio.mp3');
$audio->getAlbumArtist(); // `Band`

$tag = $audio->update()
$tag = $audio->write()
->tags([
'title' => 'New Title',
'band' => 'New Band', // `band` is used by `id3v2` to set album artist, method is `albumArtist` but `albumArtist` key will throw an exception with `id3v2`
Expand All @@ -206,7 +201,7 @@ use Kiwilan\Audio\Audio;
$audio = Audio::read('path/to/audio.mp3');
$audio->getAlbumArtist(); // `Band`

$tag = $audio->update()
$tag = $audio->write()
->title('New Title')
->albumArtist('New Band') // `albumArtist` will set `band` for `id3v2`, exception safe
->save();
Expand All @@ -224,7 +219,7 @@ use Kiwilan\Audio\Audio;

$audio = Audio::read('path/to/audio.mp3');

$tag = $audio->update()
$tag = $audio->write()
->tags([
'title' => 'New Title',
'title2' => 'New title', // not supported by `id3v2`, will throw an exception
Expand All @@ -240,7 +235,7 @@ use Kiwilan\Audio\Audio;

$audio = Audio::read('path/to/audio.mp3');

$tag = $audio->update()
$tag = $audio->write()
->encoding('New encoding') // not supported by `id3v2`, BUT will not throw an exception
->preventFailOnError() // if you have some errors with unsupported format for example, you can prevent exception
->save();
Expand All @@ -262,7 +257,7 @@ $coverPicturetypeid = $image[2];
$coverDescription = 'cover';
$coverMime = $image['mime'];

$tag = $audio->update()
$tag = $audio->write()
->tags([
'title' => 'New Title',
'band' => 'New Band',
Expand All @@ -278,29 +273,6 @@ $tag = $audio->update()
->save();
```

#### Merge tags

Merge `tags` with arrow functions.

```php
use Kiwilan\Audio\Audio;

$audio = Audio::read($path);

$tag = $audio->update()
->title('New Title') // will be merged with `tags` and override `title` key
->tags([
'title' => 'New Title tag',
'band' => 'New Band',
]);

$tag->save();

$audio = Audio::read($path);
expect($audio->getTitle())->toBe('New Title');
expect($audio->getAlbumArtist())->toBe('New Band');
```

### Extras

Audio files format metadata with different methods, `JamesHeinrich/getID3` offer to check these metadatas by different methods. In `extras` property of `Audio::class`, you will find raw metadata from `JamesHeinrich/getID3` package, like `id3v2`, `id3v1`, `riff`, `asf`, `quicktime`, `matroska`, `ape`, `vorbiscomment`...
Expand All @@ -322,20 +294,36 @@ $id3v2 = $extras['id3v2'] ?? [];
use Kiwilan\Audio\Audio;

$audio = Audio::read('path/to/audio.mp3');

$audio->getAudio()->getFilesize(); // `?int` in bytes
$audio->getAudio()->getExtension(); // `?string` (mp3, m4a, ...)
$audio->getAudio()->getEncoding(); // `?string` (UTF-8...)
$audio->getAudio()->getMimeType(); // `?string` (audio/mpeg, audio/mp4, ...)
$audio->getAudio()->getDurationSeconds(); // `?float` in seconds
$audio->getAudio()->getDurationReadable(); // `?string` (00:00:00)
$audio->getAudio()->getBitrate(); // `?int` in kbps
$audio->getAudio()->getBitrateMode(); // `?string` (cbr, vbr, ...)
$audio->getAudio()->getSampleRate(); // `?int` in Hz
$audio->getAudio()->getChannels(); // `?int` (1, 2, ...)
$audio->getAudio()->getChannelMode(); // `?string` (mono, stereo, ...)
$audio->getAudio()->getLossless(); // `bool` to know if is lossless
$audio->getAudio()->getCompressionRatio(); // `?float`
$metadata = $audio->getMetadata();

$metadata->getFileSize(); // `?int` in bytes
$metadata->getSizeHuman(); // `?string` (1.2 MB, 1.2 GB, ...)
$metadata->getExtension(); // `?string` (mp3, m4a, ...)
$metadata->getEncoding(); // `?string` (UTF-8...)
$metadata->getMimeType(); // `?string` (audio/mpeg, audio/mp4, ...)
$metadata->getDurationSeconds(); // `?float` in seconds
$metadata->getDurationReadable(); // `?string` (00:00:00)
$metadata->getBitrate(); // `?int` in kbps
$metadata->getBitrateMode(); // `?string` (cbr, vbr, ...)
$metadata->getSampleRate(); // `?int` in Hz
$metadata->getChannels(); // `?int` (1, 2, ...)
$metadata->getChannelMode(); // `?string` (mono, stereo, ...)
$metadata->isLossless(); // `bool` to know if is lossless
$metadata->getCompressionRatio(); // `?float`
$metadata->getFilesize(); // `?int` in bytes
$metadata->getSizeHuman(); // `?string` (1.2 MB, 1.2 GB, ...)
$metadata->getDataFormat(); // `?string` (mp3, m4a, ...)
$metadata->getCodec(); // `?string` (mp3, aac, ...)
$metadata->getEncoderOptions(); // `?string`
$metadata->getVersion(); // `?string`
$metadata->getAvDataOffset(); // `?int` in bytes
$metadata->getAvDataEnd(); // `?int` in bytes
$metadata->getFilePath(); // `?string`
$metadata->getFilename(); // `?string`
$metadata->getLastAccessAt(); // `?DateTime`
$metadata->getCreatedAt(); // `?DateTime`
$metadata->getModifiedAt(); // `?DateTime`
$metadata->toArray();
```

### AudioCover
Expand All @@ -344,11 +332,12 @@ $audio->getAudio()->getCompressionRatio(); // `?float`
use Kiwilan\Audio\Audio;

$audio = Audio::read('path/to/audio.mp3');
$cover = $audio->getCover();

$audio->getCover()->getContents(); // `?string` raw file
$audio->getCover()->getMimeType(); // `?string` (image/jpeg, image/png, ...)
$audio->getCover()->getWidth(); // `?int` in pixels
$audio->getCover()->getHeight(); // `?int` in pixels
$cover->getContents(); // `?string` raw file
$cover->getMimeType(); // `?string` (image/jpeg, image/png, ...)
$cover->getWidth(); // `?int` in pixels
$cover->getHeight(); // `?int` in pixels
```

## Supported formats
Expand Down Expand Up @@ -475,10 +464,10 @@ In `Audio::class`, you have a property `extras` which contains all raw metadata,
use Kiwilan\Audio\Audio;

$audio = Audio::read('path/to/audio.mp3');
$extras = $audio->getExtras();
$raw_all = $audio->getRawAll());

$custom = null;
$id3v2 = $extras['id3v2'] ?? [];
$id3v2 = $raw_all['id3v2'] ?? [];

if ($id3v2) {
$custom = $id3v2['custom'] ?? null;
Expand All @@ -496,7 +485,7 @@ use Kiwilan\Audio\Audio;

$audio = Audio::read('path/to/audio.mp3');

$extras = $audio->getExtras();
$extras = $audio->getRawAll();
var_dump($extras);
```

Expand Down
53 changes: 44 additions & 9 deletions src/Audio.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,21 @@ public function getId3Reader(): ?Id3Reader
return Id3Reader::make($this->path);
}

public function update(): Id3Writer
public function write(): Id3Writer
{
return Id3Writer::make($this);
}

/**
* @deprecated Use `write()` method instead.
*
* Update audio file.
*/
public function update(): Id3Writer

Check warning on line 158 in src/Audio.php

View check run for this annotation

Codecov / codecov/patch

src/Audio.php#L158

Added line #L158 was not covered by tests
{
return $this->write();

Check warning on line 160 in src/Audio.php

View check run for this annotation

Codecov / codecov/patch

src/Audio.php#L160

Added line #L160 was not covered by tests
}

/**
* Get duration of the audio file in seconds, limited to 2 decimals, like `180.66`
*
Expand Down Expand Up @@ -444,14 +454,39 @@ public function getRawKey(string $key, ?string $format = null): string|int|bool|
return $tags[$key] ?? null;
}

/**
* Get raw tags as array with main format, same as `getRaw()`.
*
* @return string[]
*/
public function getExtras(): array
{
return $this->getRaw();
public function toArray(): array
{
return [
'path' => $this->path,
'extension' => $this->extension,
'format' => $this->format,
'type' => $this->type,
'metadata' => $this->metadata?->toArray(),
'cover' => $this->cover?->toArray(),
'duration' => $this->duration,
'is_writable' => $this->is_writable,
'is_valid' => $this->is_valid,
'has_cover' => $this->has_cover,
'title' => $this->title,
'artist' => $this->artist,
'album' => $this->album,
'genre' => $this->genre,
'year' => $this->year,
'track_number' => $this->track_number,
'comment' => $this->comment,
'album_artist' => $this->album_artist,
'composer' => $this->composer,
'disc_number' => $this->disc_number,
'is_compilation' => $this->is_compilation,
'creation_date' => $this->creation_date,
'encoding_by' => $this->encoding_by,
'encoding' => $this->encoding,
'description' => $this->description,
'synopsis' => $this->synopsis,
'language' => $this->language,
'lyrics' => $this->lyrics,
'raw_tags_all' => $this->raw_tags_all,
];
}

private function parseTags(?\Kiwilan\Audio\Id3\Id3Reader $id3_reader): self
Expand Down
2 changes: 1 addition & 1 deletion src/Id3/Id3Writer.php
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ public function language(?string $language): self
* Example:
*
* ```php
* $audio->update()->tag('series-part', '1');
* $audio->write()->tag('series-part', '1');
* ```
*/
public function tag(string $key, string|int|bool|null $value): self

Check warning on line 257 in src/Id3/Id3Writer.php

View check run for this annotation

Codecov / codecov/patch

src/Id3/Id3Writer.php#L257

Added line #L257 was not covered by tests
Expand Down
10 changes: 10 additions & 0 deletions src/Models/AudioCover.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,14 @@ public function extractCover(string $path): void
{
file_put_contents($path, $this->getContents());
}

public function toArray(): array
{
return [
'contents' => $this->contents,
'mime_type' => $this->mime_type,
'width' => $this->width,
'height' => $this->height,
];
}
}
Loading

0 comments on commit d43d294

Please sign in to comment.