Laravel Chunk Upload пропускает один фрагмент

Я использую laravel-chuck-upload в сочетании с dropzone.js. Все работает нормально, чанки загружаются, и когда они будут загружены, окончательный файл будет сохранен в S3. Проблема в том, что 1 чанка всегда не хватает. Иногда отсутствует .8.part, иногда отсутствует .7.part (они остаются в каталоге чанков после загрузки). Когда я загружаю видео общим размером 9,7 МБ, размер файла в S3 составляет 8,7 МБ. То есть отсутствует 1 МБ, того же размера, что и недостающая часть. Все фрагменты имеют размер 1 МБ.

В чем может быть проблема и как я могу это исправить?

Изменить: я думаю, что нашел проблему, но не исправление. Когда загружается последний фрагмент (10-й), он думает, что все фрагменты загружены, но 8-й фрагмент еще не завершен.


person Bart Bergmans    schedule 01.04.2020    source источник


Ответы (1)


Дополнил DropZoneUploadHandler моим собственным методом isLastChunk. Таким образом, файл загружается, когда это действительно последний фрагмент. Единственная проблема заключается в том, что dropzone.js запускает событие chunksUploaded для последнего вызова чанка, а не для последнего завершенного чанка.

public function isLastChunk()
{
    $chunkFileName = preg_replace(
        "/\.[\d]+\.".ChunkStorage::CHUNK_EXTENSION.'$/', '', $this->getChunkFileName()
    );

    $files = ChunkStorage::storage()->files(function ($file) use ($chunkFileName) {
        return false === Str::contains($file, $chunkFileName);
    });

    return (count($files) + 1) == $this->getTotalChunks();
}

Чтобы решить эту проблему, я добавил функцию chunkUploaded в dropzone.js, чтобы получать ответ на каждую загрузку фрагмента. Теперь я могу делать все, как раньше, но с файлом, в котором есть все куски.

Я добавил в dropzone.js следующее:

/**
 * The callback that will be invoked when a single chunk has been uploaded for a file.
 * It gets the file for which the chunks have been uploaded as the first parameter,
 * and the `done` function as second. `done()` needs to be invoked when everything
 * needed to finish the upload process is done.
 */
chunkUploaded: function chunkUploaded(file, response, statuscode, done) {
    done();
},
xhr.onreadystatechange = function () {
    if(this.readyState == 4) {
        _this16.options.chunkUploaded(file, this.responseText, this.status, function () {
            _this16._finished(files, '', null);
        });
    }
};
person Bart Bergmans    schedule 01.04.2020