You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何加载并播放Install-time交付资源包内的MP3文件?

问题描述

我是Flutter新手,正在使用flutter_play_asset_delivery插件。我在Flutter项目中采用Install-time Delivery Asset Packs管理资源,其中包含MP3文件,希望在应用中播放这些文件,现寻求正确的加载与播放方法,欢迎提供思路或代码片段。

我的pubspec.yaml配置如下:

dependencies:
  flutter:
    sdk: flutter
  audioplayers_darwin: ^5.0.1
  cupertino_icons: ^1.0.2
  just_audio_background: ^0.0.1-beta.10
  audio_service: ^0.18.12
  just_audio: ^0.9.35
  flutter_play_asset_delivery: ^0.0.2

报错信息:

E/flutter (13059): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Exception: Asset file PonSelAudTrai1-1.mp3 not found.
E/flutter (13059): #0      FlutterPlayAssetDelivery.getAssetFile (package:flutter_play_asset_delivery/flutter_play_asset_delivery.dart:17:7)
E/flutter (13059): <asynchronous suspension>
E/flutter (13059): 
E/flutter (13059): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Exception: Asset file PonSelAudTrai1-2.mp3 not found.
E/flutter (13059): #0      FlutterPlayAssetDelivery.getAssetFile (package:flutter_play_asset_delivery/flutter_play_asset_delivery.dart:17:7)
E/flutter (13059): <asynchronous suspension>

audio.dart代码:

static int _nextMediaId = 0;
  late AudioPlayer _player;
  late Future<File> audio_1;
  late Future<File> audio_2;
  late Future<File> audio_3;
  late Future<File> audio_4;
  late Future<File> image;
  // late String audioFilePath;
  late ConcatenatingAudioSource _playlist;

  @override
  void initState() {
    super.initState();
    _player = AudioPlayer();
    SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
      statusBarColor: Colors.black,
    ));
    _init();
    _loadAudioAssets();

  }
  Future<void> _loadAudioAssets() async {
    audio_1 =  FlutterPlayAssetDelivery.getAssetFile("PonSelAudTrai1-1.mp3");
    audio_2 =  FlutterPlayAssetDelivery.getAssetFile("PonSelAudTrai1-2.mp3");
    audio_3 =  FlutterPlayAssetDelivery.getAssetFile("PonSelAudTrai1-3.mp3");
    audio_4 =  FlutterPlayAssetDelivery.getAssetFile("PonSelAudTrai1-4.mp3");
    // audioFilePath = FlutterPlayAssetDelivery.getAssetFile("PonSelAudTrai1-1.mp3") as String;
    _playlist =  _updatePlaylistPaths();
  }

 ConcatenatingAudioSource _updatePlaylistPaths() {
    return ConcatenatingAudioSource(children: [
      ClippingAudioSource(
        start: const Duration(seconds: 0),
        end: const Duration(seconds: 163),
        child: AudioSource.uri(Uri.file("$audio_1")),
        // <-- Use the variable here
        tag: MediaItem(
          id: '${_nextMediaId++}',
          album: "",
          title: "▶︎ 01 - முன்னோட்டம்",
          artUri: Uri.parse(
              "https://play-lh.googleusercontent.com/aZ41BkoanL_UP2kMyBuqE7mesewHowGbcl_TjfChnSvpYWyaO7L_84wHOIM_3x247dw=w240-h480-rw"),
        ),
      ),
      AudioSource.uri(
        Uri.parse('$audio_2'),
        tag: MediaItem(
          id: '${_nextMediaId++}',
          album: "",
          title: "▶︎ 02 - முன்னோட்டம்",
          artUri: Uri.parse(
              "https://play-lh.googleusercontent.com/aZ41BkoanL_UP2kMyBuqE7mesewHowGbcl_TjfChnSvpYWyaO7L_84wHOIM_3x247dw=w240-h480-rw"),
        ),
      ),
      AudioSource.uri(
        Uri.parse(
            '$audio_3'),
        tag: MediaItem(
          id: '${_nextMediaId++}',
          album: "",
          title: "▶︎ 03 - முன்னோட்டம்",
          artUri: Uri.parse(
              "https://play-lh.googleusercontent.com/aZ41BkoanL_UP2kMyBuqE7mesewHowGbcl_TjfChnSvpYWyaO7L_84wHOIM_3x247dw=w240-h480-rw"),
        ),
      ),
      AudioSource.uri(
        Uri.parse(
            '$audio_4'),
        tag: MediaItem(
          id: '${_nextMediaId++}',
          album: "",
          title: "▶︎ 04 - முன்னோட்டம்",
          artUri: Uri.parse(
              "https://play-lh.googleusercontent.com/aZ41BkoanL_UP2kMyBuqE7mesewHowGbcl_TjfChnSvpYWyaO7L_84wHOIM_3x247dw=w240-h480-rw"),
        ),
      ),

    ]);
   // setState(() {
   //   _playlist = _playlist; // Assuming _playlist is a state variable
   // });
  }

恳请指导如何正确加载并播放Install-time Delivery Asset Pack中的MP3文件。


解决方案

1. 先排查Asset Pack的Android配置

Install-time Asset Pack需要在Android端完成基础配置:

  • 在android/app/build.gradle中声明Asset Pack依赖:
    android {
        ...
        assetPacks = [":your_asset_pack_name"]
    }
    
  • 确认Asset Pack的目录结构:Asset Pack的src/main/assets目录下必须存放你的MP3文件,比如src/main/assets/PonSelAudTrai1-1.mp3,文件名要和代码中调用的完全一致(Android对文件路径大小写敏感)。

2. 修正异步加载的逻辑错误

你的代码存在两个核心问题:直接将Future<File>转为字符串使用、在Future未完成时就构建播放列表。修改后的代码如下:

@override
void initState() {
  super.initState();
  _player = AudioPlayer();
  SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
    statusBarColor: Colors.black,
  ));
  _init();
  // 异步初始化播放列表
  _initPlaylist();
}

Future<void> _initPlaylist() async {
  try {
    // 等待所有Asset文件加载完成
    final audioFile1 = await FlutterPlayAssetDelivery.getAssetFile("PonSelAudTrai1-1.mp3");
    final audioFile2 = await FlutterPlayAssetDelivery.getAssetFile("PonSelAudTrai1-2.mp3");
    final audioFile3 = await FlutterPlayAssetDelivery.getAssetFile("PonSelAudTrai1-3.mp3");
    final audioFile4 = await FlutterPlayAssetDelivery.getAssetFile("PonSelAudTrai1-4.mp3");

    // 创建播放列表
    _playlist = ConcatenatingAudioSource(children: [
      ClippingAudioSource(
        start: const Duration(seconds: 0),
        end: const Duration(seconds: 163),
        child: AudioSource.uri(Uri.file(audioFile1.path)),
        tag: MediaItem(
          id: '${_nextMediaId++}',
          album: "",
          title: "▶︎ 01 - முன்னோட்டம்",
          artUri: Uri.parse(
              "https://play-lh.googleusercontent.com/aZ41BkoanL_UP2kMyBuqE7mesewHowGbcl_TjfChnSvpYWyaO7L_84wHOIM_3x247dw=w240-h480-rw"),
        ),
      ),
      AudioSource.uri(
        Uri.file(audioFile2.path),
        tag: MediaItem(
          id: '${_nextMediaId++}',
          album: "",
          title: "▶︎ 02 - முன்னோட்டம்",
          artUri: Uri.parse(
              "https://play-lh.googleusercontent.com/aZ41BkoanL_UP2kMyBuqE7mesewHowGbcl_TjfChnSvpYWyaO7L_84wHOIM_3x247dw=w240-h480-rw"),
        ),
      ),
      AudioSource.uri(
        Uri.file(audioFile3.path),
        tag: MediaItem(
          id: '${_nextMediaId++}',
          album: "",
          title: "▶︎ 03 - முன்னோட்டம்",
          artUri: Uri.parse(
              "https://play-lh.googleusercontent.com/aZ41BkoanL_UP2kMyBuqE7mesewHowGbcl_TjfChnSvpYWyaO7L_84wHOIM_3x247dw=w240-h480-rw"),
        ),
      ),
      AudioSource.uri(
        Uri.file(audioFile4.path),
        tag: MediaItem(
          id: '${_nextMediaId++}',
          album: "",
          title: "▶︎ 04 - முன்னோட்டம்",
          artUri: Uri.parse(
              "https://play-lh.googleusercontent.com/aZ41BkoanL_UP2kMyBuqE7mesewHowGbcl_TjfChnSvpYWyaO7L_84wHOIM_3x247dw=w240-h480-rw"),
        ),
      ),
    ]);

    // 将播放列表加载到播放器
    await _player.setAudioSource(_playlist);
    // 可选:自动播放
    // await _player.play();
  } catch (e) {
    print("加载音频失败: $e");
  }
}

3. 额外排查技巧

  • 如果仍提示文件找不到,可调用FlutterPlayAssetDelivery.listAssets()方法列出所有可用Asset,确认目标MP3是否在列表中,排查路径或文件名错误。
  • 发布到Google Play时,需在Play Console中正确配置Asset Pack的交付类型为Install-time。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 18:07:02