Closed gbrits closed 3 years ago
I made these changes:
const blob = this.videoBlob;
console.log('NAME: ', blob.name);
console.log('SIZE: ', blob.size);
console.log('TYPE: ', blob.type);
if(blob.name && blob.size && blob.type) {
const uploader = new Upload(blob, {
endpoint: url,
retryDelays: [0, 1000, 2000, 4000, 8000],
headers: {
Authorization: 'Bearer ' + parsed_token.access_token,
},
chunkSize: 1024,
addRequestId: true,
overridePatchMethod: true,
metadata: {
name: blob.name,
type: blob.type
},
uploadSize: blob.size,
uploadLengthDeferred: true,
onError: function(error) {
console.log("Failed because: " + error)
this.loading?.dismiss();
},
onProgress: function(bytesUploaded, bytesTotal) {
var percentage = (bytesUploaded / bytesTotal * 100).toFixed(2)
console.log(bytesUploaded, bytesTotal, percentage + "%")
},
onSuccess: function() {
this.loading?.dismiss();
}
});
And now I finally have an error... but that's hard to debug too, seems to be related to my metadata which I've made sure both are not null... so maybe a backend issue?
Argument 2 passed to TusPhp\File::setMeta() must be of the type int, null given, called in /home/forge/privateurl.com.au/vendor/ankitpokhrel/tus-php/src/Tus/Server.php on line 643
{"userId":2,"exception":"[object] (TypeError(code: 0): Argument 2 passed to TusPhp\\File::setMeta() must be of the type int, null given,
called in /home/forge/privateurl.com.au/vendor/ankitpokhrel/tus-php/src/Tus/Server.php on line 643 at /home/forge/privateurl.com.au/vendor/ankitpokhrel/tus-php/src/File.php:74)
I put a catch on the route to see if anything is being posted and the response is empty, is this normal?
Route::any('/tus/{any?}', function (Request $request) {
Log::debug(print_r($request->all(), true));
$resp = app('tus-server')->serve();
$resp->send();
exit(0);
})->where('any', '.*');
As seen here:
[2021-02-23 00:46:44] local.DEBUG: Array
(
)
[2021-02-23 00:46:44] local.INFO: Are we uploading?
[2021-02-23 00:46:44] local.ERROR: Argument 2 passed to TusPhp\File::setMeta() must be of the type int, null given, called in /home/forge/privateurl.com.au/vendor/ankitpokhrel/tus-php/src/Tus/Server.php on line 643 {"userId":2,"exception":"[object] (TypeError(code: 0): Argument 2 passed to TusPhp\\File::setMeta() must be of the type int, null given, called in /home/forge/privateurl.com.au/vendor/ankitpokhrel/tus-php/src/Tus/Server.php on line 643 at /home/forge/privateurl.com.au/vendor/ankitpokhrel/tus-php/src/File.php:74)
When I remove my authorisation header I get a different error:
[log] - Failed because: Error: tus: failed to resume upload, caused by [object XMLHttpRequestProgressEvent], originated from request (method: HEAD, url: https://privateurl.com.au/auth/api/tus, response code: n/a, response text: n/a, request id: n/a)
If I remove the uploadUrl & just leave endpoint, the deeper culprit shows up as:
tus: failed to create upload, caused by [object XMLHttpRequestProgressEvent]
Tried implementing middleware as your README prescribes - local.ERROR: Undefined property: App\Http\Middleware\TusPass::$user
Are these supposed to be empty?
[2021-02-23 03:51:29] local.INFO: TusPhp\Request Object
(
[request:protected] => Symfony\Component\HttpFoundation\Request Object
(
[attributes] => Symfony\Component\HttpFoundation\ParameterBag Object
(
[parameters:protected] => Array
(
)
)
[request] => Symfony\Component\HttpFoundation\ParameterBag Object
(
[parameters:protected] => Array
(
)
)
[query] => Symfony\Component\HttpFoundation\InputBag Object
(
[parameters:protected] => Array
(
)
)
I've drawn the conclusion that my frontend is still not sending the upload data correctly, due to using Ionic / Capacitor / FileEntry File type etc.
In case some good Samaritan comes across this post, my frontend (Ionic / Capacitor) flow is as follows:
async submitAudit() {
const options: VideoCapturePlusOptions = { limit: 1, highquality: true }
this.recording = true;
this.videoCapturePlus.captureVideo(options).then(
async (mediaSheet: MediaFile[]) => {
let media = mediaSheet[0];
console.log('Media Sheet', media);
let resolvedPath: DirectoryEntry;
let path = media.fullPath.substring(0, media.fullPath.lastIndexOf("/"));
if (Capacitor.getPlatform() === "ios") {
resolvedPath = await this.file.resolveDirectoryUrl("file://" + path);
} else {
resolvedPath = await this.file.resolveDirectoryUrl(path);
}
this.selectedVideo = resolvedPath;
console.log('Providing to Filesystem - PATH: ',this.selectedVideo);
const contents = await Filesystem.readFile({ path: this.selectedVideo.nativeURL + media.name });
const base64Response = await fetch(`data:video/quicktime;base64,${contents.data}`);
const blob = await base64Response.blob();
this.videoBlob = blob;
this.uploadTus(this.selectedVideo);
},
(error) => console.log('Error', error)
);
}
And my uploading function is
async uploadTus(webPath: string): Promise<void> {
if(!this.loading) {
this.loading = await this.loadingCtrl.create({
message: 'Uploading...'
});
await this.loading.present();
}
const token = await Storage.get({ key: 'private_user_token' });
const parsed_token = JSON.parse(token.value);
const filename = nanoid(10);
const url = 'https://privateurl.com.au/auth/api/tus';
const blob = this.videoBlob;
if(blob.size && blob.type) {
const uploader = new Upload(
blob,
{
endpoint: url,
retryDelays: [0, 1000, 2000],
metadata: {
name: `${filename}.mov`,
type: blob.type,
access_token: `${parsed_token.access_token}`
},
headers: {
'Authorization': `Bearer ${parsed_token.access_token}`
},
onError: function(error) {
console.log("Failed because: " + error)
this.loading?.dismiss();
},
onProgress: function(bytesUploaded, bytesTotal) {
var percentage = (bytesUploaded / bytesTotal * 100).toFixed(2)
console.log(bytesUploaded, bytesTotal, percentage + "%")
},
onSuccess: function() {
this.loading?.dismiss();
}
});
uploader.start();
}
}
And my understanding of things is pretty rudimentary, but I think it's a warning sign that both the InputBag & the ParameterBag is empty on Laravel's end, via the middleware
Stuck here now:
[log] - Failed because: Error: tus: failed to create upload, caused by [object XMLHttpRequestProgressEvent], originated from request (method: POST, url: https://privateurl.com.au/files, response code: n/a, response text: n/a, request id: n/a)
In the end I decided to use AWS SDK, skipped PHP & chunking altogether and just upload directly to Mr Bezos' cloud, 1GB limit uploads & all :) Hopefully someone will benefit from my random scrawls.
@gbrits I think It would make it easier to isolate the problem first whether it lies on frontend or server side.
I would also suggest to try to use other alternative client to ensure that tus-php server was configured fine.
From the PHP error log it definitely looks like data is not being passed to it correctly.
Remove uploadLengthDeferred: true, it should work
I have been working on using this library for the last four hours and I can't seem to get past this point. I have alternated between using Blobs and now I'm using the FileEntry File object as prescribed in your documentation. My client is the
tus-js-client
official.My code is as follows for the client side:
Prior to uploading, I retrieve the File object like so:
Finally... my Laravel serverside is:
So XCode just hangs on this:
And my Laravel log file just shows:
But there's never any finalisation / update / response / error etc. That's where it all just stops. If anyone can help I'd be extremely grateful.