just_audio
just_audio copied to clipboard
player is not working appropriately in web when try to play an mp3 file from signed url generated by AWS
Which API doesn't behave as documented, and how does it misbehave? The error is in play() after user setUrl().
the url is like:
var url="https://d2oogf3dio531h.cloudfront.net/65577d97-9969-4043-8bc4-5f6bb973e3a9.mp3?Policy=eyAKICAgIlN0YXRlbWVudCI6IFt7IAogICAgICAiUmVzb3VyY2UiOiJodHRwczovL2Qyb29nZjNkaW81MzFoLmNsb3VkZ291cmNlSXAiOFRpbWUiOjgzNTc5ODN9CiAgICAgIH0gCiAgIH1dIAp9&Signature=Jc1d~yaNIW5C3StRtQe-EZtZhGvAK-JGh1cDF~CrVYBjbJSpz-hmiPjZwGJjKEGaLCaOeFJjIYGE~B7P0dm8PLfjb6eydfebNfdp5OMdrFio2HnGRsjqVcPuCDOKtjezYu3isWtt0AY-Tim6TBYvG9kuG3pPZa5L32zD4aFwPTmmahZko~byCc0ZBQJbKCyG4AcKnevCd2LaGjNGloprw__&Key-Pair-Id=K35S9ERGS425ZB";
Minimal reproduction project
To Reproduce (i.e. user steps, not code)
Error messages
Error: (4) Failed to load URL
at Object.throw_ [as throw] (http://localhost:50415/dart_sdk.js:5391:11)
at just_audio.AudioPlayer.new._load (http://localhost:50415/packages/just_audio/just_audio.dart.lib.js:828:25)
at _load.throw (<anonymous>)
at http://localhost:50415/dart_sdk.js:42999:38
at _RootZone.runBinary (http://localhost:50415/dart_sdk.js:42854:58)
at _FutureListener.thenAwait.handleError (http://localhost:50415/dart_sdk.js:37430:33)
at handleError (http://localhost:50415/dart_sdk.js:38036:51)
at Function._propagateToListeners (http://localhost:50415/dart_sdk.js:38062:17)
at _Future.new.[_completeError] (http://localhost:50415/dart_sdk.js:37908:23)
at async._AsyncCallbackEntry.new.callback (http://localhost:50415/dart_sdk.js:37947:31)
at Object._microtaskLoop (http://localhost:50415/dart_sdk.js:43153:13)
at _startMicrotaskLoop (http://localhost:50415/dart_sdk.js:43159:13)
at http://localhost:50415/dart_sdk.js:38289:9
Expected behavior A clear and concise description of what you expected to happen.
Screenshots
Desktop (please complete the following information):
Smartphone (please complete the following information):
Flutter SDK version [✓] Flutter (Channel stable, 2.10.3, on macOS 12.0.1 21A559 darwin-x64, locale en-AE) [✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0) [✓] Xcode - develop for iOS and macOS (Xcode 13.1) [✓] Chrome - develop for the web [✓] Android Studio (version 2020.3) [✓] VS Code (version 1.65.2) [✓] Connected device (3 available) [✓] HTTP Host Availability Additional context Add any other context about the problem here.
When I open that URL in my web browser it also gives an error, so I would not expect to work through this plugin either.
the signed url remains valid for only few seconds to protect our mp3 files. this works fine in Android and IOS but the error is in the web
I can't test it if I only have a few seconds to access it. Why don't you supply a test URL that has a longer expiration date?
have you found solution?
no, I didn't complete this module in the web app
On Mon, Dec 19, 2022 at 9:45 AM paprikaparty33 @.***> wrote:
have you found solution?
— Reply to this email directly, view it on GitHub https://github.com/ryanheise/just_audio/issues/688#issuecomment-1357222887, or unsubscribe https://github.com/notifications/unsubscribe-auth/AK6CYRZTCTDKJID3NJKCEX3WOAHCJANCNFSM5RK66Y6Q . You are receiving this because you authored the thread.Message ID: @.***>
This is the real problem. I have same with aws, but not only aws itself, but any S3-like storage.
what does code 4 means atleast? @ryanheise
just_audio_web just passes on the error as is from the platform, in this case, from the browser, so you'll have to consult the browser documentation or Javascript documentation for what that error code means. The most popular cause of errors is incorrect server headers.
@ryanheise is there any caching behind setUrl? I see this error not for the first time I download some file, but after a while, when I trying to download it again using same link (because my backend generates different presigned urls, but for app it always the same url for same file
There shouldn't be any caching for setUrl
, but if you create an audio source instance e.g. via AudioSource.uri()
and you pass that same instance into setAudioSource
again, then yes there will be a sort of caching going on because you are in fact using the same instance. Feel free to take a look through the source code to understand what happens in your scenario, as it's all pure Dart.
The problem is that I always destroy player and always create new one
Can you elaborate on what way that is the problem? Do you mean that it works without recreating the player?
No, I mean that error described above occurs after some time, even if I create new AudioPlayer instance everytime. So its like: 1 get presigned url from server; 2 Create audioplayer; 3 use setUrl; 4 see it works fine; 5 destroy audioplayer; 6 repeat steps 1-5 after some time and few times; 7 get error on "setUrl" step, and after you get it once - you will get it all the time, even with other urls, which wasnt used before;
Oh, right now I noticed, that you mean AudioSource instance. But I do not use AudioSource, I simply use player.setUrl(urlString);
Also about reading code, when it came for web, I do not understand it very well, seems that load function (where error occurs) on web package, call some native code (js library?), and I do not know how to find this code, and I still do not understand what code 4 means in error.
What is the expiry date for your signed URL? Does it expire during the timespan we're talking about here?
@ryanheise Yes, it expires in 700 seconds.
For anyone who want to solve this problem - just add updating url argument. For example https://download.mp3?version=1
@Abo-ghazalla Just increment version before any request, and you will not have any problem with (4) Failed to load URL. At least it worked for me.
If the URL expires in the span you're talking about, why would appending a version query parameter cause it to "un"-expire?
In my case, setUrl uses my server url which looks like https://server.com/download?file=file
But inside server just create presigned url and return 301 redirect.
And there is no problem in expiration, because new presigned url generates every time for new request
Anyone found any reliable way or workaround? I have tried using url argument update but that didn't work. And once this error happens, it just keeps on happening even for all valid and accessible urls. My .mp3 files are also on AWS.
When you tried a URL argument update, I think there were other parts to that workaround besides just the argument, including a server redirect and so on.
Hmm, sounds like I may have to find another solution/workaround. :(
One other thing you can try is to download the file using http, and then play it in memory using a base64 URL. To avoid locking up the UI while encoding into base64, you could either do the encoding in a web worker or you could do it server side and just download the base64 encoded data to the web app.
Awesome, thanks. That can work, can get the file as base64 directly. Do I need to do any more conversion to use? I am trying to learn more about StreamAudioSource so I can use that. Do I need base64 into other format/encode to use StreamAudioSource?
It will be more efficient to bypass StreamAudioSource
if you already have the base64 encoded data. You would do this by constructing a data URL:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs