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

Ubuntu系统Chrome中react-dropzone无法预览.mov文件

React-Dropzone无法在Ubuntu Chrome中预览.mov文件的解决方案

我使用react-dropzone实现了文件拖拽上传组件,该组件在Windows 11的Chrome浏览器中正常运行,但在Ubuntu 22.04.1 LTS系统的Chrome 105.0.5195.125(64位正式版)中无法预览.mov格式文件。组件代码如下:

import Loader from "./Loader";
import PropTypes from "prop-types";
import notification from "@/utils/notification";
import styles from "@/components/Icon/PopupBox.module.css";
import { Box } from "@mui/material";
import { memo, useCallback } from "react";
import { Controller } from "react-hook-form";
import { useDropzone } from "react-dropzone";
import { checkFileExtensionIsInArray } from "@/utils/helper";
import { FormControl, FormHelperText, Typography } from "@mui/material";

const DropzoneUpload = (props) => {
  const {
    control,
    rules,
    name,
    accept,
    maxFiles,
    minSize,
    maxSize,
    noDrag,
    noClick,
    disabled,
    children,
    label,
    errors,
    allowedFileType,
    multiple,
    handleChange,
    loadingField,
    progress,
  } = {
    ...props,
  };

  const checkFileAndValidate = useCallback(
    (file) => {
      const fileName = file?.name?.toLowerCase();
      if (file.type?.includes("image") && file?.size > 52428800) {
        return notification.error("Image size should be upto 50MB");
      }
      if (!checkFileExtensionIsInArray(fileName, allowedFileType)) {
        return notification.error(`Only ${allowedFileType?.join(", ")} is allowed`);
      }
      if (maxSize && file?.size > maxSize) {
        return notification.error("Maximum file size limit exceeds");
      }
    },
    [allowedFileType, maxSize]
  );

  const onDrop = useCallback(
    (acceptedFiles) => {
      if (checkFileExtensionIsInArray(acceptedFiles[0]?.path, allowedFileType)) {
        const finalFiles = [];
        acceptedFiles?.length > 0 &&
          acceptedFiles.forEach((file) => {
            if (file?.type?.includes("image") && file.size > 52428800) {
              // return notification.error("Image size should be upto 50MB");
            } else {
              finalFiles.push(file);
            }
          });
        handleChange(finalFiles);
      }
    },
    [handleChange]
  );
  const { getRootProps, getInputProps } = useDropzone({
    accept,
    maxFiles: multiple ? maxFiles : 0,
    minSize,
    maxSize,
    onDrop,
    noDrag,
    noClick,
    disabled,
    multiple,
    validator: checkFileAndValidate,
  });

  return (
    <FormControl variant="standard" sx={{ m: 0, minWidth: "100%" }}>
      <Typography>{label}</Typography>
      <Controller
        name={name}
        rules={rules}
        control={control}
        render={(controllerProps) => {
          return (
            <div>
              {loadingField === name ? (
                <Box className={styles.boxStyles}>
                  <Loader value={progress} colorStyle={styles.redColor} />
                </Box>
              ) : loadingField === true ? (
                <Loader />
              ) : (
                <div {...getRootProps()} {...controllerProps}>
                  <input {...getInputProps()} />
                  {children}
                </div>
              )}
            </div>
          );
        }}
      />
      <FormHelperText error={true}>{errors || null}</FormHelperText>
    </FormControl>
  );
};

DropzoneUpload.propTypes = {
  control: PropTypes.any,
  rules: PropTypes.any,
  name: PropTypes.string,
  accept: PropTypes.string,
  maxFiles: PropTypes.number,
  minSize: PropTypes.number,
  maxSize: PropTypes.number,
  noDrag: PropTypes.bool,
  noClick: PropTypes.bool,
  disabled: PropTypes.bool,
  children: PropTypes.any,
  label: PropTypes.string,
  errors: PropTypes.any,
  allowedFileType: PropTypes.any,
  multiple: PropTypes.bool,
  handleChange: PropTypes.func,
  loadingField: PropTypes.string,
  progress: PropTypes.number,
};

DropzoneUpload.defaultProps = {
  control: {},
  rules: {},
  name: "",
  maxFiles: 1,
  minSize: 0,
  maxSize: 2147483640,
  noDrag: false,
  noClick: false,
  disabled: false,
  children: null,
  label: null,
  errors: null,
  allowedFileType: null,
  multiple: false,
  handleChange: () => {},
  loadingField: null,
  accept: "image/jpeg,image/png,images/jpg",
  progress: 0,
};

export default memo(DropzoneUpload);

问题原因分析

  1. MIME类型过滤缺失:默认accept属性仅包含图片类型,未添加.mov对应的video/quicktime类型,导致Ubuntu Chrome可能拒绝接收或识别.mov文件。
  2. 文件路径属性错误:onDrop中使用acceptedFiles[0]?.path验证扩展名,但浏览器环境下File对象没有path属性,应使用file.name替代。
  3. 编解码器差异:Ubuntu Chrome默认可能缺少.mov文件所需的QuickTime编解码器,导致预览失败。

修复方案

1. 更新accept属性,添加视频MIME类型

修改组件默认Props中的accept,加入视频类型:

DropzoneUpload.defaultProps = {
  // ...其他默认属性
  accept: "image/jpeg,image/png,image/jpg,video/quicktime,video/mp4",
};

2. 修复扩展名验证逻辑

将onDrop中的path替换为name,并补全依赖数组:

const onDrop = useCallback(
  (acceptedFiles) => {
    // 替换path为name,浏览器中File对象无path属性
    if (checkFileExtensionIsInArray(acceptedFiles[0]?.name, allowedFileType)) {
      const finalFiles = [];
      acceptedFiles?.length > 0 &&
        acceptedFiles.forEach((file) => {
          if (file?.type?.includes("image") && file.size > 52428800) {
            notification.error("Image size should be upto 50MB");
          } else {
            finalFiles.push(file);
          }
        });
      handleChange(finalFiles);
    }
  },
  [handleChange, allowedFileType] // 添加allowedFileType到依赖
);

3. 确保allowedFileType包含.mov

使用组件时,传入包含.mov的允许扩展名列表:

<DropzoneUpload
  allowedFileType={['.jpg', '.png', '.mov']}
  // 其他属性
/>

4. 完善视频预览逻辑

如果预览组件未处理视频类型,添加<video>标签支持:

// 示例预览组件
const FilePreview = ({ files }) => {
  return (
    <div>
      {files.map(file => (
        <div key={file.name} style={{ margin: '10px 0' }}>
          {file.type.includes('image') ? (
            <img 
              src={URL.createObjectURL(file)} 
              alt={file.name} 
              style={{ maxWidth: '200px' }} 
            />
          ) : file.type.includes('video') ? (
            <video 
              src={URL.createObjectURL(file)} 
              controls 
              style={{ maxWidth: '200px' }} 
            />
          ) : (
            <p>{file.name}</p>
          )}
        </div>
      ))}
    </div>
  );
};

5. 安装Ubuntu多媒体编解码器

若上述修复后仍无法预览,安装系统级编解码器:

sudo apt update && sudo apt install ubuntu-restricted-extras

安装完成后重启Chrome再测试。

内容的提问来源于stack exchange,提问作者Sajjan Shah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 19:41:56