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
相关产品推荐
相关产品推荐

