I have a Laravel project for API and a VueJS project for the front end. I need to upload large video files to the server. My first question is, what is the best way to upload large files to the server with minimum failure?
I have decided to upload the file in chunks and for this purpose, I have tried two different ways.
Using resumablejs:
this.r = new Resumable({
target:process.env.API_URL+'upload',
query:{upload_token:'my_token'},
headers:{
Authorization: 'Bearer '
},
maxChunkRetries: 1,
simultaneousUploads: 1,
testChunks: false,
});
// Resumable.js isn't supported, fall back on a different method
if(!this.r.support) return alert('Your browser doesn't support chunked uploads. Get a better browser.');
this.r.assignBrowse(this.$refs.videodropzone);
this.r.assignDrop(this.$refs.videodropzone);
// set up event listeners to feed into vues reactivity
this.r.on('fileAdded', (file, event) => {
file.hasUploaded = false
console.log('this.files', this.files)
// keep a list of files with some extra data that we can use as props
this.files.push({
file,
status: 'uploading',
progress: 0
})
this.r.upload()
})
this.r.on('fileSuccess', (file, event) => {
this.findFile(file).status = 'success'
})
this.r.on('fileError', (file, event) => {
this.findFile(file).status = 'error'
})
this.r.on('fileRetry', (file, event) => {
this.findFile(file).status = 'retrying'
})
this.r.on('fileProgress', (file) => {
// console.log('fileProgress', progress)
const localFile = this.findFile(file)
// if we are doing multiple chunks we may get a lower progress number if one chunk response comes back early
const progress = file.progress()
if( progress > localFile.progress)
localFile.progress = progress
})
Creating manual chunk:
upload() {
const url = 'upload'
this.$axios.post(url, this.formData).then(() => {
this.chunks.shift()
}).catch((error) => {
})
},
createChunks() {
let size = 1024 * 1000, chunks = Math.ceil(this.file.size / size)
for (let i = 0; i < chunks; i++) {
this.chunks.push(this.file.slice(
i * size, Math.min(i * size + size, this.file.size), this.file.type
))
}
}
Both codes give me the same output in the backend. The next part is to append the chunk files into one final file. For this, I have written the following code in Laravel-
public function upload(Request $request)
{
$file = $request->file('file');
Storage::disk('local')->append('output/' . $file->getClientOriginalName(), $file->get());
}
Now, here is my problem. I can upload large files using the code above. But the output is not right I think although the output and input file size is the same. The output video file is not playable. It plays first few seconds then it stops. I think only the first chunk is playable. I have tested with a 10MB video file.
Then I have tested with a 10MB pdf file, after uploading the pdf file, I can open the output file and the output is ok. But for the video file, I cannot play the whole video. What is the problem here?