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

Flutter实现无间隙连续播放MP3音频问题求助

MP3音频无间隙连续播放问题排查与解决方案

问题概述

需实现MP3音频的无间隙连续播放,目前三种Flutter方案(audioplayer库、just_audio两种实现)均能按顺序播放,但音频间存在约1秒间隙,不符合需求。

尝试的三种实现代码

1. 标准audioplayer库实现

// STANDARD AUDIO PLAYER
import 'package:audioplayers/audioplayers.dart';
...

AudioPlayer player = AudioPlayer();
...
void _playAudio(
    {required List<String> files, required int currentIndex}) async {
  String fileName =
      'audio/${files[currentIndex].toLowerCase()}.mp3';
  await player.play(AssetSource(fileName), mode: PlayerMode.lowLatency);

  player.onPlayerComplete.listen((event) {
    if (currentIndex + 1 >= files.length) {
      return;
    }
    _playAudio(files: files, currentIndex: ++currentIndex);
  });
}

2. just_audio循环播放实现(原代码存在语法/逻辑错误)

// JUST_AUDIO
import 'package:just_audio/just_audio.dart';
...
AudioPlayer player = AudioPlayer();
...
void _playAudio(
    {required List<String> files, required int currentIndex}) async {
  await AudioPlayer.clearAssetCache();
  for (final file in files) {
    await player.setAsset('assets/audio/${file}.mp3'); // 修正原代码语法错误
    await player.play();
    await player.pause(); // 逻辑错误:pause是立即暂停,而非等待播放完成
  }
}

3. just_audio播放列表实现

// JUST AUDIO GAPLESS
import 'package:just_audio/just_audio.dart';
...
AudioPlayer player = AudioPlayer();
...
void _playAudio(
    {required List<String> files, required int currentIndex}) async {
  final playlist = ConcatenatingAudioSource(
    useLazyPreparation: false,
    children: [],
  );
  for (final file in files) {
    playlist.add(AudioSource.asset('assets/audio/${file}.mp3'));
  }
  await player.setAudioSource(playlist);
  await player.play();
}

间隙产生的原因

  1. 标准audioplayer方案:onPlayerComplete回调存在系统级延迟,且每次切换音频时需重新加载资源,即使启用lowLatency模式,资源加载与回调触发的间隔仍会产生间隙。
  2. just_audio循环方案:代码逻辑错误(用pause替代等待播放完成),且clearAssetCache清空缓存会增加资源加载时间,每次setAsset都需重新解析音频文件,导致间隙。
  3. just_audio播放列表方案:
    • 音频文件本身问题:部分MP3文件编码时会在首尾插入静音填充数据,或自带间隙。
    • 预加载配置不合理:useLazyPreparation: false会一次性加载所有资源,但如果资源未完全加载就开始播放,切换时仍有延迟。
    • 平台音频引擎限制:部分Android/iOS设备的底层音频框架存在微小间隙,需额外配置优化。

可行解决方法

1. 优化just_audio播放列表配置

调整参数实现预加载与无缝切换:

final playlist = ConcatenatingAudioSource(
  useLazyPreparation: true, // 接近当前音频结束时预加载下一个资源
  children: files.map((file) => AudioSource.asset('assets/audio/${file}.mp3')).toList(),
);
await player.setAudioSource(playlist, initialIndex: 0);
await player.play();

确保使用最新版本的just_audio,版本更新常修复无缝播放的底层bug。

2. 预处理音频文件

  • 用Audacity等工具检查并移除MP3文件首尾的静音片段。
  • 若场景允许,提前将所有需连续播放的音频合并为单个MP3文件,从根源避免切换间隙。

3. 配置平台低延迟音频

  • Android:在AndroidManifest.xml中添加低延迟配置:
    <application ...>
      <meta-data android:name="android.media.AUDIO_ATTRIBUTES_FLAGS" android:value="AUDIO_FLAG_LOW_LATENCY" />
    </application>
    
  • iOS:在Info.plist中配置音频后台权限:
    <key>UIBackgroundModes</key>
    <array>
        <string>audio</string>
    </array>
    
    并初始化音频会话:
    import 'package:audio_session/audio_session.dart';
    
    Future<void> _initAudioSession() async {
      final session = await AudioSession.instance;
      await session.configure(AudioSessionConfiguration.music());
    }
    
    播放前调用_initAudioSession()。

4. 使用底层音频库flutter_sound

若上述方案无效,尝试flutter_sound提供的更精细音频控制:

import 'package:flutter_sound/flutter_sound.dart';

final FlutterSoundPlayer _player = FlutterSoundPlayer();

Future<void> _playGapless(List<String> files) async {
  await _player.openAudioSession();
  for (var file in files) {
    await _player.startPlayer(fromURI: 'assets/audio/${file}.mp3');
    await _player.onPlayerStateChanged.firstWhere((state) => state == PlayerState.stopped);
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 05:12:36