在Flutter中使用’audioplayers’库播放URL时出现冻结?

huangapple go评论69阅读模式
英文:

Freeze when playing URL with 'audioplayers' library in Flutter?

问题

以下是您提供的代码的翻译部分:

我有一组URL,我想在Flutter中使用'audioplayers'来播放。当URL列表开始播放时,播放7-8URL后,冻结过程会发生。应用程序和页面会冻结。这总是显示为错误:

E/flutter (11570): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Bad state: Future already completed
E/flutter (11570): #0      _AsyncCompleter.complete (dart:async/future_impl.dart:35:31)
E/flutter (11570): #1      AudioPlayer._completePrepared.<anonymous closure> (package:audioplayers/src/audioplayer.dart:292:29)
E/flutter (11570): #2      _RootZone.runUnaryGuarded (dart:async/zone.dart:1594:10)
E/flutter (11570): #3      _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)
E/flutter (11570): #4      _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
E/flutter (11570): #5      _ForwardingStreamSubscription._add (dart:async/stream_pipe.dart:123:11)
E/flutter (11570): #6      _MapStream._handleData (dart:async/stream_pipe.dart:218:10)
E/flutter (11570): #7      _RootZone.runUnaryGuarded (dart:async/zone.dart:1594:10)
E/flutter (11570): #8      _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)
E/flutter (11570): #9      _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
E/flutter (11570): #10     _ForwardingStreamSubscription._add (dart:async/stream_pipe.dart:123:11)
E/flutter (11570): #11     _WhereStream._handleData (dart:async/stream_pipe.dart:195:12)
E/flutter (11570): #12     _RootZone.runUnaryGuarded (dart:async/zone.dart:1594:10)
E/flutter (11570): #13     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)
E/flutter (11570): #14     _DelayedData.perform (dart:async/stream_impl.dart:515:14)
E/flutter (11570): #15     _PendingEvents.handleNext (dart:async/stream_impl.dart:620:11)
E/flutter (11570): #16     _PendingEvents.schedule.<anonymous closure> (dart:async/stream_impl.dart:591:7)
E/flutter (11570): #17     _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
E/flutter (11570): #18     _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)

我的相关代码如下:

bool isPlaying = false;
AudioPlayer audioPlayer = AudioPlayer();
int currentIndex = 0;
int start = 0;

//按钮按下
onPressed: () {
    isPlaying = !isPlaying;
    if (start == 0) {
        start++;
        playAudioInstructions();
    } else if (start == 1) {
        start++;
        audioPlayer.pause();
    } else {
        start--;
        audioPlayer.resume();
    }
    setState(() {});
},

void playAudioInstructions() {
    playAudio(urlList, currentIndex);
}

Future<void> playAudio(List<String> urlList, int currentIndex) async {
    await audioPlayer.play(UrlSource(urlList[currentIndex]));
    audioPlayer.onPlayerComplete.listen((event) {
        if (currentIndex < urlList.length - 1) {
            audioPlayer.stop();
            currentIndex++;
            playAudio(urlList, currentIndex);
        } else {
            currentIndex = 0;
            audioPlayer.stop();
            start = 0;
        }
    });
}

我无法找出冻结的原因。我将很乐意帮助您调整代码片段。
英文:

I have a list of URLs that I want to play with 'audioplayers' in Flutter. When the URL list starts to play, the freezing process occurs after playing 7-8 URLs. App and page freezes. This is always shown as an error:

E/flutter (11570): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Bad state: Future already completed
E/flutter (11570): #0      _AsyncCompleter.complete (dart:async/future_impl.dart:35:31)
E/flutter (11570): #1      AudioPlayer._completePrepared.&lt;anonymous closure&gt; (package:audioplayers/src/audioplayer.dart:292:29)
E/flutter (11570): #2      _RootZone.runUnaryGuarded (dart:async/zone.dart:1594:10)
E/flutter (11570): #3      _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)
E/flutter (11570): #4      _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
E/flutter (11570): #5      _ForwardingStreamSubscription._add (dart:async/stream_pipe.dart:123:11)
E/flutter (11570): #6      _MapStream._handleData (dart:async/stream_pipe.dart:218:10)
E/flutter (11570): #7      _RootZone.runUnaryGuarded (dart:async/zone.dart:1594:10)
E/flutter (11570): #8      _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)
E/flutter (11570): #9      _BufferingStreamSubscription._add (dart:async/stream_impl.dart:271:7)
E/flutter (11570): #10     _ForwardingStreamSubscription._add (dart:async/stream_pipe.dart:123:11)
E/flutter (11570): #11     _WhereStream._handleData (dart:async/stream_pipe.dart:195:12)
E/flutter (11570): #12     _RootZone.runUnaryGuarded (dart:async/zone.dart:1594:10)
E/flutter (11570): #13     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:339:11)
E/flutter (11570): #14     _DelayedData.perform (dart:async/stream_impl.dart:515:14)
E/flutter (11570): #15     _PendingEvents.handleNext (dart:async/stream_impl.dart:620:11)
E/flutter (11570): #16     _PendingEvents.schedule.&lt;anonymous closure&gt; (dart:async/stream_impl.dart:591:7)
E/flutter (11570): #17     _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
E/flutter (11570): #18     _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)

My related codes are as follows:

  bool isPlaying = false;
AudioPlayer audioPlayer = AudioPlayer();
int currentIndex = 0;
int start = 0;
...
//button pressed
onPressed: () {
isPlaying = !isPlaying;
if (start == 0) {
start++;
playAudioInstructions();
} else if (start == 1) {
start++;
audioPlayer.pause();
} else {
start--;
audioPlayer.resume();
}
setState(() {});
},
...
void playAudioInstructions() {
playAudio(urlList, currentIndex);
}
Future&lt;void&gt; playAudio(List&lt;String&gt; urlList, int currentIndex) async {
await audioPlayer.play(UrlSource(urlList[currentIndex]));
audioPlayer.onPlayerComplete.listen((event) {
if (currentIndex &lt; urlList.length - 1) {
audioPlayer.stop();
currentIndex++;
playAudio(urlList, currentIndex);
} else {
currentIndex = 0;
audioPlayer.stop();
start = 0;
}
});
}
...

I couldn't figure out the cause of the freezing. I'd be happy to get help with the code snippet.

答案1

得分: -2

你遇到的冻结问题似乎与你的Flutter应用中的“坏状态:Future已经完成”错误有关。通常情况下,当你尝试完成已经完成的Future时,会发生这个错误。

从你的代码来看,问题似乎发生在playAudio函数中,当你递归调用playAudio以播放列表中的下一个URL时。问题出现在你在创建新订阅之前未正确取消先前的audioPlayer.onPlayerComplete订阅。结果是会创建多个订阅,导致错误发生。

要解决这个问题,你需要在创建新订阅之前使用cancel方法取消先前的订阅。以下是你的代码的更新版本,包括必要的修改:

bool isPlaying = false;
AudioPlayer audioPlayer = AudioPlayer();
int currentIndex = 0;
int start = 0;
StreamSubscription<void>? playerCompleteSubscription; // Add this line

// ...

onPressed: () {
  isPlaying = !isPlaying;
  if (start == 0) {
    start++;
    playAudioInstructions();
  } else if (start == 1) {
    start++;
    audioPlayer.pause();
  } else {
    start--;
    audioPlayer.resume();
  }
  setState(() {});
},

// ...

void playAudioInstructions() {
  playAudio(urlList, currentIndex);
}

Future<void> playAudio(List<String> urlList, int currentIndex) async {
  await audioPlayer.play(UrlSource(urlList[currentIndex]));

  playerCompleteSubscription?.cancel(); // Cancel previous subscription if exists
  playerCompleteSubscription = audioPlayer.onPlayerComplete.listen((event) {
    if (currentIndex < urlList.length - 1) {
      audioPlayer.stop();
      currentIndex++;
      playAudio(urlList, currentIndex);
    } else {
      currentIndex = 0;
      audioPlayer.stop();
      start = 0;
    }
  });
}

在更新后的代码中,我添加了一个StreamSubscription? playerCompleteSubscription变量来跟踪audioPlayer.onPlayerComplete事件的订阅。在创建新订阅之前,我检查是否存在现有的订阅,并使用cancel方法取消它。

通过取消先前的订阅,你确保一次只有一个订阅处于活动状态,防止了“坏状态:Future已经完成”错误和潜在的应用程序冻结。

请确保用上述修改后的代码替换你原始代码中的相应部分。

英文:

The freezing issue you're experiencing seems to be related to the "Bad state: Future already completed" error in your Flutter app. This error typically occurs when you try to complete a Future that has already been completed.

Looking at your code, the issue seems to be happening in the playAudio function when you recursively call playAudio to play the next URL in the list. The problem arises because you're not properly canceling the previous audioPlayer.onPlayerComplete subscription before creating a new one. As a result, multiple subscriptions are created, leading to the error.

To fix this issue, you need to cancel the previous subscription using the cancel method before creating a new subscription. Here's an updated version of your code with the necessary modifications:

bool isPlaying = false;
AudioPlayer audioPlayer = AudioPlayer();
int currentIndex = 0;
int start = 0;
StreamSubscription&lt;void&gt;? playerCompleteSubscription; // Add this line
// ...
onPressed: () {
isPlaying = !isPlaying;
if (start == 0) {
start++;
playAudioInstructions();
} else if (start == 1) {
start++;
audioPlayer.pause();
} else {
start--;
audioPlayer.resume();
}
setState(() {});
},
// ...
void playAudioInstructions() {
playAudio(urlList, currentIndex);
}
Future&lt;void&gt; playAudio(List&lt;String&gt; urlList, int currentIndex) async {
await audioPlayer.play(UrlSource(urlList[currentIndex]));
playerCompleteSubscription?.cancel(); // Cancel previous subscription if exists
playerCompleteSubscription = audioPlayer.onPlayerComplete.listen((event) {
if (currentIndex &lt; urlList.length - 1) {
audioPlayer.stop();
currentIndex++;
playAudio(urlList, currentIndex);
} else {
currentIndex = 0;
audioPlayer.stop();
start = 0;
}
});
}

In the updated code, I added a StreamSubscription<void>? playerCompleteSubscription variable to keep track of the subscription for audioPlayer.onPlayerComplete events. Before creating a new subscription, I check if there is an existing subscription and cancel it using the cancel method.

By canceling the previous subscription, you ensure that only one subscription is active at a time, preventing the "Bad state: Future already completed" error and potential freezing of the app.

Make sure to replace the corresponding sections in your original code with the modified code provided above.

huangapple
  • 本文由 发表于 2023年7月3日 02:45:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/76600333.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定