Flutter标签管理插件taggy的使用
Flutter标签管理插件taggy的使用
概述
提供了简单但功能强大的API来读取、写入和转换音频标签(元数据)。
目录:
特性
- 📖 阅读音频标签元数据。
- 📝 写入音频标签。
- ✂ 删除音频标签。
- 🎶 支持多种文件格式:
- MP3, MP4, FLAC等。
计划中的功能
- 批处理:同时写入多个文件。
- 编辑文件名:根据轨道标题添加重命名文件的选项。
- TaggyFileResult:所有公共API应该返回一个通用结果;
TaggyFile
类型的值或TaggyError
类型的错误。
- 转换标签。
开始使用
安装
运行以下命令:
dart pub add taggy
使用
初始化
可以通过两种方式完成初始化:
-
第一种方法:
import 'package:taggy/taggy.dart'; void main(){ Taggy.initializeFrom(DynamicLibrary.open('path/to/library.dll')); }
-
第二种方法:
import 'package:taggy/taggy.dart'; // 调用这个帮助函数,它会帮你加载库。 Taggy.initializeFrom(getTaggyDylibFromDirectory('path/of/binaries/directory'));
关于TaggyFile
-
它给我们提供了更多关于正在读取或写入文件的信息,除了标签列表之外,我们还可以得到:
- 文件大小(字节)。
- 文件类型:是否为FLAC、WAV、MPEG等。
AudioInfo
,这是一个包含音频轨道属性的类型。
-
可以通过调用
formatAsAString()
来格式化一个TaggyFile
实例: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, ), }
读取标签
-
读取所有标签:
const path = 'path/to/audio/file.mp3'; final TaggyFile taggyFile = await Taggy.readAll(path); // 使用getter,底层是[taggyFile.tags.firstOrNull] print(taggyFile.firstTagIfAny); // 或者轻松访问所有返回的标签 for (var tag in taggyFile.tags) { print(tag.tagType); }
-
读取主标签:
final path = 'path/to/audio/file.mp3'; final TaggyFile taggyFile = await Taggy.readPrimary(path);
-
读取任意标签:
与
readPrimary
类似,但返回的TaggyFile.tags
可能为空。const path = 'path/to/audio/file.mp3'; final TaggyFile taggyFile = await Taggy.readAny(path); // 你也可以使用 [formatAsString],我们仍然得到一个 [TaggyFile]。 print(taggyFile.formatAsString()); // 你可能想检查是否有任何标签 final hasTags = taggyFile.tags.isNotEmpty; // 或使用getter final Tag? tag = taggyFile.firstTagIfAny;
写入标签
-
关于指定
TagType
创建新的
Tag
实例时需要指定TagType
。你可以:- 检查基于文件类型(扩展名)支持的
TagType
。查看此表格。 - 使用函数
Taggy.writePrimary()
并传递一个Tag
,其类型为TagType.FilePrimaryType
,如下面的示例所示。
示例创建新标签:
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( // 用零表示如何提供图片的数据。 picData: Uint8List.fromList([0, 0, 0, 0]), mimeType: MimeType.Jpeg, picType: PictureType.CoverFront, width: 1000, height: 800, ), ], ); }
- 检查基于文件类型(扩展名)支持的
-
写入主标签:
final path = 'path/to/audio/file.mp3'; final tagToWrite = getTagInstance(TagType.FilePrimaryType); final TaggyFile taggyFile = await Taggy.writePrimary( path: path, tag: tagToWrite, keepOthers: false); // 成功后,[taggyFile.tags] 将包含新添加的标签。 // 注意:这个标签可能不包含 [tagToWrite] 的相同属性。 final pTag = taggyFile.primaryTag;
-
写入多个标签:
在大多数情况下,你会使用
Taggy.writePrimary()
添加/编辑音频标签元数据,但你也可以提供多个标签写入同一文件。final path = 'path/to/audio/file.mp3'; final tags = [ getTagInstance(TagType.FilePrimaryType), getTagInstance(TagType.Id3v1), ]; final TaggyFile taggyFile = await Taggy.writeAll( path: path, tags: tags, overrideExistent: true);
删除标签
-
删除特定标签:
你可以通过指定标签类型从文件中删除标签。
final path = 'path/to/audio/file.mp3'; // 要删除的标签类型 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); // 输出是 []
反馈与贡献
致谢
- lofty:一个提供
Taggy
功能的Rust库。 - Flutter Rust Bridge:将
Rust
API 与 Dart & Flutter 连接起来。
示例代码
import 'dart:io';
import 'package:taggy/taggy.dart';
import 'package:path/path.dart' as p;
Future<void> main(List<String> args) async {
// 初始化Taggy
// 注意:如果你本地运行,你需要运行 `cargo build` 命令以便生成二进制文件
Taggy.initializeFrom(getTaggyDylibFromDirectory('../../target/debug'));
await readAllTags();
await writeTag();
}
Future<void> writeTag() async {
final tag = Tag(
tagType: TagType.FilePrimaryType,
trackTitle: 'Track Title',
trackArtist: 'Track Artist',
trackTotal: 10,
trackNumber: 1,
discNumber: 1,
discTotal: 2,
year: 2023,
recordingDate: '1/3/2019',
language: 'EN',
pictures: [
Picture(
picData: File(_getImagePath()).readAsBytesSync(),
mimeType: MimeType.Jpeg,
picType: PictureType.CoverFront,
width: 1000,
height: 800,
),
],
);
final taggyFile = await Taggy.writePrimary(
path: _getAudioSamplePath(),
tag: tag,
keepOthers: false,
);
assert(taggyFile.primaryTag?.trackTitle == tag.trackTitle);
print('Tag was written successfully');
}
Future<void> readAllTags() async {
final taggyFile = await Taggy.readAll(_getAudioSamplePath());
// 使用 `taggyFile` 作为你所希望的
final audioInfo = taggyFile.audio;
final tags = taggyFile.tags;
final trackDuration = taggyFile.duration;
final fileType = taggyFile.fileType;
final size = taggyFile.sizeInMB;
print('audioInfo: $audioInfo');
print('tags: $tags');
print('fileType: $fileType');
print('trackDuration: $trackDuration');
print('size: $size');
}
/**
* 辅助函数
*/
/// 返回音频文件路径
String _getAudioSamplePath() => p.join(_getAssetsDirPath(), 'sample.mp3');
String _getImagePath() => p.join(_getAssetsDirPath(), 'image.jpg');
String _getAssetsDirPath() {
final dir = File(p.current).parent.absolute;
final sep = p.separator;
return p.join(dir.path, 'taggy${sep}example${sep}assets');
}
更多关于Flutter标签管理插件taggy的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter标签管理插件taggy的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
taggy
是一个用于 Flutter 的标签管理插件,它可以帮助你在应用中轻松管理和显示标签。通过 taggy
,你可以创建、编辑、删除标签,并将它们与不同的实体(如文章、图片等)关联起来。以下是 taggy
插件的基本使用指南。
1. 添加依赖
首先,你需要在 pubspec.yaml
文件中添加 taggy
插件的依赖:
dependencies:
flutter:
sdk: flutter
taggy: ^1.0.0 # 请使用最新版本
然后运行 flutter pub get
来安装依赖。
2. 初始化 Taggy
在你的应用中初始化 Taggy
。通常可以在 main.dart
中进行初始化:
import 'package:flutter/material.dart';
import 'package:taggy/taggy.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Taggy.initialize();
runApp(MyApp());
}
3. 创建标签
你可以使用 Taggy
创建新的标签。例如:
import 'package:taggy/taggy.dart';
Future<void> createTag() async {
Tag tag = Tag(name: 'Flutter', color: Colors.blue);
await Taggy.instance.createTag(tag);
}
4. 获取标签
你可以获取所有标签或根据条件获取特定标签:
Future<void> getTags() async {
List<Tag> tags = await Taggy.instance.getAllTags();
tags.forEach((tag) {
print(tag.name);
});
}
5. 更新标签
你可以更新已存在的标签:
Future<void> updateTag() async {
Tag tag = Tag(id: 1, name: 'Dart', color: Colors.red);
await Taggy.instance.updateTag(tag);
}
6. 删除标签
你可以删除标签:
Future<void> deleteTag() async {
await Taggy.instance.deleteTag(1); // 通过 ID 删除标签
}
7. 关联标签
你可以将标签与实体关联起来。例如,将标签与文章关联:
Future<void> associateTagWithPost() async {
int tagId = 1;
int postId = 1;
await Taggy.instance.associateTagWithEntity(tagId, postId, 'Post');
}
8. 获取关联的标签
你可以获取与特定实体关联的标签:
Future<void> getTagsForPost() async {
int postId = 1;
List<Tag> tags = await Taggy.instance.getTagsForEntity(postId, 'Post');
tags.forEach((tag) {
print(tag.name);
});
}
9. 显示标签
在 UI 中显示标签,你可以使用 Chip
或 Wrap
来展示标签列表:
import 'package:flutter/material.dart';
import 'package:taggy/taggy.dart';
class TagList extends StatelessWidget {
final List<Tag> tags;
TagList({required this.tags});
[@override](/user/override)
Widget build(BuildContext context) {
return Wrap(
children: tags.map((tag) {
return Chip(
label: Text(tag.name),
backgroundColor: tag.color,
);
}).toList(),
);
}
}
10. 完整示例
以下是一个简单的完整示例,展示如何使用 taggy
插件:
import 'package:flutter/material.dart';
import 'package:taggy/taggy.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Taggy.initialize();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Taggy Example')),
body: TagExample(),
),
);
}
}
class TagExample extends StatefulWidget {
[@override](/user/override)
_TagExampleState createState() => _TagExampleState();
}
class _TagExampleState extends State<TagExample> {
List<Tag> tags = [];
[@override](/user/override)
void initState() {
super.initState();
_loadTags();
}
Future<void> _loadTags() async {
List<Tag> loadedTags = await Taggy.instance.getAllTags();
setState(() {
tags = loadedTags;
});
}
[@override](/user/override)
Widget build(BuildContext context) {
return Column(
children: [
ElevatedButton(
onPressed: () async {
Tag newTag = Tag(name: 'New Tag', color: Colors.green);
await Taggy.instance.createTag(newTag);
_loadTags();
},
child: Text('Add Tag'),
),
TagList(tags: tags),
],
);
}
}
class TagList extends StatelessWidget {
final List<Tag> tags;
TagList({required this.tags});
[@override](/user/override)
Widget build(BuildContext context) {
return Wrap(
children: tags.map((tag) {
return Chip(
label: Text(tag.name),
backgroundColor: tag.color,
);
}).toList(),
);
}
}