Provides a simple yet powerful API for reading, writing and converting audio tags (metadata).
Table of contents:
- π Reading audio tags metadata from file.
- π Writing audio tags.
- β Removing audio tags.
- πΆ Supports a variety of file formats: MP3, MP4, FLAC, and more.
- Batches: write to multiple files at the same time.
- Editing file name: add the option to rename a file based on its track title.
- TaggyFileResult: all public APIs should return a universal result;
a value of
TaggyFile
type or an error ofTaggyError
type. - Converting tags
- Install the package.
- Read the Usage section to explore Taggy's features.
- For more details: check out the Dart example and Flutter example apps.
Run the following command:
-
For a Dart project:
dart pub add taggy
-
For a Flutter project:
flutter pub add flutter_taggy
-
With Dart
import 'package:taggy/taggy.dart'; void main(){ Taggy.initializeFrom(DynamicLibrary.open('path/to/library.dll')); }
Or
import 'package:taggy/taggy.dart'; // call this helper function which takes care of loading the library for you. Taggy.initializeFrom(getTaggyDylibFromDirectory('path/of/binaries/directory'));
-
With Flutter
import 'package:flutter_taggy/flutter_taggy.dart'; void main(){ // When using the Flutter package, we don't have to pass the dynamic library // ourselves but it'll be automatically fetched then loaded for us. // So You only need to add the following line. Taggy.initialize(); // build something cool }
-
It gives us a little more information about the file(s) we're reading from or writing to, so alongside the list of
Tag
, we get:- the file size (in bytes).
- a
FileType
: whether it's (flac, wav, mpeg, etc). - an
AudioInfo
, which is another type, holds the properties of the audio track.
-
you can pretty-print a
TaggyFile
instance by callingformatAsAString()
:output example
TaggyFile: { size: 12494053 bytes ~ 12.2 MB, fileType: FileType.Mpeg primaryTagType: TagType.Id3v2, tags: { count: 1, items: [ Tag( tagType: Id3v2, trackTitle: Fine Line, trackArtist: Eminem, trackNumber: 9, trackTotal: 1, discTotal: null, discNumber: null, album: SHADYXV, albumArtist: Various Artists, genre: null, language: null, year: null, recordingDate: null, originalReleaseDate: null, has lyrics: true, pictures: { count: 1, items: [ Picture( picType: PictureType.CoverFront, picData(Bytes): 168312, mimeType: MimeType.Jpeg, width: 1000, height: 1000, colorDepth: 24, numColors: 0, )], }, ), ], }, audio: AudioInfo( channelMask: 3, channels: 2, sampleRate: 44100, audioBitrate: 321, overallBitrate: 326, bitDepth: null, durationSec: 306, ), }
-
Reading all tags:
const path = 'path/to/audio/file.mp3'; final TaggyFile taggyFile = await Taggy.readAll(path); // you can use the getter which, under the hood, is [taggyFile.tags.firstOrNull] print(taggyFile.firstTagIfAny); // or easily access all returned tags for (var tag in taggyFile.tags) { print(tag.tagType); }
-
Reading primary tag:
final path = 'path/to/audio/file.mp3'; final TaggyFile taggyFile = await Taggy.readPrimary(path);
-
Reading any tag:
It's similar to
readPrimary
except that the returnedTaggyFile.tags
might be empty.const path = 'path/to/audio/file.mp3'; final TaggyFile taggyFile = await Taggy.readyAny(path); // you can also use [formatAsString], we still get a [TaggyFile]. print(taggyFile.formatAsString()); // you may want to check if it has any tags final hasTags = taggyFile.tags.isNotEmpty(); // Or use the getter final Tag? tag = taggyFile.firstTagIfAny;
-
About specifying the
TagType
A tag type is required for creating a new
Tag
instance. You can:-
check what
TagType
the file supports based on its type(extension). see this table. -
Use the function
Taggy.writePrimary()
and pass it aTag
with a type ofTagType.FilePrimaryType
, as shown in example below.
-
-
Example of creating a new Tag
Tag getTagInstance(TagType tagType){ return Tag( tagType: tagType, album: 'Some Album', trackTitle: 'some Track', trackArtist: 'Some Artist', trackTotal: 10, trackNumber: 1, discNumber: 1, discTotal: 2, year: 2023, recordingDate: '1/3/2019', language: 'EN', pictures: [ Picture( // zeros are used to demonstrate how to provide a picture's data. picData: Uint8List.fromList([0, 0, 0, 0]), mimeType: MimeType.Jpeg, picType: PictureType.CoverFront, width: 1000, height: 800, ), ], ); }
-
Writing primary tag:
final path = 'path/to/audio/file.mp3'; final tagToWrite = getTagInstance(TagType.FilePrimaryType); final TaggyFile taggyFile = await Taggy.writePrimary( path: path, tag: tagToWrite, keepOthers: false); // On Success, [taggyFile.tags] will contain the newly added tag. // NOTE: this tag may not contain the same properties of [tagToWrite]. final pTag = taggyFile.primaryTag;
-
Writing multiple tags:
In most use-cases, you'll use
Taggy.writePrimary()
to add/edit an audio tag metadata, but you can also provide multiple tags to be written to the same file.final path = 'path/to/audio/file.mp3'; final tags = [ getTagInstance(TagType.FilePrimaryType), getTagInstance(TagType.Id3v1), ]; final TaggyFile taggyFile = await Taggy.writeAll( path: path, tag: tagToWrite, overrideExistent: true);
-
You can delete a tag from file by specifying its tag type.
final path = 'path/to/audio/file.mp3'; // The type of to-remove-tag final tagType = TagType.Ape; final TaggyFile taggyFile = await Taggy.removeTag(path: path, tagType: tagType);
-
final path = 'path/to/audio/file.mp3'; final TaggyFile taggyFile = await Taggy.removeAll(path: path); print(taggyFile.tags); // output is []
-
π Found an issue or encountered a bug? please check the existing issues or create a new one.
-
πͺπ» Want to contribute? Thank you, its always welcomed!. You can start by reading the Contributing guide.
-
ππ» You can also contribute if you β this repository and ππ» the Dart and Flutter packages on
Pub.dev
, we do appreciate your love.
-
lofty: a Rust library which provides
Taggy
with its functionality. -
Flutter Rust Bridge: connects
Rust
APIs with Dart & Flutter.