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

Flutter中使用audioplayer播放音频遇Unable to load asset错误求助

问题:Flutter点击按钮播放音频提示“Unable to load asset”错误

我想要实现用户点击按钮时播放音频的功能,尝试了多种方法但始终提示“Unable to load asset”错误。我之前处理过资源文件,推测这是新问题,恳请各位帮忙解决。

代码实现

// ignore_for_file: prefer_const_constructors, file_names, non_constant_identifier_names

import 'dart:async';
import 'package:dyslexia/pages/data/DataSoundLevel1/DataQ1SoundL1.dart';
import 'package:dyslexia/pages/level1/round_2/Q8sound.dart';
import 'package:flutter/material.dart';
import 'package:flutter_tabler_icons/flutter_tabler_icons.dart';

import 'package:audioplayers/audioplayers.dart';

import '../../../utilities/QuestionWidget.dart';

class Q7sound extends StatefulWidget {
  const Q7sound({Key? key}) : super(key: key);

  @override
  State<Q7sound> createState() => _Q7soundState();
}

class _Q7soundState extends State<Q7sound> {
  String question =
      "Listen to this letter sound and then choose the letter whose sound you hear";

  var changeButton = false;

  bool changecolourC = false;
  bool changecolourW1 = false;
  bool changecolourW2 = false;
  bool changecolourW3 = false;

  double elev = 10;
  bool changeColor = false;
  String letter = "p";
  bool buttonPressed1 = false;
  bool isPlayingMsg = false;
  var istap = false;

  int clicksPerpage = 0;
  int correctAns = 0;
  int incorrectAns = 0;
  int timeFirstClick = 0;
  num duration = 0;
  List timeIntervalClicks = [];

  int timer = 0;
  bool canceltimer = false;

  void starttimer() async {
    const onesec = Duration(seconds: 1);
    Timer.periodic(onesec, (Timer t) {
      if (mounted) {
        setState(() {
          timer = timer + 1;
        });
      }
    });
  }

  AudioPlayer player = AudioPlayer();

  num countDuration() {
    for (int i = 0; i < timeIntervalClicks.length; i++) {
      duration = duration + timeIntervalClicks[i];
    }
    return duration;
  }

  DataQ1soundL1 data = new DataQ1soundL1();

  void mappData() {
    data.clicksPerpage = clicksPerpage;
    data.correctAns = correctAns;
    data.incorrectAns = incorrectAns;
    data.timeFirstClick = timeFirstClick;
    data.timeIntervalClicks = timeIntervalClicks;
    data.duration = countDuration();
  }

  @override
  Widget build(BuildContext context) {
    bool isPlayingMsg = false;

    return Scaffold(
      appBar: AppBar(
        automaticallyImplyLeading: true,
        backgroundColor: Colors.cyan,
        title: Text("AD&DY"),
      ),
      body: Padding(
        padding: const EdgeInsets.all(14.0),
        child: Column(children: [
          Row(mainAxisAlignment: MainAxisAlignment.center, children: [
            Icon(
              changecolourC
                  ? TablerIcons.circle_check
                  : changecolourW1
                      ? TablerIcons.circle_check
                      : changecolourW2
                          ? TablerIcons.circle_check
                          : changecolourW3
                              ? TablerIcons.circle_check
                              : TablerIcons.circle_dashed,
              size: 30,
              color: changecolourC
                  ? Colors.green
                  : changecolourW1
                      ? Colors.red
                      : changecolourW2
                          ? Colors.red
                          : changecolourW3
                              ? Colors.red
                              : Colors.black,
            ),
            Icon(
              TablerIcons.line_dashed,
              size: 30,
            ),
            Icon(
              TablerIcons.circle_dashed,
              size: 30,
            ),
            Icon(
              TablerIcons.line_dashed,
              size: 30,
            ),
            Icon(
              TablerIcons.circle_dashed,
              size: 30,
            ),
            Icon(
              TablerIcons.line_dashed,
              size: 30,
            ),
            Icon(
              TablerIcons.circle_dashed,
              size: 30,
            ),
            Icon(
              TablerIcons.line_dashed,
              size: 30,
            ),
            Icon(
              TablerIcons.circle_dashed,
              size: 30,
            ),
          ]),
          SizedBox(height: MediaQuery.of(context).size.height * 0.05),
          QuestionWidget(question: question),
          SizedBox(height: MediaQuery.of(context).size.height * 0.1),

          //audio button
          Material(
            elevation: 5,
            color: Colors.cyan[50],
            child: ListTile(
              onTap: () async {
                player.play(AssetSource("/sound/p.mp3"));
                isPlayingMsg = true;
                clicksPerpage += 1;
                timeFirstClick = timer.toInt();
                timeIntervalClicks.add(timer.toInt());
                if (mounted) {
                  setState(() {
                    timer = 0;
                  });
                }
              },
              leading: Icon(isPlayingMsg ? Icons.stop : Icons.play_arrow),
              title: Text(isPlayingMsg ? "Stop" : "Play",
                  textScaleFactor: 1.2,
                  style: TextStyle(
                    color: Colors.black,
                  )),
            ),
          ),

          Divider(
            thickness: 1.0,
          ),
          SizedBox(height: MediaQuery.of(context).size.height * 0.1),
          Wrap(
            spacing: 10,
            runSpacing: 5,
            children: [
              Material(
                elevation: elev,
                shadowColor: Colors.grey,
                color: changecolourW1 ? Colors.red : Colors.cyan,
                borderRadius: BorderRadius.circular(changeButton ? 50 : 8),
                child: InkWell(
                  onTap: () {
                    clicksPerpage += 1;
                    incorrectAns += 1;

                    timeIntervalClicks.add(timer.toInt());
                    if (mounted) {
                      setState(() {
                        changecolourW1 = true;
                        elev = 0;
                        timer = 0;
                      });
                    }
                  },
                  child: Container(
                      height: 50,
                      width: 50,
                      alignment: Alignment.center,
                      child: Text("M",
                          textScaleFactor: 1.2,
                          style: TextStyle(
                            color: Colors.black,
                          ))),
                ),
              ),
              Material(
                elevation: elev,
                shadowColor: Colors.grey,
                color: changecolourC ? Colors.green : Colors.cyan,
                borderRadius: BorderRadius.circular(changeButton ? 50 : 8),
                child: InkWell(
                  onTap: () {
                    clicksPerpage += 1;
                    correctAns += 1;
                    timeIntervalClicks.add(timer.toInt());
                    if (mounted) {
                      setState(() {
                        changecolourC = true;
                        elev = 0;
                        timer = 0;
                      });
                    }
                    istap = true;
                  },
                  child: Container(
                      height: 50,
                      width: 50,
                      alignment: Alignment.center,
                      child: Text("P",
                          textScaleFactor: 1.2,
                          style: TextStyle(
                            color: Colors.black,
                          ))),
                ),
              ),
              Material(
                elevation: elev,
                shadowColor: Colors.grey,
                color: changecolourW2 ? Colors.red : Colors.cyan,
                borderRadius: BorderRadius.circular(changeButton ? 50 : 8),
                child: InkWell(
                  onTap: () {
                    clicksPerpage += 1;
                    incorrectAns += 1;
                    timeIntervalClicks.add(timer.toInt());
                    if (mounted) {
                      setState(() {
                        changecolourW2 = true;
                        elev = 0;
                        timer = 0;
                      });
                    }
                  },
                  child: Container(
                      height: 50,
                      width: 50,
                      alignment: Alignment.center,
                      child: Text("R",
                          textScaleFactor: 1.2,
                          style: TextStyle(
                            color: Colors.black,
                          ))),
                ),
              ),
              Material(
                elevation: elev,
                shadowColor: Colors.grey,
                color: changecolourW3 ? Colors.red : Colors.cyan,
                borderRadius: BorderRadius.circular(changeButton ? 50 : 8),
                child: InkWell(
                  onTap: () {
                    clicksPerpage += 1;
                    incorrectAns += 1;
                    timeIntervalClicks.add(timer.toInt());

                    if (mounted) {
                      setState(() {
                        changecolourW3 = true;
                        elev = 0;
                        timer = 0;
                      });
                    }
                  },
                  child: Container(
                      height: 50,
                      width: 50,
                      alignment: Alignment.center,
                      child: Text("S",
                          textScaleFactor: 1.2,
                          style: TextStyle(
                            color: Colors.black,
                          ))),
                ),
              ),
            ],
          ),
          SizedBox(height: MediaQuery.of(context).size.height * 0.1),
          Material(
            color: Colors.black,
            borderRadius: BorderRadius.circular(changeButton ? 50 : 8),
            child: InkWell(
              onTap: () {
                mappData();

                Duration(seconds: 4);
                Navigator.of(context).pushReplacement(
                    MaterialPageRoute(builder: (context) => Q8sound()));
              },
              child: AnimatedContainer(
                duration: Duration(seconds: 4),
                width: changeButton ? 50 : 150,
                height: 50,
                alignment: Alignment.center,
                child: changeButton
                    ? Icon(
                        Icons.done,
                        color: Colors.black,
                      )
                    : Text(
                        'Next',
                        style: TextStyle(
                            color: Colors.white,
                            fontWeight: FontWeight.bold,
                            fontSize: 18),
                      ),
              ),
            ),
          ),
        ]),
      ),
    );
  }
}

错误信息

E/flutter (14336): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Unable to load asset: assets/sound/p.mp3
E/flutter (14336): #0      PlatformAssetBundle.load
package:flutter/…/services/asset_bundle.dart:258
E/flutter (14336): <asynchronous suspension>
E/flutter (14336): #1      AudioCache.fetchToMemory
package:audioplayers/src/audio_cache.dart:75
E/flutter (14336): <asynchronous suspension>
E/flutter (14336): #2      AudioCache.load
package:audioplayers/src/audio_cache.dart:101
E/flutter (14336): <asynchronous suspension>
E/flutter (14336): #3      _AudioPlayerLocalAssetState.playMusic
package:dyslexia/…/round_2/playeraudio.dart:67
E/flutter (14336): <asynchronous suspension>
E/flutter (14336):

解决方案

针对这个错误,从代码和资源配置角度排查几个关键点:

  • 修正资源路径格式
    代码里写的是player.play(AssetSource("/sound/p.mp3")),AssetSource的路径不需要开头的斜杠,改成AssetSource("sound/p.mp3")。因为Flutter的资源路径是相对于pubspec.yaml里配置的assets目录,开头加斜杠会导致路径错误。

  • 检查pubspec.yaml的资源配置
    确保你已经在pubspec.yaml里正确声明了音频资源:

    flutter:
      assets:
        - sound/p.mp3
        # 如果sound目录下有多个文件,可以直接声明整个目录:
        # - sound/
    

    配置完后执行flutter pub get,并重启IDE或热重载应用,确保资源被正确加载。

  • 确认文件路径和大小写
    Flutter的资源路径区分大小写,检查音频文件实际路径是sound/p.mp3还是Sound/P.mp3,要和代码里的路径完全一致。同时确认文件确实存在于项目对应目录下,没有拼写错误。

  • 清理缓存并重启应用
    执行flutter clean清理项目缓存,然后重新运行应用,避免缓存导致的资源加载异常。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 23:41:11