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

React中如何通过本地文件输入更新视频标签src并正常播放

解决React中本地视频选中后无法播放的问题

你的问题出在使用FileReader.readAsDataURL()处理视频文件上,这种方式会将整个视频编码为Base64字符串,不仅占用大量内存,还会导致浏览器加载视频时效率低下,最终无法正常播放。正确的做法是使用URL.createObjectURL()生成Blob URL,它直接指向本地文件,浏览器可以高效加载播放。

修改后的代码

补全缺失的状态定义并调整核心逻辑:

import { useState, useEffect } from 'react';
import { CModal, CModalBody, CButton } from '@coreui/react';
import VideoPlayer from './VideoPlayer';
import { Link } from 'react-router-dom';

function EditProfile() {
  const [selectedVideo, setSelectedVideo] = useState(null);
  const [profileVideo, setProfileVideo] = useState(null);
  const [visible2, setVisible2] = useState(false);

  const handleVideoChange = (event) => {
    const file = event.target.files[0];
    if (!file) return;

    setSelectedVideo(file);
    // 生成Blob URL替代Base64编码
    const videoBlobUrl = URL.createObjectURL(file);
    setProfileVideo(videoBlobUrl);
  };

  const handleSave = () => {
    // 可在此添加视频上传逻辑
    setVisible2(!visible2);
  };

  // 组件卸载时释放Blob URL,避免内存泄漏
  useEffect(() => {
    return () => {
      if (profileVideo) {
        URL.revokeObjectURL(profileVideo);
      }
    };
  }, [profileVideo]);

  return (
    <>
      <div className='user-bio-video-clip mt-lg-0 mt-4'>
        <VideoPlayer
          videoUrl={profileVideo}
          width='100%'
        />
        <Link className='edit-bio-video-clip' onClick={() => setVisible2(!visible2)}>
          Edit Video
        </Link>
      </div>

      {/* 视频更新模态框 */}
      <CModal
        className='photos-upload-modal'
        alignment="center"
        visible={visible2}
        onClose={() => setVisible2(false)}
        aria-labelledby="VerticallyCenteredExample"
        size='lg'
      >
        <CModalBody>
          <div className='upload-photo-modal-body-content film-upload-content text-center'>
            <h3>upload your video</h3>
            <div className='text-center mt-4'>
              <label htmlFor='photoInput' className='secondary_outline_btn'>
                Browse
              </label>
              <input type='file' id="photoInput" onChange={handleVideoChange} accept="video/*" hidden/>
            </div>
            <div className='mt-4'>
              <CButton className='primary_btn' onClick={handleSave}>
                Save
              </CButton>
            </div>
          </div>
          <CButton className='close_modal_btn' onClick={() => setVisible2(false)}></CButton>
        </CModalBody>
      </CModal>
    </>
  )
}

export default EditProfile;

关键说明

  1. Blob URL的优势:URL.createObjectURL()不会读取整个文件内容,仅创建指向本地文件的临时URL,内存占用小,浏览器可直接流式加载视频,避免了Base64编码的性能瓶颈。
  2. 资源清理:必须在组件卸载时调用URL.revokeObjectURL()释放Blob URL,否则会造成内存泄漏。
  3. 异步状态注意:原代码中handleSave里的console.log(profileVideo)可能打印旧值,因为React状态更新是异步的,若需跟踪最新值,可通过useEffect监听profileVideo的变化。

内容的提问来源于stack exchange,提问作者hina shahzadi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 03:58:14