将input替换为select获取视频元数据时触发TypeError报错求助
解决思路与代码修改方案
核心问题定位
原来的代码依赖<input type="file">返回的FileList对象(通过input.files[0]获取本地文件),但<select>的选项值是服务器视频的URL字符串,没有files属性,直接调用原逻辑里的files[0]自然会报undefined错误。
具体修改步骤
1. 调整select的HTML结构
给每个option设置服务器视频的真实URL作为value,比如:
<select id="videoSelector"> <option value="">选择视频</option> <option value="/videos/movie1.mp4">电影1</option> <option value="/videos/movie2.mp4">电影2</option> </select>
2. 替换原文件读取逻辑
原代码里监听input的change事件,现在改成监听select的change事件,并且不再使用FileReader,而是直接通过URL加载视频,再提取元数据:
const videoSelector = document.getElementById('videoSelector'); const videoElement = document.getElementById('yourVideoElement'); // 页面上的video标签 const coverImg = document.getElementById('coverImg'); // 显示封面的img标签 const titleEl = document.getElementById('title'); // 显示标题的元素 videoSelector.addEventListener('change', function() { const videoUrl = this.value; if (!videoUrl) return; // 设置视频源 videoElement.src = videoUrl; // 提取标题(直接用option的文本) titleEl.textContent = this.options[this.selectedIndex].text; // 提取封面截图 videoElement.addEventListener('loadeddata', function getCover() { // 创建canvas绘制第一帧 const canvas = document.createElement('canvas'); canvas.width = videoElement.videoWidth; canvas.height = videoElement.videoHeight; canvas.getContext('2d').drawImage(videoElement, 0, 0); // 转成base64设置给img标签 coverImg.src = canvas.toDataURL('image/jpeg'); // 移除监听避免重复触发 videoElement.removeEventListener('loadeddata', getCover); }); });
3. 补充其他元数据获取逻辑
如果原代码需要文件大小、视频时长这类信息,可补充如下:
// 获取视频时长 videoElement.addEventListener('loadedmetadata', function() { const duration = videoElement.duration; console.log(`视频时长:${Math.floor(duration / 60)}分${Math.floor(duration % 60)}秒`); }); // 获取文件大小(需服务器允许HEAD请求) fetch(videoUrl, { method: 'HEAD' }) .then(res => { const fileSize = res.headers.get('Content-Length'); console.log(`文件大小:${(fileSize / 1024 / 1024).toFixed(2)}MB`); });
关键注意事项
- 确保服务器视频文件允许跨域访问(如果前端和视频不在同一域名),否则会出现加载失败
- 视频加载是异步的,必须在
loadeddata或loadedmetadata事件触发后再提取封面和元数据 - 若需判断视频类型,可从URL后缀解析,比如
videoUrl.split('.').pop()
内容的提问来源于stack exchange,提问作者Amir Jawad
相关产品推荐
相关产品推荐

