I am trying to make a flutter app with downloading videos functionality from a url and videos are expected to be large (1 to 2 hours of 720p atleast).
I used Dio for this but it tries to store the complete video in RAM which causes the out of memory error. This is the code I used.
Any workarounds? or better solutions?
Dio dio = Dio();
dio
.download(
url,
filePathAndName,
onReceiveProgress: (count, total) {
progressStream.add(count / total);
},
)
.asStream()
.listen((event) {
})
.onDone(() {
Fluttertoast.showToast(msg: "Video downloaded");
});
After a while it gives this exception : java.lang.OutOfMemoryError
Since it's a large file, I think it would be better to download your file using flutter_downloader plugin which also supports notifications and background mode
WidgetsFlutterBinding.ensureInitialized();
await FlutterDownloader.initialize(
debug: true // optional: set false to disable printing logs to console
);
Important note: your UI is rendered in the main isolate, while download events come from a background isolate (in other words, codes in callback are run in the background isolate), so you have to handle the communication between two isolates. For example:
ReceivePort _port = ReceivePort();
@override
void initState() {
super.initState();
IsolateNameServer.registerPortWithName(_port.sendPort, 'downloader_send_port');
_port.listen((dynamic data) {
String id = data[0];
DownloadTaskStatus status = data[1];
int progress = data[2];
setState((){ });
});
FlutterDownloader.registerCallback(downloadCallback);
}
@override
void dispose() {
IsolateNameServer.removePortNameMapping('downloader_send_port');
super.dispose();
}
static void downloadCallback(String id, DownloadTaskStatus status, int progress) {
final SendPort send = IsolateNameServer.lookupPortByName('downloader_send_port');
send.send([id, status, progress]);
}
final taskId = await FlutterDownloader.enqueue(
url: 'your download link',
savedDir: 'the path of directory where you want to save downloaded files',
showNotification: true, // show download progress in status bar (for Android)
openFileFromNotification: true, // click on notification to open downloaded file (for Android)
);