Open Xotonori opened 1 year ago
Did you found any solution for this? I am also facing the exact same issue.
Unfortunatly no =(
I cannot confirm this issue.
I can successfully upload a 500 MB video file with tus-js-client
3.0.1
to my own TUS server implementation, with both Firefox and Chrome on Android 11 (LineageOS on a Google Pixel 1).
Separate: In your code:
const uploader = new tus.Upload(file, {
//...
chunkSize,
It looks like here you're passing the large file's full size as chunkSize
.
According to chunkSize
docs this will pull the whole file into RAM:
A large chunk size (more than a GB) is problematic when a reader/readable stream is used as the input file. In these cases, tus-js-client will create an in-memory buffer with the size of
chunkSize
On Android devices you usually don't have a lot of RAM, so this might be problematic.
When attempting to upload a large file on iOS, the app's memory usage rapidly increases to 2GB and subsequently causes the app to crash.
@H4mxa Are you using React Native on iOS? Or are you using it in the browser? Because the original question was using React Native.
I am also facing the same issue with React-Native and I am using expo-image-picker to select a video.
LOG {"assetId": "33737", "base64": null, "duration": 180032, "exif": null, "fileName": "77541d9f-259a-4fde-8e3b-a5d98d940223.mp4", "filesize": 451514586, "height": 1080, "mimeType": "video/mp4", "rotation": 90, "type": "video", "uri": "file:///data/user/0/host.exp.exponent/cache/ExperienceData/%2540anonymous%252FnativeChunking-94c8fbbb-5bd2-4a23-be0e-a8c6ef78365f/ImagePicker/4c885de7-a3c5-4759-8156-b8ade72214e7.mp4", "width": 1920}
LOG Failed because: Error: tus: cannot fetch `file.uri` as Blob, make sure the uri is correrrrect and accessible. [object Object]
I am getting this error when file size is around 400MB
My first thought is that this could be an memory issue. When a file URI in React Native is passed to tus-js-client, we attempt to load the entire file into a blob in memory:
It is quite possible that this operation is not possible for larger file sizes as it would exhaust the available memory. We should investigate whether it is possible to only load parts of the file into memory and then tus-js-client can use its chunking logic to divide the file into multiple, smaller chunks.
I think @Acconut is right. I saw in some place about a fetch()
limitation on Android but I didn't find it to link.
Maybe a custom FileReader using expo-file-system
and react-native-quick-base64
can solve the issue. Something like:
export default class TusFileReader {
async openFile(input, chunkSize): {
const fileInfo = await FileSystem.getInfoAsync(input.uri);
if (fileInfo.exists) {
return new FileSource(input, fileInfo.size);
}
}
}
class FileSource {
private _file;
private _size;
get size(): number {
return this._size;
}
constructor(file, size) {
this._file = file;
this._size = size;
}
async slice(start, end) {
if (start >= this._size) {
return { value: new Uint8Array(0), done: true };
}
end = Math.min(end, this._size);
const length = end - start;
const data = await FileSystem.readAsStringAsync(this._file.uri, {
encoding: FileSystem.EncodingType.Base64,
length: length,
position: start,
});
const value = toByteArray(data);
return { value, done: false };
}
}
@wfern Thank you for the suggestion. Something like you suggested will likely help here. Do you have an opinion on what is the best way to access files that works well with React Native and Expo? You mentioned expo-file-system
, but react-native-fs
also has method for reading files at offsets: https://github.com/itinance/react-native-fs?tab=readme-ov-file#readfilepath-string-length--0-position--0-encodingoroptions-any-promisestring. I am no React Native developer and thus I am wondering that the preferred approach for file access currently is.
@Acconut This is debatable because there is no preferred way. Most people should use expo nowadays but there are still many cases of people not using it and not liking using expo libraries because of the extra setup (even though it is minimal).
A good option would be to leave it as it is because:
Document the possible limitation and add a snippet with that code on how to create FileReader for RN and mention that it is also possible to do it with "react-native-fs".
This would work for me because first I would test it the way it is today (no extra setup or libraries, just works™) and if it didn't work I would add FileReader based on this documentation snippet.
tus-js-client doesn't upload file larger than 100Mb for Android. I've got next error - "Failed to upload because: Error: tus: cannot fetch file.uri as Blob, make sure the uri is correct and accessible. [object Object]"
I get video file data by "react-native-document-picker" library.
Than i get data like:
Than i push assets to tus upload component and get presight params:
And when uploading started, I get this error - "Failed to upload because: Error: tus: cannot fetch file.uri as Blob, make sure the uri is correct and accessible. [object Object]"
Files lower than 100Mb uploading very well, but larger don't( This problem only for an Android, IOS is ok.