Closed iosephmagno closed 5 months ago
Hi @iosephmagno Thank you for reporting this issue.
Looking at the example code you provide, you are setting the file content-type as media/mp4
, which is an invalid mime type. In your case, it should be video/mp4
. Please refer to the list of common file extension names and corresponding mime types.
In addition, what's the value of key
when you upload the video file? I would recommend you to keep the extension name .mp4
.
We also noticed that upload is pretty slow.
What's the size of the video file you were testing with?
My bad it is 'video/mp4' correcting it.
Here is values for key
, file
and content-type
.
Just noticed that in key we use extension but use add a subfolder inside filename.
Although we have no issue using this very config with images.
key: 'stories/3d8cd340-8d0d-469b-adad-bab48a3ec9f5/3d8cd340-8d0d-469b-adad-bab48a3ec9f51683907850186_media.MP4' file: '/private/var/mobile/Containers/Data/Application/34C45561-F9B6-4C71-B96C-C12CEFBAD471/tmp/.video/1683907858.mp4' mimeType: video/mp4
My bad it is 'video/mp4' correcting it.
Do you mean you used correct mime type string when upload the video file?
Just noticed that in key we use extension but use add a subfolder inside filename.
This should not have an impact on the mime type.
Could you provide example code for downloading the video and play in your video player?
Hi @HuiSF Yes we use correct mime type, code above is now correct.
We use BetterPlayer, all videos we load to S3 manually via AWS console play correctly, so it shouldn't be an issue with the player.
Videos play well inside web browser, which I think use a trick to get to play videos anyway (prolly in default 16/9 ratio).
To reproduce issue you should upload a video via amplify and then play it with flutter video_player (better_player is built on top of it, so they are the same).
I also check if any differences on AWS console between playing and non.playing file, but they are the same and I can see contentType properly assigned in the metadata panel. It is more like file gets corrupted, like it loses width/height/duration but mediaType is ok.
@HuiSF was just told it is a state issue, video is ok.
But is there a way to improve upload speed? I mean we find simple Dio to be faster and dont get why.
Thanks for the update, are you guys working together? I was confused for a second :D
To clarify again: playing the video uploaded to s3 is no long an issue correct?
But is there a way to improve upload speed?
I mean we find simple Dio to be faster and dont get why.
Did you use Dio to upload to the same S3 bucket? Could you try to quantify the meaning of "faster", e.g. faster by 2MB/s?
Hi @HuiSF was out travelling. Will revert soon. Thx!
Thanks for the update, are you guys working together? I was confused for a second :D
Yep :)
To clarify again: playing the video uploaded to s3 is no long an issue correct?
Yes. no issue with that.
But is there a way to improve upload speed?
- What's the size of the video file?
About 6-7MB each
- Are you in the region of your S3 bucket?
Us-east-1
- What's the uplink bandwidth of your testing network? Did the upload used all the bandwidth?
Bandwidth shouldn't be an issue. Testing with 70Mbps uplink.
I mean we find simple Dio to be faster and dont get why.
Did you use Dio to upload to the same S3 bucket? Could you try to quantify the meaning of "faster", e.g. faster by 2MB/s?
We are not in that detailed testing yet. That is just what was simply noticed by looking console logs in terms of secs in between prints.
Idk if this might be an hint, but we launch a few parallel uploads like that. Might it be an issue with concurrency?
await Future.wait([
//Upload media file
if (content['media_path'] != null)
() async {
mediaUrl = await uploadMedia(
localId: localId,
userId: userId,
mediaPath: content['media_path'],
);
}(),
...
//Upload thumbnail for media file
...
etc
Also, we are still using v 0.6.12, maybe we should upgrade and provide you details with that one?
As for v1.1.0, is there hope we can benefit of background upload anytime soon?. App is meant to let users upload UGC contents. It is a common practise from people to close the app as soon as they launch the upload and let it complete task in background. On iOS, that would crash upload if it is not completed within 7-10sec :-/ Thx for the precious support so far!
Also, we are still using v 0.6.12, maybe we should upgrade and provide you details with that one?
@delfme if you do not have any blockers to upgrading, I recommend you upgrade to at least 1.0.x. 1.1.0 will require flutter 3.10 as it use the new Dart 3 version.
See the v1 upgrade guide: https://docs.amplify.aws/lib/project-setup/upgrade-guide/q/platform/flutter/
If you are able to upgrade, please let me know if that resolves the issue.
@Jordan-Nelson @HuiSF thx for the kind guidance. We updraged to latest amplify and at first glance we see a noticeable improvement in upload speed (in the scale of secs on relative small files).
Questions:
1) with old version, uploadfile()
didnt perform an update file in the case file already existed on s3. Is that feature available on v1? We should change code to test and your answer would save us time
2) Will us see something similar to flutter_uploader / downloader anytime soon?
https://pub.dev/packages/files_uploader https://pub.dev/packages/flutter_downloader
With no background operation support, Amplify usage remains pretty limited in the social media / messaging app context.
Have a nice sunday!
Hi @delfme sorry for the delayed response.
- with old version, uploadfile() didnt perform an update file in the case file already existed on s3. Is that feature available on v1?
You meant if the file key already existed in your bucket, uploading to the same key would fail? I don't think that's the case in any version of Amplify; uploading to the same key should override the original file in the bucket.
If you want to check if the file key already exists in the buckets before starting upload, you can use the getProperties
API. If the API call returns normally, meaning the file key has a corresponding object in the bucket, then you can decide whether to continue uploading or not.
- Will us see something similar to flutter_uploader / downloader anytime soon?
We are looking into solutions of supporting background operations, thank you for your patience!
On iOS, that would crash upload if it is not completed within 7-10sec :-/
Before we provide full background operation support, if the file is larger than 5 MB, you can call .pause()
provided by the operation object when your app is entering the background to avoid long background processes crashing. And resume the operation when your app becomes active again.
Thx for the support!
As for point 2, .pause()
is not a real workaround in our specific case, which is similar to
Instagram. User would notice that app behaves weirdly coz while opening app he would still see the UI animation of the upload task going on (maybe after minutes or hrs passed by since he quit app). Also in that time, his content wouldnt be on the server / seen from others users.
But background operation shouldnt be too hard to add if inspired by some available code like the above mentioned plugins. Hope you guys can give this a P1 coz it is really a core feature. As of now, Amplify on iOS wont upload contents that takes more than 5sec if user quits app. Due to users’ known behaviour and slow internet that would occur many times.
PS: I wrote 5sec coz after uploading files to AWS, app still needs time to call api to upload a post
to our database.
@HuiSF @Jordan-Nelson Is AWS Amplify backed by lambda functions? Because we just noticed that slow upload occurs just for first upload. It is fast from second upload on. So we are guessing it might be a cold-start issue on AWS side. If that is the case, is there a way to improve performance?
Is AWS Amplify backed by lambda functions?
Not really, Amplify Flutter uses S3 SDK under the hood, which communicate with the service directly S3 service API.
Can it be a plugin thing? Would appreciate if you could test uploading same image a few times in a row to investigate on differences between first and subsequent uploads.
Might it be also that? https://docs.amplify.aws/lib/storage/transfer-acceleration/q/platform/flutter/#override-storage-resource
Im testing on iphone 13 pro ios 16.1 and differences are evident
Are you using transfer acceleration (It shouldn't matter anyways)? I've tested uploading a 60MB file for a few times, didn't notice a significant difference between the first upload and subsequent uploads...
How do you create the localFile
?
@HuiSF thx for the kind support. We just compress and upload image. From logs it looked like compression task was not the bottleneck, but will double check it.
Can you try uploading a 200-300KB image multiple times. Coz with a 60MB file the difference in time, if any, will be minimal. With a small file you might notice an idle time of 2-4sec on first upload (value is a bit random). The upload itself will be sub second.
Could you provide a minimal code example from your testing? @delfme
Only thing I can think of now, is very API calls from the underlying S3 sdk requires getting credentials by fetching current session, the very first API call may causes session refresh from Cognito, that may add some latency as refresh session requires a round trip of network request.
Could you provide a minimal code example from your testing? @delfme
Only thing I can think of now, is very API calls from the underlying S3 sdk requires getting credentials by fetching current session, the very first API call may causes session refresh from Cognito, that may add some latency as refresh session requires a round trip of network request.
Sorry for my belated answer I was out of office.
If there is a demo in the amplify package, I can give it a try. The test is just uploading small files in a row (200/300KB) so that issue will be evident.
But your idea above might be the real culprit. Because upload progress logs start after this delay, so it might truly be latency due to initial auth verification.
Is there a way to pre-authenticate user before upload method is invoked? That would be a valid workaround. By UI, we know when user picks up media file, so we might call a cognito refresh-session method by then.
@Jordan-Nelson @NikaHsn have you guys had a chance to work on this issue? Coz it is really impairing our app to the point we will be forced to dismiss the plugin.
To reproduce it, please use small size files. 64KB file: https://unsplash.com/photos/ijxWA9RHabI/download?ixid=M3wxMjA3fDF8MXxhbGx8MXx8fHx8fDJ8fDE2OTkwMDU2NDF8&force=true&w=640 490KB file: https://unsplash.com/photos/ijxWA9RHabI/download?ixid=M3wxMjA3fDF8MXxhbGx8MXx8fHx8fDJ8fDE2OTkwMDU2NDF8&force=true&w=1920
Will try to put up a demo app, but sample is simple. You just need an "Upload" button which will upload the file. Tap the button multiple times in a row and you will see the difference in the delay between first upload and subsequent uploads.
As mentioned, the first upload is very slow, like even a small file can take seconds.
It seems that issue depends on AWS backend. This is why I asked whether AWS Amplify were backed by lamba functions and being hit by cold start. If that is not the case, issue might be due to auth (as mentioned here https://github.com/aws-amplify/amplify-flutter/issues/3044#issuecomment-1583362653). But in any event, can you please assign this a P1? It might not be disruptive for apps dealing with uploading a few big files once in a while (where issue won't be even noticeable). But it is disruptive for all apps which upload many small-medium files frequently (like messaging / social media apps).
Making a sample app.
Sample app here: https://github.com/delfme/sample_demo_amplify/tree/main
amplify_configuration.dart
getDownloadUrl
inside storage.dart
1) Tap first button to download a fake image from web 2) Tap second button to upload image to AWS. Tap it multiple times to notice delay issue (first upload is usually slow) 3) Tap third button to download file from AWS. It looks like I cannot download file (noticed this just now coz currently in our app we are not using AWS Amplify to download files). Any idea about what the mistake might be? A working download would let us test delay also during file download.
Uploading file time can vary much due to initial delay that seems not related to variation of internet connectivity but to AWS backend (or maybe http client?). Coz the delay occurs only on the first upload.
Time elapsed to upload 3721ms **// ON FIRST UPLOAD**
Time elapsed to upload 1721ms // ON SUBSEQUENT UPLOADS
Error while trying to download file. It shoulnd't be due to access level permission coz we are using a public folder, might it be due to the fact that the url is from CloudFront
?
flutter: LOG: Error downloading file: StorageKeyNotFoundException {
flutter: "message": "Cannot find the item specified by the key and access level.",
flutter: "recoverySuggestion": "Ensure that correct object key is provided, and/or correct `StorageAccessLevel` and `targetIdentityId` are included in the options.",
flutter: "underlyingException": "NoSuchKey {\n}"
flutter: }
flutter: Time elapsed to download 992ms
flutter: Failed to download file example_file.jpg
@iosephmagno @delfme apologies for the delay.
@iosephmagno it sounds like the original issue may be resolved. Is that correct?
@delfme - Re: first upload being slower than subsequent uploads - As discussed, this is likely due to the additional requests to fetch credentials if the user does not have valid credentials. I think we discussed this in https://github.com/aws-amplify/amplify-flutter/issues/4083
Is there a way to pre-authenticate user before upload method is invoked?
Calling Amplify.Auth.fetchAuthSession()
will refresh credentials if they are expired. If you want to force them to be refreshed (even when they are not expired) you can call Amplify.Auth.fetchAuthSession(options: FetchAuthSessionOptions(forceRefresh: forceRefresh))
Thx Jordan we will try this one.
@Jordan-Nelson what is the token expiry time? I mean, after a force refresh, how long it will last? Can it be edited from AWS console?
My doubt is that issue occurs after a few minutes of inactivity, hence the culprit shouldnt be an expired token. I see Storage uses a custom http client, might it be it? Or, might it be the internal flow by which Storage obtains a signed url? Can you guys test more with our sample?
AWS credentials are short lived. They expire after 1 hour.
Can you share the network traffic for an initial upload as well as a subsequent upload as requested in https://github.com/aws-amplify/amplify-flutter/issues/4083?
Hello, Im out travelling. Can you filter again your network traffic to try to reproduce the issue? If I remind it well, we have shared our network traffic in subsequent issues opened after https://github.com/aws-amplify/amplify-flutter/issues/4083 Basically, the first call has a bigger delay. We also tried to upload with a different http client but we cannot make your snippet works https://github.com/aws-amplify/amplify-flutter/issues/4105#issuecomment-2053618071
@iosephmagno I had attempted to reproduce this when working with @delfme on #4083 and was unable to. @delfme shared network requests and the delay for the first request was due to requests for credentials.
If you are still facing this issue please share the network traffic for the initial and subsequent upload. Thanks.
I will do it. Meantime can you please share your network traffic here? https://github.com/aws-amplify/amplify-flutter/issues/3044#issuecomment-1792308900
@iosephmagno If you are still facing this issue please share the network traffic for the initial and subsequent upload. Thanks.
Thx @Jordan-Nelson, it seems that after adding below auth refresh, issue is gone.
Amplify.Auth.fetchAuthSession(options: FetchAuthSessionOptions(forceRefresh: true));
We can close this as of now and we will keep testing.
Thanks for the update @iosephmagno. I will close this issue then.
Description
Uploading a mp4 video with Amplify results in a corrupted remote video. Video uploads successfully but any video player says that it has no mime and plays it with wrong aspect ratio. We also noticed that upload is pretty slow.
Any help to fix this is much appreciated.
Categories
Steps to Reproduce
Upload a video with below code and play it. Video upload will be slow and video will play with wrong aspect ratio. Players report that video with without mime.
Screenshots
Original video on client, aspect ratio is 16 / 9, resolution 1920 x 1080
Corrupted video played from AWS S3 with wrong aspect ratio and size.
Platforms
Flutter Version
3.3.10
Amplify Flutter Version
0.6.12
Deployment Method
Amplify CLI
Schema
No response