js在浏览器中如何使用MediaStream与MediaRecorder实现声音音频多轨道混流?
网友回复
这个可以实现,多音轨合并混流音频,可拖拽时间
完整代码
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>HTML5 音频编辑器</title> <style> body { font-family: sans-serif; margin: 20px; background-color: #f4f4f4; color: #333; } .controls button { margin: 5px; padding: 10px 15px; background-color: #007bff; color: white; border: none; cursor: pointer; border-radius: 4px; } .controls button:hover { background-color: #0056b3; } .tracks-container { margin-top: 20px; border: 1px solid #ccc; padding: 10px; background-color: #fff; position: relative; /* For absolute positioning of ruler */ overflow-x: auto; /* Allow horizontal scrolling for long timelines */ } .timeline-ruler { height: 20px; background-color: #e0e0e0; position: sticky; /* Make ruler sticky */ top: 0; z-index: 10; display: flex; } .ruler-mark { min-width: 50px; /* Corresponds to 1 second if pixelsPerSecond is 50 */ border-left: 1px solid #aaa; font-size: 10px; text-align: right; padding-right: 2px; box-sizing: border-box; } .track { border: 1px dashed #ddd; margin-bottom: 10px; min-height: 60px; /* Min height for dropping files */ position: relative; /* Crucial for absolute positioning of clips */ background-color: #f9f9f9; padding: 5px 0; /* Add some padding for clips */ } .track-header { font-size: 0.9em; color: #555; padding: 2px 5px; background-color: #eee; display: flex; justify-content: space-between; align-items: center; } .track-header input[type="file"] { display: none; } .audio-clip { position: absolute; height: 50px; background-color: lightcoral; border: 1px solid darkred; border-radius: 3px; cursor: move; display: flex; align-items: center; justify-content: center; font-size: 0.8em; color: white; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; box-sizing: border-box; padding: 0 5px; } .drop-zone-active { border: 2px dashed dodgerblue !important; background-color: #e6f7ff !important; } #loading-indicator { display: none; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); padding: 20px; background: rgba(0,0,0,0.7); color: white; border-radius: 5px; z-index: 1000; } </style> </head> <body> <h1>简易音频混音器</h1> <div class="controls"> <button id="addTrackBtn">添加音轨</button> <button id="mergeAndDownloadBtn">合并并下载 (WAV)</button> </div> <div class="tracks-container"> <div class="timeline-ruler" id="timelineRuler"> <!-- Ruler marks will be generated by JS --> </div> <div id="tracks"> <!-- Audio tracks will be added here --> </div> </div> <div id="loading-indicator">处理中,请稍候...</div> <script> document.addEventListener('DOMContentLoaded', () => { const addTrackBtn = document.getElementById('addTrackBtn'); const mergeAndDownloadBtn = document.getElementById('mergeAndDownloadBtn'); const tracksContainer = document.getElementById('tracks'); const timelineRuler = document.getElementById('timelineRuler'); const loadingIndicator = document.getElementById('loading-indicator'); let audioContext; let tracksData = []; // Array to store data for each track and its clips let trackIdCounter = 0; let clipIdCounter = 0; const PIXELS_PER_SECOND = 50; // 50 pixels represent 1 second const MAX_TIMELINE_SECONDS = 180; // Max length of timeline ruler // Initialize AudioContext function initAudioContext() { if (!audioContext) { audioContext = new (window.AudioContext || window.webkitAudioContext)(); } if (!audioContext) { alert("浏览器不支持 Web Audio API"); return false; } return true; } // Generate timeline ruler function generateTimelineRuler() { timelineRuler.innerHTML = ''; // Clear existing marks for (let i = 0; i < MAX_TIMELINE_SECONDS; i++) { const mark = document.createElement('div'); mark.classList.add('ruler-mark'); mark.style.minWidth = `${PIXELS_PER_SECOND}px`; mark.textContent = `${i}s`; timelineRuler.appendChild(mark); } // Ensure the tracks container is wide enough tracksContainer.style.minWidth = `${MAX_TIMELINE_SECONDS * PIXELS_PER_SECOND}px`; } // Add a new track addTrackBtn.addEventListener('click', () => { if (!initAudioContext()) return; createTrackElement(); }); function createTrackElement() { const trackId = `track-${trackIdCounter++}`; const trackDiv = document.createElement('div'); trackDiv.classList.add('trac...
点击查看剩余70%