Neill Bowler
Neill Bowler

Reputation: 165

How to stream mp3 file with extra info after extension in just_audio

I am using just_audio in flutter to play audio files. All is lovely, except that just_audio uses the file-name extension to determine the file type. Therefore, if your URL does not end with the appropriate few characters, then you cannot play the file. From reading the issues on GitHub there appears to be a way to side-step this problem (#86 and #87) but I'm afraid I don't understand the answer.

Can some-one point me to an easy way to play such a URL?

Ways to replicate the issue:

  1. Download the example project from just_audio
  2. Replace one of the URIs with https://www.dropbox.com/s/egtn3aavqggpdj2/Bible_ResurrectionLife.mp3%3Fdl=1
  3. When you attempt to play the audio file, you should see the following error:
flutter: An error occured (-11800) The operation could not be completed
[VERBOSE-2:ui_dart_state.cc(177)] Unhandled Exception: PlatformException(-11800, The operation could not be completed, null, null)

Upvotes: 3

Views: 1369

Answers (1)

Ryan Heise
Ryan Heise

Reputation: 2786

The first GitHub issue you linked to doesn't apply in your case since it involves the detection of HLS or Dash streams specifically on Android. MP3 files on both iOS and Android are determined not by the file extension but by the HTTP headers.

In the case specifically of iOS's detection of the audio file content type, the file extension is only important when dealing with files. For URLs, it's the Content-Type HTTP header that iOS uses to determine the type of audio. iOS additionally has a requirement that the server must support byte range requests (see Apple's explanation).

It is likely that Dropbox is failing one of these requirements.

Two solutions come to mind:

  1. Host the MP3 file on a server that is capable of supporting the headers that iOS requires.

  2. You could try using just_audio's LockCachingAudioSource. This is intended to cache the audio while it's being simultaneously played and downloaded. Although you may not be interested in that feature, the way it is implemented is by inserting a proxy between the iOS media player and the server. The proxy is implemented in a way that supports byte-range requests, although it won't necessarily be able to fulfill a byte range request to the end of the file until the cache has completely downloaded the file. Since it's your mp3 file, you could try encoding the mp3 file in a way that is optimised for streaming so that iOS doesn't need to jump to the end of the file to find metadata. Since the implementation of LockCachingAudioSource is available as part of the open source project, you could also make your own version of it that takes out the caching part if you don't need it.

Upvotes: 2

Related Questions