如何使用原生JavaScript将多个视频URL合并为单个MP4文件?
原生JavaScript浏览器端合并MP4文件方案
核心说明
浏览器端原生合并MP4不能直接拼接文件Blob,因为MP4有特定的容器结构。如果需要生成单个MP4文件,得借助MediaSource与MediaRecorderAPI处理音视频轨道;如果只是需要连续播放(而非生成新文件),可以优化你现有的切换播放逻辑。
方案一:真正合并为单个MP4文件
1. 加载视频并提取音视频轨道
async function getVideoTracks(urls) { const tracks = { video: [], audio: [] }; for (const url of urls) { const video = document.createElement('video'); video.muted = true; video.preload = 'auto'; await new Promise((resolve, reject) => { video.onloadeddata = resolve; video.onerror = reject; video.src = url; }); // 提取有效音视频轨道 if (video.videoTracks.length > 0) { tracks.video.push(video.captureStream().getVideoTracks()[0]); } if (video.audioTracks.length > 0) { tracks.audio.push(video.captureStream().getAudioTracks()[0]); } } return tracks; }
2. 合并轨道并录制为新MP4
async function mergeVideos(videoUrls) { const tracks = await getVideoTracks(videoUrls); // 创建合并后的媒体流 const mergedStream = new MediaStream([ ...tracks.video, ...tracks.audio ]); // 初始化MediaRecorder(指定MP4格式) const recorder = new MediaRecorder(mergedStream, { mimeType: 'video/mp4' }); const chunks = []; recorder.ondataavailable = (e) => chunks.push(e.data); recorder.onstop = () => { const mergedBlob = new Blob(chunks, { type: 'video/mp4' }); // 生成下载链接 const downloadLink = document.createElement('a'); downloadLink.href = URL.createObjectURL(mergedBlob); downloadLink.download = 'merged-video.mp4'; downloadLink.click(); }; // 开始录制,按顺序播放所有视频以驱动轨道输出 recorder.start(); for (const url of videoUrls) { const video = document.createElement('video'); video.muted = true; video.src = url; await video.play(); await new Promise(resolve => video.onended = resolve); video.pause(); } // 停止录制并释放资源 recorder.stop(); tracks.video.forEach(track => track.stop()); tracks.audio.forEach(track => track.stop()); } // 使用示例 const targetUrls = ['视频1地址.mp4', '视频2地址.mp4']; mergeVideos(targetUrls);
注意事项
- 浏览器兼容性:Chrome、Edge等现代浏览器支持MP4格式的
MediaRecorder,Firefox需额外配置,建议提前测试目标环境。 - CORS限制:所有视频URL必须允许跨域访问,否则无法加载和提取轨道。
- 性能问题:合并大体积视频会占用较多内存,建议控制视频数量与大小。
方案二:优化版连续播放(不生成新文件)
如果不需要生成单个MP4,只是实现无缝连续播放,可以简化你的原有代码:
let activeVideo = 0; const videoUrls = ['视频1地址.mp4', '视频2地址.mp4']; const myvid = document.getElementById('myvid'); function loadAndPlay(index) { myvid.src = videoUrls[index]; myvid.play().catch(err => console.error('播放失败:', err)); } // 初始化播放 loadAndPlay(activeVideo); // 监听视频结束事件,切换下一个 myvid.addEventListener('ended', () => { activeVideo = (activeVideo + 1) % videoUrls.length; loadAndPlay(activeVideo); });
内容的提问来源于stack exchange,提问作者Geloteee
相关产品推荐
相关产品推荐

