You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dropzone.js加载服务器视频缩略图失败及TypeError报错修复问询

解决Dropzone加载视频缩略图及FileReader错误问题

首先,咱们来拆解一下你遇到的两个核心问题:

错误原因分析

你看到的 TypeError: Argument 1 of FileReader.readAsArrayBuffer does not implement interface Blob 错误,根源在于你通过AJAX创建的mockFile是一个普通的JavaScript对象,不是标准的File或Blob类型。而FileReader.readAsArrayBuffer()只能接受Blob/File类型的参数,所以直接传入mockFile必然会报错。

另外,Dropzone能加载图片缩略图是因为你直接调用了thumbnail事件并传入了图片路径,但视频缩略图需要先截取视频帧,你的原逻辑错误地把mock文件当成了本地文件去处理,自然无法生成缩略图。

修复方案

我们需要区分本地上传的文件和从服务器加载的mock文件,分别处理:

1. 完善Mock文件的标记与属性

在AJAX回调里创建mock文件时,添加类型标记和视频类型,方便后续区分:

$.ajax({
  url: 'https://localhost/asnaf2019/userpanel/uploader.php',
  type: 'post',
  data: {request: 2},
  dataType: 'json',
  success: function(response){
    $.each(response, function(key,value) {
      var mockFile = { 
        name: value.name, 
        type: 'video/mp4', // 根据实际视频类型设置,或从response中获取
        path: value.path,
        isMock: true // 标记这是从服务器加载的mock文件
      };
      myDropzone_video.emit("addedfile", mockFile);
      myDropzone_video.emit("complete", mockFile);
      // 这里不再直接调用thumbnail,交给addedfile事件处理
    });
  }
});

2. 修改addedfile事件处理逻辑

区分mock文件和本地文件,对mock文件直接通过视频URL生成缩略图:

this.on('addedfile', function(origFile) {
  // 处理从服务器加载的mock视频文件
  if (origFile.isMock) {
    generateVideoThumbnailFromUrl(origFile, origFile.path);
    return;
  }

  // 保留原有的本地文件处理逻辑(只处理本地上传的视频)
  if (!origFile.type.match(/mp4|MP4/)) {
    myDropzone_video.enqueueFile(origFile);
    myDropzone_video.removeFile(origFile);
    return;
  }

  var fileReader = new FileReader();
  fileReader.addEventListener("load", function(event) {
    var origFileIndex = myDropzone_video.files.indexOf(origFile);
    myDropzone_video.files[origFileIndex].status = Dropzone.ADDED;
    var blob = new Blob([fileReader.result], {type: origFile.type});
    var url = URL.createObjectURL(blob);
    
    var video = document.createElement('video');
    var timeupdate = function() {
      if (snapImage()) {
        video.removeEventListener('timeupdate', timeupdate);
        video.pause();
      }
    };

    var snapImage = function() {
      var canvas = document.createElement('canvas');
      canvas.width = video.videoWidth;
      canvas.height = video.videoHeight;
      canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
      var image = canvas.toDataURL();
      var success = image.length > 100000;
      if (success) {
        myDropzone_video.emit("thumbnail", origFile, image);
        URL.revokeObjectURL(url);
      }
      return success;
    };

    video.addEventListener('loadeddata', function() {
      if (snapImage()) {
        video.removeEventListener('timeupdate', timeupdate);
      }
    });
    video.addEventListener('timeupdate', timeupdate);
    video.preload = 'metadata';
    video.src = url;
    video.muted = true;
    video.playsInline = true;
    video.play();
  });
  fileReader.readAsArrayBuffer(origFile);
});

// 新增:通过视频URL生成缩略图的工具函数
function generateVideoThumbnailFromUrl(file, videoUrl) {
  var video = document.createElement('video');
  var timeupdate = function() {
    if (snapImage()) {
      video.removeEventListener('timeupdate', timeupdate);
      video.pause();
    }
  };

  var snapImage = function() {
    var canvas = document.createElement('canvas');
    canvas.width = video.videoWidth;
    canvas.height = video.videoHeight;
    canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
    var image = canvas.toDataURL();
    var success = image.length > 100000;
    if (success) {
      myDropzone_video.emit("thumbnail", file, image);
      URL.revokeObjectURL(video.src); // 释放浏览器资源
    }
    return success;
  };

  video.addEventListener('loadeddata', function() {
    if (snapImage()) {
      video.removeEventListener('timeupdate', timeupdate);
    }
  });
  video.addEventListener('timeupdate', timeupdate);
  video.preload = 'metadata';
  video.src = videoUrl;
  video.muted = true;
  video.playsInline = true;
  video.crossOrigin = 'anonymous'; // 若视频跨域,需开启此设置并确保服务器允许跨域
  video.play();
}

3. 额外注意事项

  • 如果视频资源与当前页面跨域,需要在服务器端配置CORS允许访问,同时设置video.crossOrigin = 'anonymous'。
  • 若服务器已经生成了视频缩略图,可以直接在AJAX回调中调用myDropzone_video.emit("thumbnail", mockFile, 缩略图路径),省去前端截取帧的步骤,效率更高。

内容的提问来源于stack exchange,提问作者mr.titan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:03:19