使用MediaRecorder录制的MP4文件播放时进度条无法拖动求助
问题:MediaRecorder录制的视频无法拖拽进度条
我用JavaScript的MediaRecorder实现了音视频录制,保存为MP4格式,录制功能正常,但在VLC或Windows Media Player播放时,进度条显示但点击拖拽无响应。试过移除码率参数、更换为AVI格式,问题依旧。
我的代码:
let stopVar = false; let stopped = false; const downloadBTN = document.getElementById('downloadRec'); const stopBtn = document.getElementById('stop'); var saveData = (function () { var a = document.createElement("a"); document.body.appendChild(a); a.style = "display: none"; return function (data, fileName) { url = window.URL.createObjectURL(data); a.href = url; a.download = fileName; a.click(); window.URL.revokeObjectURL(url); }; }()); function startRecord() { $('.btn-info').prop('disabled', true); $('#stop').prop('disabled', false); $('#stop').css('display', 'block') $('#downloadRec').css('display', 'none') $('#startRecording').css('display', 'none') } function stopRecord() { $('.btn-info').prop('disabled', false); $('#stop').prop('disabled', true); $('#stop').css('display', 'none') $('#downloadRec').css('display', 'block') $('#startRecording').css('display', 'block') } stopBtn.addEventListener('click', function () { stopVar = true; }); const handleRecording = function ({ stream, mimeType }) { startRecord() let chunks = []; stopped = false; const mediaRecorder = new MediaRecorder(stream); mediaRecorder.ondataavailable = function (e) { if (e.data.size > 0) { chunks.push(e.data); } if (stopVar === true && stopped === false) { mediaRecorder.stop(); stopped = true; } }; mediaRecorder.onstop = function () { const blob = new Blob(chunks, { type: mimeType }); chunks = [] const filename = "RTS_recording.mp4" saveData(blob, filename); stopRecord(); }; mediaRecorder.start(200); }; async function recordScreen() { const mimeType = { audioBitsPerSecond: 128000, videoBitsPerSecond: 2500000, mimeType: 'video/mp4' }; stopVar = false; if (!navigator.mediaDevices.getDisplayMedia) { return window.alert('Change browser to new chrome or fox') } let stream = null; const streamedData = await navigator.mediaDevices.getDisplayMedia({ video: { cursor: "motion" }, audio: { 'echoCancellation': true } }); stream = streamedData; handleRecording({ stream, mimeType }); }
我曾尝试移除码率参数:
audioBitsPerSecond: 128000, videoBitsPerSecond: 2500000,
只保留MP4格式,之后又换AVI格式,问题仍存在。
解决方案
核心原因
MediaRecorder生成的MP4文件,元数据(moov原子)默认存放在文件末尾。播放器需要读取元数据才能获取视频时长、帧索引等关键信息,进而支持进度条拖拽。直接拼接Blob得到的文件,播放器无法提前解析到这些数据,导致进度条无法交互。AVI格式也存在类似的索引信息缺失问题。
解决方法:前端修复视频元数据
用FFmpeg.wasm在前端把MP4的moov原子移到文件开头,让播放器能快速读取元数据。
步骤1:引入FFmpeg.wasm
在HTML中添加:
<script src="https://unpkg.com/@ffmpeg/ffmpeg@0.12.6/dist/ffmpeg.min.js"></script>
步骤2:修改handleRecording中的onstop方法
替换原来的保存逻辑,先用FFmpeg处理Blob:
mediaRecorder.onstop = async function () { const blob = new Blob(chunks, { type: mimeType }); chunks = []; // 初始化FFmpeg const { createFFmpeg, fetchFile } = FFmpeg; const ffmpeg = createFFmpeg({ log: false }); await ffmpeg.load(); // 将Blob写入FFmpeg虚拟文件系统 ffmpeg.FS('writeFile', 'input.mp4', await fetchFile(blob)); // 处理视频:拷贝流并移动moov原子到开头 await ffmpeg.run('-i', 'input.mp4', '-c', 'copy', '-movflags', 'faststart', 'output.mp4'); // 读取处理后的文件 const data = ffmpeg.FS('readFile', 'output.mp4'); const processedBlob = new Blob([data.buffer], { type: 'video/mp4' }); // 下载处理后的视频 const filename = "RTS_recording_fixed.mp4"; saveData(processedBlob, filename); stopRecord(); };
其他注意事项
- FFmpeg.wasm首次加载会下载约20MB的核心文件,建议添加加载状态提示提升用户体验。
- 若不需要前端处理,也可将视频上传到后端,用FFmpeg命令行处理:
ffmpeg -i input.mp4 -c copy -movflags faststart output.mp4。 - AVI格式的修复逻辑类似,用FFmpeg重新封装即可:
ffmpeg -i input.avi -c copy output_fixed.avi。
内容的提问来源于stack exchange,提问作者rafaelHTML
相关产品推荐
相关产品推荐

