You need to enable JavaScript to run this app. 使用Flutter或Python访问用户设备音频文件及元数据的实现方案问询
优惠活动
大模型
产品
解决方案
定价
更多

使用Flutter或Python访问用户设备音频文件及元数据的实现方案问询

Flutter端实现方案

前置准备

首先需要申请设备存储/媒体访问权限,使用permission_handler包实现权限申请逻辑:

  • 安卓端:安卓13及以上需申请READ_MEDIA_AUDIO权限,更低版本需申请READ_EXTERNAL_STORAGE权限
  • iOS端:需申请媒体库访问权限,需在Info.plist中添加NSAppleMusicUsageDescription权限说明

核心实现

推荐使用on_audio_query包完成音频扫描和元数据读取,该包同时支持安卓、iOS平台,默认兼容mp3、wav等主流音频格式:

  1. 先在pubspec.yaml中添加依赖:
dependencies:
  permission_handler: ^11.0.1
  on_audio_query: ^2.9.0
  1. 权限申请代码示例:
import 'dart:io';
import 'package:permission_handler/permission_handler.dart';
import 'package:device_info_plus/device_info_plus.dart';

Future<bool> checkAndRequestAudioPermission() async {
  if (Platform.isAndroid) {
    final androidInfo = await DeviceInfoPlugin().androidInfo;
    if (androidInfo.version.sdkInt >= 33) {
      return await Permission.audio.request().isGranted;
    } else {
      return await Permission.storage.request().isGranted;
    }
  } else if (Platform.isIOS) {
    return await Permission.mediaLibrary.request().isGranted;
  }
  return false;
}
  1. 扫描音频并读取元数据代码示例:
import 'package:on_audio_query/on_audio_query.dart';

final OnAudioQuery audioQuery = OnAudioQuery();

Future<List<SongModel>> getTargetAudioFiles() async {
  // 查询设备所有音频文件
  List<SongModel> allSongs = await audioQuery.querySongs(
    sortType: SongSortType.TITLE,
    orderType: OrderType.ASC_OR_SMALLER,
    uriType: UriType.EXTERNAL,
    ignoreCase: true,
  );
  // 过滤仅保留mp3、wav格式文件
  return allSongs.where((song) {
    final ext = song.fileExtension.toLowerCase();
    return ext == 'mp3' || ext == 'wav';
  }).toList();
}

返回的SongModel对象可直接读取所需元数据:

  • 歌曲名:song.title
  • 作者名:song.artist
  • 专辑名:song.album
  • 音频时长:song.duration
  • 本地文件路径:song.data
Python端备选实现方案

如果需要离线预处理音频文件,可使用以下方案实现本地音频扫描和元数据读取:

  1. 安装依赖:
    pip install mutagen
  2. 实现代码:
import os
from mutagen import File

def scan_local_audio(root_dir: str) -> list[dict]:
    audio_result = []
    for root, _, files in os.walk(root_dir):
        for file in files:
            file_ext = os.path.splitext(file)[-1].lower()
            if file_ext not in ('.mp3', '.wav'):
                continue
            file_path = os.path.join(root, file)
            try:
                audio = File(file_path, easy=True)
                if not audio:
                    continue
                audio_meta = {
                    "file_path": file_path,
                    "title": audio.get("title", [os.path.splitext(file)[0]])[0],
                    "artist": audio.get("artist", ["未知作者"])[0],
                    "album": audio.get("album", ["未知专辑"])[0],
                    "duration": round(audio.info.length, 2) if hasattr(audio, "info") else 0
                }
                audio_result.append(audio_meta)
            except Exception:
                # 跳过损坏的音频文件
                continue
    return audio_result

调用时传入待扫描的根目录路径,即可返回所有符合要求的音频文件及其元数据。


内容的提问来源于stack exchange,提问作者user15887518

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 05:48:03