3

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

keval
  • 39
  • 1
  • 7

1 Answers1

0

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)
);
Sajad Abdollahi
  • 1,593
  • 1
  • 7
  • 19
  • Thanks. That is what I tried first. But it gave this error while building. app\src\main\java\io\flutter\plugins\GeneratedPluginRegistrant.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. – keval Aug 12 '21 at 20:20
  • @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. – Sajad Abdollahi Aug 12 '21 at 20:27
  • I tried that but gives the same error. Can you tell me what version of the plugin are you using. – keval Aug 13 '21 at 15:11
  • I'm using last version. 1.6.1 – Sajad Abdollahi Aug 13 '21 at 15:27
  • I am using the same. The readme mentions no additional configuration is required for android. Is there anything you did in the android part? – keval Aug 13 '21 at 15:52
  • i didn't change anything, have you tried testing it on a different device? – Sajad Abdollahi Aug 13 '21 at 21:14
  • I reinstalled flutter and it worked. but I am still stuck https://stackoverflow.com/questions/68778000/flutter-downloader-download-huge-video-to-application-directory-with-progress – keval Aug 13 '21 at 21:39
  • I have the same problem with flutter_downloader. I've reinstalled the flutter and nothing changed. Flutter 3.3.6 and downloader 1.8.4 – Hamed Hamedi Nov 01 '22 at 22:02