haudiotagger 1.2.6
haudiotagger: ^1.2.6 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.
1.2.6 #
- Performance improved in
batch_update_changes - Code quality: added
PartialEqderives toTag,TagChanges,Picture,PictureType,MimeType - Simplified
is_empty()onTag,TagChanges::merge()withor_clone!macro andTagChanges— delegates toPartialEqagainst default - Added rayon parallelism to file-path
batch_writeandbatch_update_changes - Updated README benchmarks with both bytes and file-path API results
1.2.5 #
- Performance optimizations: rayon parallelism for batch operations, pre-allocated output buffers, consolidated MP3 byte manipulation
- Added performance benchmarks to README
- Code cleanup: removed duplicated MP3 byte manipulation logic into shared helper
1.2.4 #
- Added
validate/validateFromBytes/validateTag— detect metadata issues (missing fields, invalid track/disc numbers, bad BPM/year) - Added
NormalizeOptionsandnormalize/normalizeBytes/normalizeTag— trim whitespace, normalize Unicode (NFKC), collapse spaces, remove empty values - Added
copyMetadata/copyMetadataFromBytes— copy metadata between files with options to include/exclude artwork, lyrics, and custom tags - Added
mergeTagswithMergeStrategy— merge two tags with configurable priority (preferFirst, preferSecond, preferFirstNonEmpty, preferSecondNonEmpty) - Added ReplayGain support:
replayGainTrackGain,replayGainTrackPeak,replayGainAlbumGain,replayGainAlbumPeakfields onTag - Added ReplayGain fields to
TagChangesfor partial updates - Added
copyWithextensions forTag,TagChanges, andPicture - New types:
ValidationResult,ValidationIssue,ValidationSeverity,NormalizeOptions,MergeStrategy
1.2.3 #
- Added
inspect/inspectFromBytes— get format, tag format, properties, metadata, pictures, and file size in one call - Added
diff— compare two tags and get a structured list of changes (added/updated/removed) - New types:
AudioFileInfo,MetadataDiff,MetadataChange,ChangeType
1.2.2 #
- Added custom tag operations for reading, writing, and removing format-specific custom tags:
getCustomTags/getCustomTagsFromBytes: read custom tags (ID3v2 TXXX frames, Vorbis non-standard keys)setCustomTag/setCustomTagFromBytes: write custom tagsremoveCustomTag/removeCustomTagFromBytes: remove custom tags
- Added ID3v2 version control:
getId3v2Version/getId3v2VersionFromBytes: detect current ID3v2 version (v2.2, v2.3, v2.4)convertId3v2/convertId3v2FromBytes: convert ID3v2 tag to a specific version (v3 or v4)
- Added ID3v1 removal:
removeId3v1/removeId3v1FromBytes: strip ID3v1 tags from files/bytes
- All new features work on both native (file paths) and web (byte arrays)
1.2.1 #
- Added batch operations for processing multiple files at once:
batchWrite/batchWriteFromBytes: write the same tag to multiple filesbatchUpdateChanges/batchUpdateChangesFromBytes: apply the sameTagChangesto multiple filesbatchUpdate/batchUpdateFromBytes: per-file callback-based update with progress tracking
- Added
BatchResult,BatchBytesResult, andBatchProgresstypes for batch operation results - All batch operations work on both native (file paths) and web (byte arrays)
1.2.0 #
- Added
getTagFormats()andgetTagFormatsFromBytes()to detect which tag formats are present in an audio file (ID3v1, ID3v2, APE, iTunes, VorbisComments, RiffInfo, AiffText). - Updated README with correct supported formats table.
1.1.9 #
- Minor changes and binary version updates
1.1.8 #
- Fixed a native (and all platform) runtime crash where calls such as
readFromBytes/writeToBytesaborted insideTagField::sse_decodewithinternal error: entered unreachable code. The published package was shipping stale committed prebuilt native binaries (built from the oldTagField-based API signatures) against newly generated Dart bindings, so the native binary decoded arguments using the wrong types. ThepublishCI job now overwrites the committed prebuilt native artifacts with the freshly-built ones frombuild_and_uploadbefore publishing, guaranteeing the native binary matches the published Dart/FFI contract. Also rebuilt the committed Linux prebuilt and re-scopedpanic=abortto the WASM build only.
1.1.7 #
- Fixed a native (Android/iOS/Linux/macOS/Windows) runtime crash where the async FFI dispatcher aborted with
panic cannot unwind. The threaded web build previously relied on a committedrust/.cargo/config.tomlwithbuild-std = ["std","panic_abort"], which also rebuilt the nativestdwithpanic=abortand brokeflutter_rust_bridge'scatch_unwind-based async dispatcher. The build-std/panic_abort configuration is now scoped to the WASM build only (CIbuild_webjob + local build viaCARGO_UNSTABLE_BUILD_STD/build-std), so native builds use the default unwindingstdagain. Web behaviour (threaded shared-memory WASM + cross-origin isolation) is unchanged.
1.1.6 #
- Minor changes with updated logs and docs.
1.1.5 #
- Reverted the 1.1.4 synchronous workaround. Web now runs calls asynchronously through
flutter_rust_bridge2.13's Web Worker pool (non-blocking on the main thread), which requires shared (threaded) WASM memory plus cross-origin isolation. - Rebuilt the web WASM with
+atomics,+bulk-memory,+mutable-globals, a shared/imported memory (--shared-memory --import-memory), and the wasm-threads TLS/heap symbols explicitly exported (--export=__wasm_init_tls --export=__tls_size --export=__tls_align --export=__tls_base --export=__heap_base --export=__stack_pointer). This is built withRUSTUP_TOOLCHAIN=nightlyand-Z build-std=std,panic_abortso std provides the threads runtime. The exported symbols let wasm-bindgen's threading transform succeed (previously it failed withfailed to find __wasm_init_tls). - Web hosts must be cross-origin isolated: serve the page with
Cross-Origin-Opener-Policy: same-originandCross-Origin-Embedder-Policy: require-corp(e.g.flutter run -d chrome --web-header=Cross-Origin-Opener-Policy=same-origin --web-header=Cross-Origin-Embedder-Policy=require-corp). Without these headers,RustLib.init()fails with aWorkerPool/ shared-memory error. - Native platforms are unaffected in API and now run async on the thread pool again (no main-thread blocking, unlike 1.1.4).
1.1.4 #
- Fixed a web runtime crash (
fail to create WorkerPool: ... #<Memory> could not be cloned).flutter_rust_bridge2.13 dispatches async calls through a Web Worker pool that requires shared WASM memory plus cross-origin isolation (COOP/COEP headers), which the example host did not provide. Generated all API functions synchronously (default_dart_async: false) so web calls run on the main thread with no Worker pool, no shared memory, and no special server headers. The publicFuture<T>API is unchanged; native calls now execute synchronously on the calling isolate instead of via an async worker pool.
1.1.3 #
- Fixed the web platform: the WASM was previously built with
wasm-pack --target web, producing an ES module thatflutter_rust_bridge2.13's classic-script loader could not initialize (the example hung atRustLib.init()). Rebuilt withwasm-pack -t no-modules, pointed the plugin/example assets and frb'swebPrefixtopkg/, and removed the manual<script>tag so frb loads the glue automatically. No API changes.
1.1.2 #
- Added partial-tag editing that preserves existing metadata:
Haudiotagger.update(path, TagChanges(...))applies only the fields you specify, leaving the rest untouched (plusupdateFromBytesfor web/native).Haudiotagger.remove(path, [TagField.lyrics, TagField.comment, ...])clears specific fields while keeping the rest (plusremoveFromBytes).Haudiotagger.clear(path)removes all metadata (plusclearFromBytes).
- Added
commentfield toTag(read/write supported).
1.1.1 #
- Added read-only
AudioPropertiesmodel exposing technical audio properties (duration, bitrate, sample rate, channels, bits per sample, codec, container format, lossless flag, bitrate mode, file size). Available viaHaudiotagger.readProperties(path)(native) andHaudiotagger.readPropertiesFromBytes(bytes)(web + native). Does not affect existing read/write behavior.
1.1.0 #
- Pointed every platform's prebuilt download at the fixed release. The Android, Linux and Windows
CMakeLists.txtand the iOS/macOS podspecs all hardcodedv1.0.1, so every version still shipped the old buggy native binary. All now download fromv1.1.0. Also fixed the macOS podscript condition so it actually re-downloads (it previously skipped the download because the committed framework already existed). - MP3 write fix (byte-level ID3v2 path, robust
.mp3/ID3 detection) and MP3 lyrics fix included.
1.0.9 #
- Fixed Android never picking up native fixes:
android/CMakeLists.txtpinned the prebuilt.sodownload tov1.0.1, so every version still shipped the old buggy binary. Pointed it at thev1.0.8release (which contains the fixedandroid.tar.gz). NOTE: the CMakeVersionmust be bumped alongside future releases, or Android will keep using an outdated prebuilt.
1.0.8 #
- Hardened MP3 write detection.
writepreviously gated the byte-level ID3v2 path on lofty's content probe (file.file_type() == Mpeg), which mis-identifies some real MP3s and routed them through lofty's writer, producingFileEncodingError { format: None }. Detection now keys off the.mp3extension and a leadingID3marker (matchingwrite_to_bytes), so MP3s never reach lofty'ssave_to_path/remove_from. Added a regression test for an unsniffable-but-.mp3file.
1.0.7 #
- Fixed
writecrashing on MP3/ID3v2 files withFileEncodingError { format: None }. lofty'sTagType::remove_fromre-probes the file on write and fails for any file it cannot content-sniff (common on Android). MP3 writes now strip the existing tag at the byte level (ID3v2/ID3v1/APE markers) and prepend a freshly serialized ID3v2, so the new tag fully replaces the old one. Other formats replace the in-memory primary tag and letsave_to_pathrewrite the file (also stripping it when the new tag is empty). Addpictures: []toTagwhen clearing all fields.
1.0.6 #
- Fixed lyrics not persisting for MP3 (ID3v2) files.
ItemKey::Lyricsis unsupported by ID3v2 (lyrics live in theUSLTframe, addressed byItemKey::UnsyncLyrics).writenow uses the ID3v2-correct key andreadfalls back to both keys, so lyrics round-trip on MP3 as well as MP4.
1.0.5 #
- Fixed Android build failure (
Inconsistent JVM Target Compatibility): replaced the removed legacykotlinOptionswith a Kotlin JVM toolchain (jvmToolchain(17)), aligning the Kotlin and Java compile targets soflutter build apksucceeds.
1.0.4 #
- Added Swift Package Manager support for iOS and macOS: committed
ios/haudiotagger/Package.swift,macos/haudiotagger/Package.swift, and the prebuilthaudiotagger.xcframework, clearing the pub.dev SPM warning. - Removed the legacy
kotlinOptions { jvmTarget = '17' }block fromandroid/build.gradle, clearing the pub.dev legacy Kotlin configuration warning.
1.0.3 #
- Declared
webplatform support inpubspec.yaml(added theweb:entry underflutter.plugin.platformsandlib/haudiotagger_web.dartregistration shim). pub.dev now lists Web support for the package.
1.0.2 #
- Fixed
write()failing to replace/remove existing tags (lofty'sremove_from_pathopened a probe without guessing the file type and aborted withformat: None). Tags are now properly removed from disk before the new tag is written, and clearing a tag fully strips it. - Fixed reading/writing files by path regardless of file extension — format is now detected from file content instead of the path extension.
- Fixed
writeToBytes()now correctly removes existing tags before applying the new ones (byte-based I/O on all platforms including web). - Tests now run against isolated per-test scratch copies of the samples, eliminating the parallel-execution race on shared fixture files.
- Added the
samples/directory to.gitignore/.pubignore.
1.0.1 #
- Add web/WASM support — read and write metadata in the browser
- Add
readFromBytes()andwriteToBytes()for byte-based I/O (works on all platforms including web) - Fixed BPM and tag field unwrap panics in Rust
- Fixed Dart init race condition (concurrent
RustLib.init()calls) - Improved error messages (human-readable
HaudiotaggerErrordisplay) - Added
Clonederive toPictureTypeandMimeType - Example app rewritten as cross-platform metadata editor
1.0.0 #
- Initial release
- Read audio metadata (title, artist, album, year, genre, cover art, lyrics, BPM, and more)
- Write audio metadata back to files
- Support for MP3, FLAC, OGG, MP4/M4A, WAV, AIFF, APE, WavPack, Musepack, AAC
- Cross-platform: Android, iOS, Linux, macOS, Windows
- Powered by Rust (lofty) via flutter_rust_bridge