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%


