downloading a large video with Dio download causes out of memory

558

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

Init flutter downloader

WidgetsFlutterBinding.ensureInitialized();
await FlutterDownloader.initialize(
  debug: true // optional: set false to disable printing logs to console
);

Handle isolates

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]);
}

Download the file

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)
);
Share:
558
keval
Author by

keval

Updated on December 31, 2022

Comments

  • keval
    keval over 1 year

    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

    • Rishabh Deep Singh
      Rishabh Deep Singh over 2 years
      Does this answer your question? Downloading large pdf files in a Flutter app
    • keval
      keval over 2 years
      tried that @RishabhDeepSingh wasn't able to store it in the path I want. Can you help me with that. Actually I am handling downloads for the first times.
    • Rishabh Deep Singh
      Rishabh Deep Singh over 2 years
      what is the size of the video you downloading?
    • Javad Zobeidi
      Javad Zobeidi over 2 years
      try to use Isolate
    • keval
      keval over 2 years
      it may be around 200mb to 1GB max.
    • keval
      keval over 2 years
      @MadMan The thing is I want to use the download progress and add it to a stream for a streambuilder to use it. Is it possible to add to a stream in the main isolate from the new isolate?
  • keval
    keval over 2 years
    Thanks. That is what I tried first. But it gave this error while building. app\src\main\java\io\flutter\plugins\GeneratedPluginRegistra‌​nt.java:20: error: package vn.hunghd.flutterdownloader does not exist flutterEngine.getPlugins().add(new vn.hunghd.flutterdownloader.FlutterDownloaderPlugin()); ^ So i move forward without using that.
  • Sajad Abdollahi
    Sajad Abdollahi over 2 years
    @keval I'm using it in a production project and it's fine, I think the error says that it's not completely imported to your project, try flutter clean and flutter pub get, it will be ok.
  • keval
    keval over 2 years
    I tried that but gives the same error. Can you tell me what version of the plugin are you using.
  • Sajad Abdollahi
    Sajad Abdollahi over 2 years
    I'm using last version. 1.6.1
  • keval
    keval over 2 years
    I am using the same. The readme mentions no additional configuration is required for android. Is there anything you did in the android part?
  • Sajad Abdollahi
    Sajad Abdollahi over 2 years
    i didn't change anything, have you tried testing it on a different device?
  • keval
    keval over 2 years
    I reinstalled flutter and it worked. but I am still stuck stackoverflow.com/questions/68778000/…