haudiotagger 1.2.3 copy "haudiotagger: ^1.2.3" to clipboard
haudiotagger: ^1.2.3 copied to clipboard

Read and write audio metadata in Flutter. Supports MP3, FLAC, OGG, MP4, WAV, AIFF, and more. Powered by Rust for fast, reliable performance.

[hAudiotagger]

hAudiotagger

Rust-powered audio metadata for Flutter

pub.dev CI MIT License


Read, write, and edit audio metadata across Android, iOS, Linux, macOS, Windows, and Web. Built on lofty via flutter_rust_bridge.

[hAudiotagger]

Features #

Feature Platforms
Read / write metadata (title, artist, album, art, lyrics...) All
Partial updates — change one field without touching others All
Batch operations with progress callbacks All
Custom tags (TXXX, Vorbis) All
ID3v2 version control (v2.3 / v2.4) All
Strip ID3v1 tags All
Audio properties (duration, bitrate, codec...) All
Tag format detection All

Install #

dependencies:
  haudiotagger: ^1.2.3

Quick Start #

import 'package:haudiotagger/haudiotagger.dart';

// Read
final tag = await Haudiotagger.read('/path/to/song.mp3');
print(tag?.title);

// Write
await Haudiotagger.write('/path/to/song.mp3', Tag(
  title: 'My Song',
  artist: 'Artist',
  album: 'Album',
));

// Update (preserves other fields)
await Haudiotagger.update('/path/to/song.mp3', TagChanges(
  album: 'New Album',
));

// Batch
final result = await Haudiotagger.batchWrite(paths, tag);

Supported Formats #

Format Tags
MP3 ID3v2, ID3v1, APE
FLAC Vorbis Comments, ID3v2*
MP4 / M4A iTunes ilst
Ogg Vorbis Vorbis Comments
Opus Vorbis Comments
AAC ID3v2, ID3v1
WAV ID3v2, RIFF INFO
AIFF ID3v2, Text Chunks
APE APE, ID3v2*, ID3v1
WavPack APE, ID3v1

* The tag will be read only, due to lack of official support


Usage #

Read Metadata #

// From file path (native)
final tag = await Haudiotagger.read('/path/to/song.mp3');

// From bytes (web + native)
final tag = await Haudiotagger.readFromBytes(fileBytes);

Write Metadata #

// To file path (native)
await Haudiotagger.write('/path/to/song.mp3', Tag(
  title: 'Song Title',
  trackArtist: 'Artist',
  album: 'Album',
  year: 2024,
));

// To bytes (web + native)
final modified = await Haudiotagger.writeToBytes(fileBytes, tag);

Update Metadata #

Only the fields you pass are changed — everything else stays intact.

await Haudiotagger.update('/path/to/song.mp3', TagChanges(
  title: 'New Title',
  genre: 'Jazz',
));

// Bytes variant
final modified = await Haudiotagger.updateFromBytes(fileBytes, changes);

Batch Operations #

// Write same tag to multiple files
final result = await Haudiotagger.batchWrite(paths, tag);

// Apply same changes to multiple files
await Haudiotagger.batchUpdateChanges(paths, TagChanges(album: 'New Album'));

// Per-file callback with progress
await Haudiotagger.batchUpdate(
  paths,
  onProgress: (p) => print('${(p.percent * 100).round()}%'),
  (path, current) => current.copyWith(trackNumber: paths.indexOf(path) + 1),
);

// Web/bytes variants available
await Haudiotagger.batchWriteFromBytes(byteArrays, tag);

Custom Tags #

Read, write, and remove format-specific custom tags (ID3v2 TXXX frames, Vorbis non-standard keys).

// Read
final custom = await Haudiotagger.getCustomTags('/path/to/song.mp3');
// {'MY_FIELD': 'some value'}

// Write
await Haudiotagger.setCustomTag('/path/to/song.mp3', 'MY_FIELD', 'some value');

// Remove
await Haudiotagger.removeCustomTag('/path/to/song.mp3', 'MY_FIELD');

// Bytes variants: getCustomTagsFromBytes, setCustomTagFromBytes, removeCustomTagFromBytes

ID3v2 Version Control #

// Detect version
final version = await Haudiotagger.getId3v2Version('/path/to/song.mp3');
// Id3v2Version.v3 or Id3v2Version.v4

// Convert to ID3v2.3 (widely compatible)
await Haudiotagger.convertId3v2('/path/to/song.mp3', Id3v2Version.v3);

// Convert to ID3v2.4 (latest spec)
await Haudiotagger.convertId3v2('/path/to/song.mp3', Id3v2Version.v4);

// Bytes variants: getId3v2VersionFromBytes, convertId3v2FromBytes

Remove ID3v1 #

await Haudiotagger.removeId3v1('/path/to/song.mp3');
final cleaned = await Haudiotagger.removeId3v1FromBytes(bytes);

Audio Properties #

final props = await Haudiotagger.readProperties('/path/to/song.mp3');
// props.duration, props.bitrate, props.sampleRate, props.codec, ...

// Bytes variant
await Haudiotagger.readPropertiesFromBytes(bytes);

Diff Tags #

Compare two tags to see exactly what changed — useful for confirmation dialogs and undo previews.

final oldTag = await Haudiotagger.read('/path/to/song.mp3');
final newTag = oldTag?.copyWith(title: 'New Title', year: 2025);

final diff = Haudiotagger.diff(oldTag!, newTag!);

print(diff.length);     // 2
print(diff.changes[0]); // title: Old Title → New Title

for (final change in diff.changes) {
  switch (change.type) {
    case ChangeType.added:
      print('Added ${change.field.name}');
    case ChangeType.updated:
      print('Updated ${change.field.name}');
    case ChangeType.removed:
      print('Removed ${change.field.name}');
  }
}

Detect Tag Formats #

final formats = await Haudiotagger.getTagFormats('/path/to/song.mp3');
// ['ID3v2', 'ID3v1']

Inspect File #

One call to get everything: format, tag format, properties, metadata, pictures, and file size.

final info = await Haudiotagger.inspect('/path/to/song.mp3');

print(info.format);      // 'MP3'
print(info.tagFormat);   // 'ID3v2'
print(info.size);        // 4812345
print(info.metadata?.title);
print(info.properties.duration);
print(info.pictures.length);

// Bytes variant
final info = await Haudiotagger.inspectFromBytes(bytes);

Web Setup #

The host page must be cross-origin isolated for WASM shared memory. Add these headers when serving:

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

For local development:

flutter run -d chrome \
  --web-header=Cross-Origin-Opener-Policy=same-origin \
  --web-header=Cross-Origin-Embedder-Policy=require-corp

API Reference #

All methods
Method Returns Platform
read(path) Tag? native
readFromBytes(bytes) Tag? all
write(path, tag) void native
writeToBytes(bytes, tag) Uint8List all
update(path, changes) void native
updateFromBytes(bytes, changes) Uint8List all
remove(path, fields) void native
removeFromBytes(bytes, fields) Uint8List all
clear(path) void native
clearFromBytes(bytes) Uint8List all
readProperties(path) AudioProperties native
readPropertiesFromBytes(bytes) AudioProperties all
getTagFormats(path) List<String> native
getTagFormatsFromBytes(bytes) List<String> all
inspect(path) AudioFileInfo native
inspectFromBytes(bytes) AudioFileInfo all
getCustomTags(path) Map<String, String> native
getCustomTagsFromBytes(bytes) Map<String, String> all
setCustomTag(path, key, value) void native
setCustomTagFromBytes(bytes, key, value) Uint8List all
removeCustomTag(path, key) void native
removeCustomTagFromBytes(bytes, key) Uint8List all
getId3v2Version(path) Id3v2Version? all
getId3v2VersionFromBytes(bytes) Id3v2Version? all
convertId3v2(path, version) void all
convertId3v2FromBytes(bytes, version) Uint8List all
removeId3v1(path) void all
removeId3v1FromBytes(bytes) Uint8List all
batchWrite(paths, tag) BatchResult native
batchUpdateChanges(paths, changes) BatchResult native
batchUpdate(paths, updater, {onProgress}) BatchResult native
batchWriteFromBytes(bytes, tag) BatchBytesResult all
batchUpdateChangesFromBytes(bytes, changes) BatchBytesResult all
batchUpdateFromBytes(bytes, updater, {onProgress}) BatchBytesResult all
Data types

Tag #

Field Type Notes
title String?
trackArtist String?
album String?
albumArtist String?
year int?
genre String?
trackNumber int?
trackTotal int?
discNumber int?
discTotal int?
lyrics String?
comment String?
bpm double?
duration int? Read-only
pictures List<Picture>

TagChanges #

Same fields as Tag, all optional. Only set fields are applied.

Picture #

Field Type
pictureType PictureType
mimeType MimeType?
bytes Uint8List

AudioFileInfo #

Field Type Notes
format String e.g. MP3, FLAC
tagFormat String e.g. ID3v2, VorbisComments
properties AudioProperties Technical details
metadata Tag? All metadata fields
pictures List<Picture> Embedded artwork
size BigInt File size in bytes

AudioProperties #

Field Type
duration Duration?
durationMicros int?
bitrate int?
sampleRate int?
channels int?
bitsPerSample int?
codec String
containerFormat String
lossless bool
bitrateMode BitrateMode
fileSize BigInt?

Id3v2Version #

v2 (not supported for writing), v3, v4

BatchResult #

Field Type
successes int
failures int
errors List<(String, String)>

BatchBytesResult #

Field Type
results List<Uint8List>
failures int
errors List<(int, String)>

BatchProgress #

Field Type
completed int
total int
percent double

MetadataDiff #

Field Type
changes List<MetadataChange>
length int
isEmpty bool

MetadataChange<T> #

Field Type
field TagField
oldValue T?
newValue T?
type ChangeType

ChangeType #

added, updated, removed


Requirements #

  • Flutter >= 3.0.0
  • Dart SDK >= 3.6.0

License #

hAudiotagger is open-source software licensed under the MIT License.

See the LICENSE file for more information.

❤️ Support #

If hAudiotagger helps you build something cool, consider:

  • ⭐ Starring the repository
  • 🐛 Reporting bugs
  • 💡 Suggesting improvements
  • 🤝 Contributing code
  • 📦 Sharing the package with other Flutter developers

Every bit of support helps keep the project moving forward.

Made with ❤️ and 🦀.

12
likes
0
points
950
downloads

Publisher

verified publisherhirdaya-shrestha.com.np

Weekly Downloads

Read and write audio metadata in Flutter. Supports MP3, FLAC, OGG, MP4, WAV, AIFF, and more. Powered by Rust for fast, reliable performance.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

ffi, flutter, flutter_rust_bridge, freezed_annotation, plugin_platform_interface

More

Packages that depend on haudiotagger

Packages that implement haudiotagger