Introduction to the

Audioplayers is a library for Flutter that supports simultaneous playback of multiple audio files. Usage is also fairly simple:

 AudioPlayer audioPlayer = new AudioPlayer();
 await audioPlayer.play(url);

 //or
 //await audioPlayer.play(localPath, isLocal: true);
 
 
 // Some control API
 await audioPlayer.pause();
 await audioPlayer.stop();
 await audioPlayer.resume();
Copy the code

How to Crash an Application (Android)

AudioPlayer audioPlayer = new AudioPlayer();
await audioPlayer.play(localPath, isLocal: true);

// Immediately after playing, call pause, bottom throws' PlatformException 'exception, program crash
await audioPlayer.pause();

Copy the code

Well, it’s as simple as that, and you haven’t written more than 10 lines of code.

The analysis reason

After the crash, I looked at the code of AudioPlayers and the documentation again with curiosity. Audioplayer. setUrl (audioplayer. setUrl); resume (audioplayer. setUrl);

Well, I didn’t see it at the time, and it was a blessing in disguise, but there are also problems with that realization. Android MediaPlayer State Diagram

Whether audioPlayer.play or andioplayer. setUrl, their most important job is to call Android’s native prepareAsync method and make the MediaPlayer object Prepared. To quote the official Android documentation:

A MediaPlayer object must first enter the Prepared state before playback can be started.

. or a call to prepareAsync() (asynchronous) which first transfers the object to the Preparing state after the call returns (which occurs almost right away) while the internal player engine continues working on the rest of preparation work until the preparation work completes. When the preparation completes or when prepare() call returns, the internal player engine then calls a user supplied callback method ……

To sum up, there are two points:

  1. Play/pause and other operations must enterPreparedstate
  2. prepareAsyncIs an asynchronous operation that causesMediaPlayerEnter thepreparingState, when the bottomplayer enginecompletepreparationThe user-supplied callback function will be invoked.

Preparing state MediaPlayer is a preparing state after the audioPlayer.play call, and a PlatformException is raised when pause is called. Future like Play and setUrl should not resolve only in perparing state, but should wait until prepared.

So… I went backhand to Audioplayers Github to put forward an issue, hiding the merit and name.

The end of the

Audioplayers also supports SoundPool(new AudioPlayer(mode: playermode.low_latency)) on Android, which has the same problem.

Presumably ios will have the same problem.

Write more messy and simple, I hope to help people who encounter the same problem.