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;
关键说明
- Blob URL的优势:
URL.createObjectURL()不会读取整个文件内容,仅创建指向本地文件的临时URL,内存占用小,浏览器可直接流式加载视频,避免了Base64编码的性能瓶颈。 - 资源清理:必须在组件卸载时调用
URL.revokeObjectURL()释放Blob URL,否则会造成内存泄漏。 - 异步状态注意:原代码中
handleSave里的console.log(profileVideo)可能打印旧值,因为React状态更新是异步的,若需跟踪最新值,可通过useEffect监听profileVideo的变化。
内容的提问来源于stack exchange,提问作者hina shahzadi
相关产品推荐
相关产品推荐

