如何无缝循环背景音频?

问题描述 投票:0回答:3

该应用程序无限循环地播放一些背景音频(wav)。使用

just_audio
包的音频播放是完美的,但切换到
audioplayers
后,所有循环音频现在在重新开始之前都包含短暂的静音间隙。现在的问题是:如何消除差距?

加载和播放文件的代码非常简单:

  Future<void> loadAmbient() async {
    _audioAmbient = AudioPlayer();
    await _audioAmbient!.setSource(AssetSource('audio/ambient.wav'));
    await _audioAmbient!.setReleaseMode(ReleaseMode.loop);
  }

  void playAmbient() async {
    if (PlayerState.playing != _audioAmbient?.state) {
      await _audioAmbient?.seek(Duration.zero);
      _audioAmbient?.resume();
    }
  }

根据音频播放器文档,这似乎是一个已知问题:

入门文档状态:

注意:无间隙循环音频时有一些注意事项。根据文件格式和平台的不同,当音频播放器使用“循环”功能的本机实现时,播放之间会存在间隙,对于非连续 SFX 可能不会明显,但对于循环歌曲肯定会明显。请查看我们的故障排除指南中的无缝环部分了解更多详细信息。

按照[故障排除指南] (https://github.com/bluefireteam/audioplayers/blob/main/troubleshooting.md) 的链接显示:

无缝循环

根据文件格式和平台的不同,当音频播放器使用“循环”功能的本机实现时,播放之间会存在间隙,对于非连续的 SFX 可能不会明显,但对于循环歌曲肯定会明显。

TODO(luan):在这里分解替代方案,低延迟模式,音频池,gapless_audioplayer,陶笛等

有趣的是

Depending on the file format and platform, ... 
部分,这听起来好像无间隙循环可以以某种方式实现。问题是,怎么办?

非常感谢任何如何使音频完美循环(即没有间隙)的想法。谢谢你。

android flutter audio flame
3个回答
0
投票

可以传递这个参数

_audioAmbient = AudioPlayer(mode: PlayerMode.LOW_LATENCY);

如果没有解决,你可以尝试一些新的东西,比如https://pub.dev/packages/ocarina


0
投票

我是这样修复的: 创建了 2 个玩家,为他们两个设置了资产路径,并创建了在第一个玩家完成之前启动第二个玩家的方法

import 'package:just_audio/just_audio.dart' as audio;

audio.AudioPlayer player1 = audio.AudioPlayer();
audio.AudioPlayer player2 = audio.AudioPlayer();
bool isFirstPlayerActive = true;
StreamSubscription? subscription;

  audio.AudioPlayer getActivePlayer() {
    return isFirstPlayerActive ? player1 : player2;
  }

  void setPlayerAsset(String asset) async {
    if (isFirstPlayerActive) {
      await player1.setAsset("assets/$asset");
      await player2.setAsset("assets/$asset");
    } else {
      await player2.setAsset("assets/$asset");
      await player1.setAsset("assets/$asset");
    }
    subscription?.cancel();
    _loopPlayer(getActivePlayer(), isFirstPlayerActive ? player2 : player1);
  }


  audio.AudioPlayer getActivePlayer() {
    return isFirstPlayerActive ? player1 : player2;
  }
  
  void _loopPlayer(audio.AudioPlayer player1, audio.AudioPlayer player2) async {
      Duration? duration = await player1.durationFuture;
      subscription = player1.positionStream.listen((event) {
        if (duration != null &&
            event.inMilliseconds >= duration.inMilliseconds - 110) {
          log('finished');
          player2.play();
          isFirstPlayerActive = !isFirstPlayerActive;
          StreamSubscription? tempSubscription;
          tempSubscription = player1.playerStateStream.listen((event) {
            if (event.processingState == audio.ProcessingState.completed) {
              log('completed');
              player1.seek(const Duration(seconds: 0));
              player1.pause();
              tempSubscription?.cancel();
            }
          });
          subscription?.cancel();
          _loopPlayer(player2, player1);
        }
      });
  
  }

0
投票

我花了很长时间才解决这个问题,因为任何可用的软件包都不能令人满意地解决该问题。

终于我找到了完美的方法。

使用

ocarina
包。不幸的是,它不再被维护,并且不支持新的 Android。 因此,我们分叉了这个存储库并进行了必要的更改。 存储库:https://github.com/mszakacz/ocarina 它支持 Gradle 1.8.0,因此解决了新 Android 的问题。

使用说明:

  1. pubspec.yaml
    中添加以下依赖项:

    陶笛: git: 网址:https://github.com/mszakacz/ocarina

  2. 转到

    android/build.gradle
    并更新您的 kotlin 版本:

    ext.kotlin_version = '1.8.0'

另外 为什么其他包不起作用?

Audioplayers
- 在 Android 上工作,但你可以注意到 iOS 上的差距 (https://github.com/bluefireteam/audioplayers/blob/main/troubleshooting.md#gapless-looping)

just_audio
- 在 Android 上并非无缝

© www.soinside.com 2019 - 2024. All rights reserved.