Laravel Загрузка чанка, пропуская один чанк - PullRequest
2 голосов
/ 01 апреля 2020

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

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

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

1 Ответ

0 голосов
/ 01 апреля 2020

Расширен 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);
        });
    }
};
...