Flutter音频标签解析插件taglib_ffi的使用

Flutter音频标签解析插件taglib_ffi的使用

仅在MacOS上构建/测试!

目前,该插件仅在MacOS上构建和测试。

支持格式:

  • MP3
  • FLAC
  • MP4 (也称为M4A,也称为ALAC)

支持的功能:

  • 读取/更新/删除标签(见下文)
  • 读取/更新/删除封面艺术
  • 读取/更新/删除歌词

依赖项

MacOS

brew install cmake
brew install taglib

设置

MacOS

需要定义HOMEBREW_PREFIX变量:

export HOMEBREW_PREFIX="$(brew --prefix)" 

使用

将插件添加到pubspec.yaml依赖项中。

读取/写入标签:

TagLib tagLib = TagLib();
Tags tags = tagLib.getAudioTags(filename);
if (tags.valid) {
  // 处理标签
}
// 更新标签
tagLib.setAudioTag(filename, tags);

显示封面艺术:

TagLib tagLib = TagLib();
FutureBuilder(
  future: tagLib.getArtworkBytes(filename),
  builder: (_, snapshot) => Image.memory(snapshot.data)
)

读取/写入歌词:

TagLib tagLib = TagLib();
String lyrics = tagLib.getLyrics(filename);
// 更新歌词
tagLib.setLyrics(filename, lyrics);

支持的标签

  • 标题
  • 专辑
  • 艺术家(专辑艺术家)
  • 表演者
  • 作曲者
  • 风格
  • 版权
  • 注释
  • 年份
  • 合辑
  • 卷/专辑编号
  • 卷/专辑数量
  • 轨道编号
  • 轨道数量

示例代码

以下是完整的示例代码,展示了如何使用taglib_ffi插件来读取和显示文件的音频标签和封面艺术。

import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:taglib_ffi/taglib_ffi.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final TagLib _tagLib = TagLib();
  String? _filename;
  Tags? _tags;

  [@override](/user/override)
  void initState() {
    super.initState();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('TagLib FFI'),
        ),
        body: SingleChildScrollView(
          child: Container(
            width: double.infinity,
            padding: const EdgeInsets.all(10),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                ElevatedButton(
                    child: const Text('选择一个文件...'),
                    onPressed: () async {
                      FilePickerResult? result = await FilePicker.platform.pickFiles();
                      if (result != null) {
                        setState(() {
                          _filename = result.files.single.path;
                          _tags = _tagLib.getAudioTags(_filename!);
                        });
                      }
                    }),
                if (_filename != null) ...[
                  const SizedBox(height: 32),
                  Text(
                    _filename!,
                    style: const TextStyle(fontWeight: FontWeight.bold),
                  ),
                  const SizedBox(height: 16),
                  FutureBuilder(
                      future: _tagLib.getArtworkBytes(_filename!),
                      builder: (context, snapshot) {
                        if (snapshot.hasData && snapshot.data != null) {
                          return Container(
                            margin: const EdgeInsets.only(bottom: 16),
                            child: Image.memory(
                              snapshot.data!,
                              height: 64,
                            ),
                          );
                        } else {
                          return Container();
                        }
                      }),
                  if (_tags != null) ...[
                    if (!_tags!.valid)
                      const Text('无标签')
                    else ...[
                      Text('标题: ${_tags!.title}'),
                      Text('专辑: ${_tags!.album}'),
                      Text('艺术家: ${_tags!.artist}'),
                      Text('表演者: ${_tags!.performer}'),
                      Text('作曲者: ${_tags!.composer}'),
                      Text('风格: ${_tags!.genre}'),
                      Text('版权: ${_tags!.copyright}'),
                      Text('注释: ${_tags!.comment}'),
                      Text('年份: ${_tags!.year}'),
                      Text('合辑: ${_tags!.compilation}'),
                      Text('卷: ${_tags!.volumeIndex} / ${_tags!.volumeCount}'),
                      Text('轨道: ${_tags!.trackIndex} / ${_tags!.trackCount}'),
                      Text('时长: ${_tags!.duration}'),
                      Text('声道数: ${_tags!.numChannels}'),
                      Text('采样率: ${_tags!.sampleRate}'),
                      Text('每样本位数: ${_tags!.bitsPerSample}'),
                      Text('比特率: ${_tags!.bitrate}'),
                    ],
                  ],
                ],
              ],
            ),
          ),
        ),
      ),
    );
  }
}

更多关于Flutter音频标签解析插件taglib_ffi的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter音频标签解析插件taglib_ffi的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用taglib_ffi插件来解析音频文件标签的示例代码。taglib_ffi是一个基于FFI(Foreign Function Interface)的Flutter插件,它允许你使用TagLib库来读取和写入音频文件的元数据。

首先,确保你已经在pubspec.yaml文件中添加了taglib_ffi依赖:

dependencies:
  flutter:
    sdk: flutter
  taglib_ffi: ^x.y.z  # 请替换为最新版本号

然后,运行flutter pub get来安装依赖。

接下来,在你的Flutter项目中,你可以按照以下步骤使用taglib_ffi来解析音频文件的标签。

示例代码

  1. 导入必要的包
import 'package:flutter/material.dart';
import 'package:taglib_ffi/taglib_ffi.dart';
import 'dart:io';
  1. 定义一个函数来解析音频文件
Future<void> parseAudioFile(File file) async {
  try {
    // 初始化TagLib库
    TagLib.initialize();

    // 打开文件
    var tagFile = TagLibFile(file.absolute.path);

    // 获取音频文件的标签信息
    var tag = tagFile.tag;

    // 输出标签信息
    print('Title: ${tag.title ?? 'N/A'}');
    print('Artist: ${tag.artist ?? 'N/A'}');
    print('Album: ${tag.album ?? 'N/A'}');
    print('Genre: ${tag.genre ?? 'N/A'}');
    print('Year: ${tag.year ?? 'N/A'}');
    print('Track Number: ${tag.track ?? 'N/A'}');
    print('Comment: ${tag.comment ?? 'N/A'}');

    // 清理资源
    TagLib.deinitialize();
  } catch (e) {
    print('Error parsing audio file: $e');
  }
}
  1. 在UI中触发文件选择并解析
void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Audio Tag Parser'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: () async {
              // 打开文件选择器
              var result = await FilePicker.platform.pickFiles(
                type: FileType.audio,
              );

              if (result != null && result.files.isNotEmpty) {
                var file = File(result.files.first.path!);
                // 解析音频文件
                await parseAudioFile(file);
              }
            },
            child: Text('Select Audio File'),
          ),
        ),
      ),
    );
  }
}

注意:上面的代码示例使用了file_picker插件来选择文件。你需要在pubspec.yaml中添加file_picker依赖并运行flutter pub get来安装它。

dependencies:
  file_picker: ^x.y.z  # 请替换为最新版本号

确保你已经处理了必要的权限,特别是在Android和iOS上访问文件系统所需的权限。

总结

以上代码展示了如何使用taglib_ffi插件在Flutter应用中解析音频文件的标签信息。通过初始化TagLib库、打开文件、获取标签信息,并在UI中触发文件选择和解析,你可以轻松地读取音频文件的元数据。记得根据实际情况处理错误和异常,以及管理资源(如初始化和清理TagLib库)。

回到顶部