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

Flutter中点击色块时停止当前音频,播放新音频终止旧音频

Flutter木琴音频播放冲突解决(audioplayers: ^0.19.0)

问题描述

我用audioplayers: ^0.19.0开发Flutter木琴应用,现有代码如下:

import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:audioplayers/src/audio_cache.dart';

void main() => runApp(XylophoneApp());
 final player = AudioCache();
class XylophoneApp extends StatelessWidget {
  void playSound(String soundNumber) {
   
    player.play('beerpour.mp3');
  }
  
  Expanded buildKey({required Color color, required String soundNumber}) {
    return Expanded(
      child: FlatButton(
        color: color,
        onPressed: () {
          // create a new player
          // Audio cache is for local assets
          if (color == Colors.red) {
            playSound(soundNumber);//here it is played when tapped,I want no currently running sound to stop when new sound is played.
          } else {
            //I want to stop when other is pressed.
          }
        },
        child: Text(
          '',
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.black,
        body: SafeArea(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              buildKey(color: Colors.red, soundNumber: 'beerpour.mp3'),
              buildKey(color: Colors.green, soundNumber: 'beerpour.mp3'),
              buildKey(color: Colors.blue, soundNumber: 'beerpour.mp3'),
              buildKey(color: Colors.teal, soundNumber: 'beerpour.mp3'),
              buildKey(color: Colors.orange, soundNumber: 'beerpour.mp3'),
              buildKey(color: Colors.purple, soundNumber: 'beerpour.mp3'),
              buildKey(color: Colors.yellow, soundNumber: 'beerpour.mp3'),
            ],
          ),
        ),
      ),
    );
  }
}

需求:点击任意色块时,若当前有音频播放则停止;播放新音频时自动终止正在播放的音频。请问如何实现该功能?是否有更易实现的audioplayers版本?


解决方案

一、基于audioplayers: ^0.19.0的实现方法

^0.19.0版本中AudioCache每次调用play都会生成新的AudioPlayer实例,要实现停止当前播放的逻辑,需要保存当前播放的实例引用,每次点击时先终止它,再播放新音频:

  1. 将XylophoneApp改为StatefulWidget,用于维护当前播放的播放器状态;
  2. 声明AudioPlayer? _currentPlayer变量存储当前播放实例;
  3. 修改playSound方法,先停止当前播放,再启动新音频并保存实例;
  4. 移除原代码中按颜色区分的逻辑,所有色块执行统一的停止+播放流程。

修改后的完整代码:

import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:audioplayers/src/audio_cache.dart';

void main() => runApp(XylophoneApp());

class XylophoneApp extends StatefulWidget {
  @override
  _XylophoneAppState createState() => _XylophoneAppState();
}

class _XylophoneAppState extends State<XylophoneApp> {
  final AudioCache _audioCache = AudioCache();
  AudioPlayer? _currentPlayer;

  void playSound(String soundPath) async {
    // 停止当前正在播放的音频
    if (_currentPlayer != null) {
      await _currentPlayer!.stop();
    }
    // 播放新音频并保存播放器实例
    _currentPlayer = await _audioCache.play(soundPath);
  }

  Expanded buildKey({required Color color, required String soundNumber}) {
    return Expanded(
      child: FlatButton(
        color: color,
        onPressed: () {
          playSound(soundNumber);
        },
        child: Text(''),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.black,
        body: SafeArea(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              buildKey(color: Colors.red, soundNumber: 'beerpour.mp3'),
              buildKey(color: Colors.green, soundNumber: 'beerpour.mp3'),
              buildKey(color: Colors.blue, soundNumber: 'beerpour.mp3'),
              buildKey(color: Colors.teal, soundNumber: 'beerpour.mp3'),
              buildKey(color: Colors.orange, soundNumber: 'beerpour.mp3'),
              buildKey(color: Colors.purple, soundNumber: 'beerpour.mp3'),
              buildKey(color: Colors.yellow, soundNumber: 'beerpour.mp3'),
            ],
          ),
        ),
      ),
    );
  }
}

二、更易实现的audioplayers版本推荐

推荐升级到**audioplayers: 1.0.0+**以上稳定版本(当前最新稳定版为5.x),新版本API更简洁,AudioCache已整合到AudioPlayer中,无需手动管理多个播放器实例:

  1. 直接使用AudioPlayer加载本地资源,播放前调用stop()即可终止当前播放;
  2. 无需导入audio_cache.dart,API统一度更高。

示例代码(基于audioplayers: ^5.x):

import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/material.dart';

void main() => runApp(const XylophoneApp());

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

  @override
  State<XylophoneApp> createState() => _XylophoneAppState();
}

class _XylophoneAppState extends State<XylophoneApp> {
  final AudioPlayer _player = AudioPlayer();

  Future<void> playSound(String soundPath) async {
    // 先停止当前播放
    await _player.stop();
    // 加载并播放本地音频资源
    await _player.play(AssetSource(soundPath));
  }

  Expanded buildKey({required Color color, required String soundPath}) {
    return Expanded(
      child: TextButton(
        style: TextButton.styleFrom(backgroundColor: color),
        onPressed: () => playSound(soundPath),
        child: const Text(''),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.black,
        body: SafeArea(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              buildKey(color: Colors.red, soundPath: 'beerpour.mp3'),
              buildKey(color: Colors.green, soundPath: 'beerpour.mp3'),
              buildKey(color: Colors.blue, soundPath: 'beerpour.mp3'),
              buildKey(color: Colors.teal, soundPath: 'beerpour.mp3'),
              buildKey(color: Colors.orange, soundPath: 'beerpour.mp3'),
              buildKey(color: Colors.purple, soundPath: 'beerpour.mp3'),
              buildKey(color: Colors.yellow, soundPath: 'beerpour.mp3'),
            ],
          ),
        ),
      ),
    );
  }
}

新版本优势:

  • API直观,无需区分AudioCache与AudioPlayer;
  • 内置完善的播放控制方法,代码更简洁;
  • 官方维护活跃,bug修复与功能更新及时。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 16:00:19