I have a Flutter app having size around 850 MB (AAB). Most of these 850MB are assets- video files (750 MB). The solution to publish it in the Google Play Store is to use deferred components (or to use private server to download video files after installation- I don't want to do this at this stage).
The problem is I found very little information about it. Here: https://docs.flutter.dev/perf/deferred-components, and here: https://github.com/flutter/flutter/wiki/Deferred-Components. And few questions on stackoverflow, most unanswered.
So, my questions:
1. If I understand correctly, each component must be less than 150 MB? As I wrote, the video files are 750 MB and there are 1150 of them. So, I need to create 5 or 6 components?
Now my pubspec.yaml looks like:
pubspec.yaml
assets:
- assets/
- assets/db/
- assets/media/
- assets/media/video/
- assets/pics/
- assets/pics/avatars/
So, I should remove this line:
- assets/media/video/
and add:
flutter:
...
deferred-components:
- name: videoComponent1
libraries:
- package:MyAppName/video1.dart
assets:
- assets/media/video/video1.mp4
- assets/media/video/video2.mp4
...
- assets/media/video/video100.mp4
...
- name: videoComponent5
libraries:
- package:MyAppName/video5.dart
assets:
- assets/media/video/video1000.mp4
- assets/media/video/video1001.mp4
...
- assets/media/video/video1150.mp4
This method is a bit time consuming. I know I can use wildcard directories:
assets:
- assets/media/video/video1/
But then I have to handle it in my video player widget (i am using video_player plugin). I can put files in alphabetical order. For example, I will put video files with a name starting with letter "A" in a video1 package, "B" in a video2 etc. And then:
if(fileName.substring(0,1)=='a') {
filePath = 'assets/media/video/video1/$fileName';
} else if...
But this is also a tedious method. Any other ideas? (I can't rename files in the database- it's an official external source, files and base are updated from time to time).
2. There are assets-only components. They can be defined by omitting the "libraries" section. It's clear. But how to use these components? Documentation says: These assets-only components must be installed with the DeferredComponent utility class in services rather than loadLibrary(). There is also loadLibrary method. How to use it all together? Something like this?
import 'package:flutter/services.dart';
var component = DeferredComponent.installDeferredComponent(componentName : video1);
How to show users the component download process is still in progress?
Assets-only components documentation is a bit lacking (in my opinion). I assume that the first step of the documentation is necessary. But what does step two look like?
What would i like to achieve?
Download all video files during the first app run (e.g on the onboarding screen) and use them in all my widgets in the same way as any other local asset. (that's exactly what is in the installDeferredComponent method documentation: Assets installed by this method may be accessed in the same way as any other local asset by providing a string path to the asset).
Results (added 06.03.22)
I did everything in accordance with the documentation, I generated an aab file without errors. I used the installDeferredComponent method as follows:
loadDeferredComponents() async {
await DeferredComponent.installDeferredComponent(
componentName: 'videoComponent1');
await DeferredComponent.installDeferredComponent(
componentName: 'videoComponent2');
await DeferredComponent.installDeferredComponent(
componentName: 'videoComponent3');
...
}
But when i try to upload it to Google Play i keep getting the message: One or more of the auto-generated multi-APKs exceeds the maximum allowed size of 150 MB.
I think I will give up the deferred components. I don't really know what I'm doing wrong.