{"id":19527890,"url":"https://github.com/dmouayad/taggy","last_synced_at":"2026-03-12T07:01:33.323Z","repository":{"id":193342186,"uuid":"684063738","full_name":"DMouayad/taggy","owner":"DMouayad","description":"Dart \u0026 Flutter packages to read, write and convert audio tags","archived":false,"fork":false,"pushed_at":"2023-09-18T09:35:05.000Z","size":502,"stargazers_count":8,"open_issues_count":2,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-16T14:32:46.709Z","etag":null,"topics":["audio-metadata","audio-tags","dart-package","flutter","flutter-package","flutter-rust-bridge"],"latest_commit_sha":null,"homepage":"","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DMouayad.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-08-28T11:33:22.000Z","updated_at":"2024-11-11T00:24:38.000Z","dependencies_parsed_at":"2025-01-08T15:54:46.831Z","dependency_job_id":"b6b5f483-ef74-4d4a-ae91-907fc6205ad4","html_url":"https://github.com/DMouayad/taggy","commit_stats":null,"previous_names":["dmouayad/taggy"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/DMouayad/taggy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DMouayad%2Ftaggy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DMouayad%2Ftaggy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DMouayad%2Ftaggy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DMouayad%2Ftaggy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DMouayad","download_url":"https://codeload.github.com/DMouayad/taggy/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DMouayad%2Ftaggy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30417685,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-12T06:40:58.731Z","status":"ssl_error","status_checked_at":"2026-03-12T06:40:40.296Z","response_time":114,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["audio-metadata","audio-tags","dart-package","flutter","flutter-package","flutter-rust-bridge"],"created_at":"2024-11-11T01:16:47.216Z","updated_at":"2026-03-12T07:01:33.307Z","avatar_url":"https://github.com/DMouayad.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n\u003ca href=\"https://github.com/DMouayad/taggy/releases\"\u003e\u003cimg src=\"https://img.shields.io/github/v/release/DMouayad/taggy?style=flat-square\u0026color=blue\" alt=\"Release\"\u003e\u003c/a\u003e\n\u003ca href=\"https://pub.dartlang.org/packages/taggy\"\u003e\u003cimg alt=\"taggy\" src=\"https://img.shields.io/pub/v/taggy\"\u003e\u003c/a\u003e\n\u003ca href=\"https://pub.dartlang.org/packages/flutter_taggy\"\u003e\u003cimg alt=\"flutter_taggy\" src=\"https://img.shields.io/pub/v/flutter_taggy\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/DMouayad/taggy/actions\"\u003e\u003cimg src=\"https://img.shields.io/github/actions/workflow/status/DMouayad/taggy/.github%2Fworkflows%2Fbuild.yaml\" alt=\"Build Status\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/DMouayad/taggy\"\u003e\u003cimg src=\"https://img.shields.io/github/stars/DMouayad/taggy.svg?style=flat\u0026logo=github\u0026colorB=deeppink\u0026label=stars\" alt=\"Github Stars\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opensource.org/licenses/MIT\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-MIT-purple.svg\" alt=\"MIT License\"\u003e\u003c/a\u003e\n\u003c/div\u003e\n\n![taggy cover image](readme-assets/Taggy%20cover.png)\n\nProvides a simple yet powerful API for reading, writing and converting audio tags (metadata).\n\n**Table of contents:**\n\n\u003c!-- TOC --\u003e\n  * [Features](#features)\n    * [Planned features ⏳](#planned-features-)\n  * [Getting started](#getting-started)\n  * [Installation](#installation)\n  * [Usage](#usage)\n    * [Initialization](#initialization)\n    * [About `TaggyFile`](#about-taggyfile)\n    * [Reading tags](#reading-tags)\n    * [Writing tags](#writing-tags)\n    * [Removing tags](#removing-tags)\n  * [Feed back \u0026 Contributions](#feed-back--contributions)\n  * [Acknowledgement](#acknowledgement)\n\u003c!-- TOC --\u003e\n\n## Features\n\n- 📖 [Reading audio tags metadata from file](#reading-tags).\n- 📝 [Writing audio tags](#writing-tags).\n- ✂  [Removing audio tags](#removing-tags).\n- 🎶 Supports a variety of [file formats](https://github.com/Serial-ATA/lofty-rs/blob/main/SUPPORTED_FORMATS.md):\n  MP3, MP4, FLAC, and more.\n\n### Planned features ⏳\n\n- **Batches**: write to multiple files at the same time.\n- **Editing file name**: add the option to rename a file based on its track title.\n- **TaggyFileResult**: all public APIs should return a universal result;\n  a value of `TaggyFile` type or an error of `TaggyError` type.\n- **Converting tags**\n\n## Getting started\n\n- Install the package.\n- Read the [Usage](#usage) section to explore Taggy's features.\n- For more details: check out the [Dart example](packages/taggy/example/README.md)\n  and [Flutter example](packages/flutter_taggy/example/README.md) apps.\n\n## Installation\n\nRun the following command:\n\n- For a Dart project:\n\n    ```bash\n    dart pub add taggy\n    ```\n\n- For a Flutter project:\n\n  ```bash\n  flutter pub add flutter_taggy\n  ```\n\n## Usage\n\n### Initialization\n\n- **With Dart**\n\n  ```dart\n  import 'package:taggy/taggy.dart';\n  \n  void main(){\n    Taggy.initializeFrom(DynamicLibrary.open('path/to/library.dll'));\n  }\n  ```\n  \n  Or\n  \n  ```dart\n  import 'package:taggy/taggy.dart';\n\n  // call this helper function which takes care of loading the library for you.\n  Taggy.initializeFrom(getTaggyDylibFromDirectory('path/of/binaries/directory'));\n    ```\n\n- **With Flutter**\n\n  ```dart\n  import 'package:flutter_taggy/flutter_taggy.dart';\n  \n  void main(){\n    // When using the Flutter package, we don't have to pass the dynamic library \n    // ourselves but it'll be automatically fetched then loaded for us.\n    // So You only need to add the following line.\n    Taggy.initialize();\n    \n    // build something cool\n  }\n  ```\n\n### About `TaggyFile`\n\n- It gives us a little more information about the file(s) we're reading from or writing to, so alongside the list of `Tag`, \n  we get:\n  - the file size (in bytes).\n  - a `FileType`: whether it's (flac, wav, mpeg, etc).\n  - an `AudioInfo`, which is another type, holds the properties of the audio track.\n- you can pretty-print a `TaggyFile` instance by calling `formatAsAString()`:\n\n  \u003cdetails\u003e\n  \u003csummary\u003eoutput example\u003c/summary\u003e\n\n  ```\n  TaggyFile: {\n      size: 12494053 bytes ~ 12.2 MB,\n      fileType: FileType.Mpeg\n      primaryTagType: TagType.Id3v2,\n      tags: {\n      count: 1,\n      items: \n        [ Tag(\n              tagType: Id3v2,\n              trackTitle: Fine Line,\n              trackArtist: Eminem,\n              trackNumber: 9,\n              trackTotal: 1,\n              discTotal: null,\n              discNumber: null,\n              album: SHADYXV,\n              albumArtist: Various Artists,\n              genre: null,\n              language: null,\n              year: null,\n              recordingDate: null,\n              originalReleaseDate: null,\n              has lyrics: true,\n              pictures: {\n                count: 1,\n                items: [ Picture(\n                  picType: PictureType.CoverFront,\n                  picData(Bytes): 168312,\n                  mimeType: MimeType.Jpeg,\n                  width: 1000,\n                  height: 1000,\n                  colorDepth: 24,\n                  numColors: 0,\n                  )],\n              },\n            ),\n        ],\n      },\n      audio: AudioInfo(\n      channelMask: 3,\n      channels: 2,\n      sampleRate: 44100,\n      audioBitrate: 321,\n      overallBitrate: 326,\n      bitDepth: null,\n      durationSec: 306,\n      ),\n  }\n  ```\n\n\u003c/details\u003e\n\n### Reading tags\n\n- **Reading all tags:**\n\n    ```dart\n    const path = 'path/to/audio/file.mp3';\n\n    final TaggyFile taggyFile = await Taggy.readAll(path);\n    // you can use the getter which, under the hood, is [taggyFile.tags.firstOrNull]\n    print(taggyFile.firstTagIfAny);\n  \n    // or easily access all returned tags\n    for (var tag in taggyFile.tags) {\n      print(tag.tagType);\n    }\n    ```\n\n- **Reading primary tag:**\n\n    ```dart\n    final path = 'path/to/audio/file.mp3';\n    final TaggyFile taggyFile = await Taggy.readPrimary(path);\n    ```\n\n\n- **Reading any tag:**\n\n  It's similar to `readPrimary` except that the returned `TaggyFile.tags` might be empty.\n\n    ```dart\n    const path = 'path/to/audio/file.mp3';\n    final TaggyFile taggyFile = await Taggy.readyAny(path);\n  \n    // you can also use [formatAsString], we still get a [TaggyFile].\n    print(taggyFile.formatAsString());\n  \n    // you may want to check if it has any tags\n    final hasTags = taggyFile.tags.isNotEmpty();\n    // Or use the getter\n    final Tag? tag = taggyFile.firstTagIfAny;\n    ```\n\n### Writing tags\n\n- **About specifying the `TagType`**\n\n  A tag type is required for creating a new `Tag` instance.\n  You can:\n\n  -  check what `TagType` the file supports based on its type(extension). see this [table](https://github.com/Serial-ATA/lofty-rs/blob/main/SUPPORTED_FORMATS.md).\n\n  -  Use the function `Taggy.writePrimary()`\n     and pass it a `Tag` with a type of `TagType.FilePrimaryType`, as shown in example below.\n\n\n- \u003cdetails\u003e \n\n    \u003csummary\u003eExample of creating a new Tag\u003c/summary\u003e\n\n    ```dart\n    Tag getTagInstance(TagType tagType){\n      return Tag(\n        tagType: tagType,\n        album: 'Some Album',\n        trackTitle: 'some Track',\n        trackArtist: 'Some Artist',\n        trackTotal: 10,\n        trackNumber: 1,\n        discNumber: 1,\n        discTotal: 2,\n        year: 2023,\n        recordingDate: '1/3/2019',\n        language: 'EN',\n        pictures: [\n          Picture(\n            // zeros are used to demonstrate how to provide a picture's data.\n            picData: Uint8List.fromList([0, 0, 0, 0]),\n            mimeType: MimeType.Jpeg,\n            picType: PictureType.CoverFront,\n            width: 1000,\n            height: 800,\n          ),\n        ],\n      );\n    }\n    ```\n\n\u003c/details\u003e\n\n- **Writing primary tag:**\n\n  ```dart\n  final path = 'path/to/audio/file.mp3';\n\n  final tagToWrite = getTagInstance(TagType.FilePrimaryType);\n\n  final TaggyFile taggyFile = await Taggy.writePrimary(\n    path: path, tag: tagToWrite, keepOthers: false);\n\n  // On Success, [taggyFile.tags] will contain the newly added tag.\n  // NOTE: this tag may not contain the same properties of [tagToWrite].\n  final pTag = taggyFile.primaryTag;\n  ```\n\n- **Writing multiple tags**:\n\n  In most use-cases, you'll use `Taggy.writePrimary()` to add/edit an audio tag metadata,\n  but you can also provide multiple tags to be written to the same file.\n\n  ```dart\n  final path = 'path/to/audio/file.mp3';\n\n  final tags = [\n    getTagInstance(TagType.FilePrimaryType),\n    getTagInstance(TagType.Id3v1),\n  ];\n      \n  final TaggyFile taggyFile = await Taggy.writeAll(\n    path: path, tag: tagToWrite, overrideExistent: true);\n  ```\n\n### Removing tags\n\n* #### Remove a specific Tag\n\n  You can delete a tag from file by specifying its tag type.\n\n    ```dart\n    final path = 'path/to/audio/file.mp3';\n  \n    // The type of to-remove-tag\n    final tagType = TagType.Ape;\n    \n    final TaggyFile taggyFile = await Taggy.removeTag(path: path, tagType: tagType);\n    ``` \n\n* #### Remove all tags\n\n  ```dart\n  final path = 'path/to/audio/file.mp3';\n  final TaggyFile taggyFile = await Taggy.removeAll(path: path);\n  \n  print(taggyFile.tags);\n  // output is []\n  ``` \n\n## Feed back \u0026 Contributions\n\n- 🐛 Found an issue or encountered a bug? please check the existing [issues](https://github.com/DMouayad/taggy/issues) or create a new one.\n\n\n- 💪🏻 Want to contribute? Thank you, its always welcomed!. You can start by reading\n  the [Contributing](CONTRIBUTING.md) guide.\n\n\n- 🙏🏻 You can also contribute if you ⭐ this repository and 👍🏻 the [Dart](https://pub.dev/packages/taggy) and\n  [Flutter](https://pub.dev/packages/flutter_taggy) packages on `Pub.dev`, we do appreciate your love.\n\n## Acknowledgement\n\n- [**lofty**](https://github.com/Serial-ATA/lofty-rs/): a Rust library which provides `Taggy` with its functionality.\n\n- [**Flutter Rust Bridge**](https://github.com/fzyzcjy/flutter_rust_bridge): connects `Rust` APIs with Dart \u0026 Flutter.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdmouayad%2Ftaggy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdmouayad%2Ftaggy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdmouayad%2Ftaggy/lists"}