Search code examples
phplaravellaravel-8dropzone.jsvideo-upload

Invalid file Uploading a video using Spatie Medialibrary and Dropzone


Please I want to add a feature for Video upload using Spatie Medialibrary but I keep getting this error.

{
  "message": "The given data was invalid.",
  "errors": {
    "file": [
      "The file failed to upload."
    ]
  }
}

While the error message sounds simple to understand I have tried to figure out the problem for over 48 hours. Does it mean that Spatie Medialibrary can't be used for video upload? Below is what I have tried

<!-- Video Field -->
<div class="form-group align-items-start d-flex flex-column flex-md-row">
    {!! Form::label('video', trans("lang.e_service_video"), ['class' => 'col-md-3 control-label text-md-right mx-1']) !!}
    <div class="col-md-9">
        <div style="width: 100%" class="dropzone video" id="video" data-field="video">
        </div>
        <a href="#loadMediaModal" data-dropzone="video" data-toggle="modal" data-target="#mediaModal" class="btn btn-outline-{{setting('theme_color','primary')}} btn-sm float-right mt-1">{{ trans('lang.media_select')}}</a>
        <div class="form-text text-muted w-50">
            {{ trans("lang.e_service_video_help") }}
        </div>
    </div>
</div>
@prepend('scripts')
    <script type="text/javascript">
        var dz_var16110647911349350349ble = $(".dropzone.video").dropzone({
            url: "{!!url('uploads/store')!!}",
            addRemoveLinks: true,
            maxFiles: 1,
            maxFilesize: 500,
            acceptedFiles: 'video/*',
            init: function () {
                @if(isset($eService) && $eService->hasMedia('video'))
                var media = {
                    name: "{!! $eService->getFirstMedia('video')->name !!}",
                    size: "{!! $eService->getFirstMedia('video')->size !!}",
                    type: "{!! $eService->getFirstMedia('video')->mime_type !!}",
                    uuid: "{!! $eService->getFirstMedia('video')->getCustomProperty('uuid'); !!}",
                    thumb: "{!! $eService->getFirstMedia('video')->getUrl('thumb'); !!}",
                    collection_name: "{!! $eService->getFirstMedia('video')->collection_name !!}"
                };
                dzInit(this, media, media.thumb);
                @endif
            },
            accept: function (file, done) {
                dzAccept(file, done, this.element, "{!!config('medialibrary.icons_folder')!!}");
            },
            sending: function (file, xhr, formData) {
                dzSending(this, file, formData, '{!! csrf_token() !!}');
            },
            complete: function (file) {
                dzComplete(this, file);
                dz_var16110647911349350349ble[0].mockFile = file;
                
            },
            removedfile: function (file) {
                dzRemoveFile(
                    file, dz_var16110647911349350349ble, '{!! url("eServices/remove-media") !!}',
                    'video', '{!! isset($eService) ? $eService->id : 0 !!}', '{!! url("uploads/clear") !!}', '{!! csrf_token() !!}'
                );
            }
        });

         dz_var16110647911349350349ble[0].mockFile = [];
        dropzoneFields['video'] = dz_var16110647911349350349ble;

    </script>
@endprepend

Below is my Controller code

public function store(CreateEServiceRequest $request)
{
    $input = $request->all();
    
    try {
        $eService = $this->eServiceRepository->create($input);

        if (isset($input['video']) && $input['video']) {
            $fileUuid = $input['video'];
            $cacheUpload = $this->uploadRepository->getByUuid($fileUuid);
            $mediaItem = $cacheUpload->getMedia('video')->first();
            $mediaItem->copy($eService, 'video');
        }
    } catch (ValidatorException $e) {
        Flash::error($e->getMessage());
    }

    Flash::success(__('lang.saved_successfully', ['operator' => __('lang.e_service')]));

    return redirect(route('eServices.index'));
}

Please any assistance will be appreciated. Thank you!


Solution

  • After couple of researches. I figured out that all my codes were correct but i needed to declare a strict rules that would contain all the file formats I wanted to accept through the Dropzone. So I had to declare the below array of file formats to test stuffs out

        return [
            'file' => 'mimes:jpeg,png,jpg,gif,svg,pdf,doc,docx,xls,xlsx,ppt,pptx,mp4',
        ];
    

    Also I learnt that the maxFilesize: 500, of the Dropzone is in bytes. So I had to increase it to equivalent of 10MB.

    When my code went live, I had a timeout errors trying to upload files of 8MB. So, I also learned that the Dropzone has a timeout property timeout: 9000, /*milliseconds*/, which I set to 0. Which mean no limit.

    I hope this helps someone out there. Thanks to everyone!