question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Read large files from the filesystem

See original GitHub issue

My app must be able to download images/video/audio for offline-perusal, on both iOS and Android. Pending #984, I have used cordova-plugin-file and cordova-promise-fs to store a downloaded blob to the filesystem, which is working nicely.

However, on both iOS and Android, whatever I try I cannot play a local video!

Using .toInternalURL()

<video src="cdvfile://localhost/persistent/data/user/0/com.example.app/cache/video.mp4"></video>

Throws error:

Mixed Content: The page at 'https://localhost:5174/' was loaded over HTTPS, but requested an insecure video 'cdvfile://localhost/persistent/data/user/0/com.example.app/cache/video.mp4'. This request has been blocked; the content must be served over HTTPS.

So cdvfile: is considered an insecure protocol.

Using .toURL()

<video src="file:///data/user/0/com.example.app/files/files/data/user/0/com.example.app/cache/video.mp4"></video>

Throws error:

Not allowed to load local resource: file:///data/user/0/com.example.app/files/files/data/user/0/com.example.app/cache/video.mp4

I realise it’s a weird looking path, but that’s what I get from .toURL(), and I don’t think that’s really the problem here.

Both the above examples behaved very similarly on my iOS simulator so I will not bother to post that error log here.

Failed approaches

Content-Security-Policy

I have tried tweaking the Content-Security-Policy meta tag to include the cdvfile: protocol, but according to this post you can only tighten security using that, not loosen it.

Potential solutions

Capacitor support for <access origin="cdvfile://*"/>

It appears Cordova may have a workaround for this issue, perhaps the functionality could be duplicated in capacitor.config.js? However Cordova’s solution might be outdated.

Read as data URL

I can read the video as a Base64 string using fs.toDataURL() and then supply a data: URL to my <video> element. This works fine on iOS and Android for small videos, but it will break for larger videos as browsers generally set a maximum size for strings (apparently ~256MB), and also loads the whole video into memory which is a big no-no.

Tweak Swift/Java

According to this, there is a way to allow mixed content on an Android WebView, perhaps there is also a way to get it working on iOS?

Use native video player

The VideoPlayer plugin can play local videos using an Android’s native player. I’d like to avoid this as I’m trying to keep compatibility with iOS and the browser.

Streams

If Capacitor’s FileSystem plugin could return a ReadableStream of the file, I’m sure a solution could be found. To avoid holding the entire file in memory at once, it could be piped into successive blobs, then stitched together into a larger blob and then turned into a playable URL using URL.createObjectURL(). Chrome at least will write blobs to disk if memory pressure gets too high.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:3
  • Comments:18 (12 by maintainers)

github_iconTop GitHub Comments

5reactions
diachedeliccommented, May 19, 2021

@saas786

Capacitor seems to provide as must storage space as the device can provide. But I could be wrong about that. I am using Capacitor v2.

To download a video to the filesystem, I use this plugin: https://github.com/diachedelic/capacitor-blob-writer/.

To play back a video from the filesystem, I do something like the following:

const { uri } = await Filesystem.stat({directory, path});
const video_element = document.createElement("video");
video_element.src = Capacitor.convertFileSrc(uri);
4reactions
guylandocommented, Mar 3, 2019

I submitted a PR to the file plugin which solves the mixed content problem on ios: https://github.com/apache/cordova-plugin-file/pull/296 The fixed version is available at: https://github.com/guylando/cordova-plugin-file If you load a remote site https://xxx.com on the webview then it allows to access local files using the url: https://xxx.com/cdvfile/bundle/www/cordova.js instead of cdvfile://localhost/bundle/www/cordova.js And by this solves the mixed content problems.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Working With Large Files in Linux - Baeldung
Learn some common problems and explore tools that help when partially processing huge files.
Read more >
How to Process Large Files with Node.js - Fusebit
Step 3: Reading the File. The fs module has a createReadStream() function that lets you read a file from the filesystem and print...
Read more >
How to read large files with fs.read and a buffer in javascript?
There are a number of different ways to solve this: Use fs.createReadStream() and read the file by listening for the data event.
Read more >
How To Find Large Files on Linux | Tom's Hardware
Searching the Whole Linux Filesystem For Large Files · 1. Open a terminal. · 2. Search the current filesystem for files larger than...
Read more >
Using Node.js to Read Really, Really Large Datasets & Files ...
js: fs (file system), readline , and stream . These imports allowed me to then create an instream and outstream and then the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found