So - letzte Version.....

Schau mal rein... Alles nicht sehr hübsch, aber ist ja ein Draft.
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MP3 Mixer</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
text-align: center;
margin: 20px;
background-color: #f8f8f8;
color: #333;
display: flex;
justify-content: center;
}
.container {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
max-width: 1000px;
}
.box {
background: white;
border-radius: 15px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
padding: 20px;
}
.audio-container {
margin: 20px 0;
}
.slider {
width: 100%;
-webkit-appearance: none;
height: 6px;
background: #ddd;
border-radius: 5px;
outline: none;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
width: 20px;
height: 20px;
background: #007AFF;
border-radius: 50%;
cursor: pointer;
}
button {
background-color: #007AFF;
color: white;
border: none;
padding: 10px 20px;
margin: 5px;
border-radius: 10px;
cursor: pointer;
font-size: 16px;
}
button:hover {
background-color: #005ecb;
}
.bpm-display {
font-size: 18px;
font-weight: bold;
margin-top: 5px;
}
.bookmark-list, .loop-list {
margin-top: 20px;
text-align: left;
}
.bookmark-item, .loop-item {
display: flex;
justify-content: space-between;
margin: 5px 0;
}
.loop-section {
margin-bottom: 20px;
}
.audio-container:nth-child(3) {
margin-top: 40px;
}
.audio-container:nth-child(3) h4 {
margin-top: 30px;
}
.slider-container {
display: flex;
align-items: center;
justify-content: center;
margin-top: 10px;
}
.slider-container label {
margin-right: 10px;
}
.mute-button {
margin-left: 20px;
}
</style>
</head>
<body>
<div class="container">
<!-- Player Section -->
<div class="box">
<h3>Player</h3>
<div class="audio-container">
<h4>Track 1</h4>
<audio id="audio1" controls>
<source src="track1.mp3" type="audio/mpeg">
Dein Browser unterstützt kein Audio-Element.
</audio>
<br>
<label>Lautstärke:</label>
<input type="range" id="volume1" class="slider" min="0" max="1" step="0.01" value="1">
</div>
<div class="audio-container">
<h4>Track 2</h4>
<audio id="audio2" controls>
<source src="track2.mp3" type="audio/mpeg">
Dein Browser unterstützt kein Audio-Element.
</audio>
<br>
<label>Lautstärke:</label>
<input type="range" id="volume2" class="slider" min="0" max="1" step="0.01" value="1">
</div>
<div class="audio-container">
<h4>Metronom</h4>
<audio id="metronome" loop>
<source src="metronome.mp3" type="audio/mpeg">
Dein Browser unterstützt kein Audio-Element.
</audio>
<div class="slider-container">
<label>Lautstärke:</label>
<input type="range" id="metronomeVolume" class="slider" min="0" max="1" step="0.01" value="0.5">
<label>Tempo (BPM):</label>
<input type="range" id="metronomeSpeed" class="slider" min="40" max="240" step="1" value="120">
<button class="mute-button" id="muteButton" onclick="toggleMetronomeMute()">Mute</button>
</div>
<div class="bpm-display">BPM: <span id="bpmValue">120</span></div>
</div>
<!-- Position Slider -->
<div class="audio-container">
<h4>Position der Tracks</h4>
<input type="range" id="positionSlider" class="slider" min="0" value="0" step="0.1" onchange="updateTracksPosition()">
<br>
<span id="currentTime">0</span> Sekunden
</div>
<!-- Balance Slider -->
<div class="audio-container">
<h4>Balance</h4>
<label for="balanceSlider">Balance zwischen Track 1 und Track 2</label>
<input type="range" id="balanceSlider" class="slider" min="-100" max="100" value="0" step="1" onchange="updateBalance()">
<br>
<span id="balanceValue">50% Track 1, 50% Track 2</span>
</div>
<button onclick="playAll()">Play</button>
<button onclick="stopAll()">Stop</button>
<button onclick="resetAll()">Zurück an Start</button>
</div>
<!-- Right Section: Loop and Bookmarks -->
<div>
<!-- Loop Section -->
<div class="box loop-section">
<h3>Loop</h3>
<label>Loop Start (A):</label>
<input type="number" id="loopStart" min="0" step="0.1" readonly> Sekunden
<button onclick="setLoopStart()">Setze A</button>
<br>
<label>Loop End (

:</label>
<input type="number" id="loopEnd" min="0" step="0.1" readonly> Sekunden
<button onclick="setLoopEnd()">Setze B</button>
<br>
<button id="loopButton" onclick="toggleLoop()">Loop aktivieren</button>
<div class="loop-list" id="loopList">
<!-- Loops will be listed here -->
</div>
</div>
<!-- Bookmark Section -->
<div class="box">
<h3>Bookmarks</h3>
<button onclick="setBookmark()">Bookmark setzen</button>
<div class="bookmark-list" id="bookmarkList">
<!-- Bookmarks will be listed here -->
</div>
</div>
</div>
</div>
<script>
const audio1 = document.getElementById('audio1');
const audio2 = document.getElementById('audio2');
const metronome = document.getElementById('metronome');
const volume1 = document.getElementById('volume1');
const volume2 = document.getElementById('volume2');
const metronomeVolume = document.getElementById('metronomeVolume');
const metronomeSpeed = document.getElementById('metronomeSpeed');
const bpmValue = document.getElementById('bpmValue');
const positionSlider = document.getElementById('positionSlider');
const currentTimeDisplay = document.getElementById('currentTime');
const balanceSlider = document.getElementById('balanceSlider');
const balanceValueDisplay = document.getElementById('balanceValue');
let loopActive = false;
let loopStart = 0;
let loopEnd = 0;
const bookmarks = [];
const loops = [];
let metronomeMuted = false;
volume1.addEventListener('input', () => audio1.volume = volume1.value);
volume2.addEventListener('input', () => audio2.volume = volume2.value);
metronomeVolume.addEventListener('input', () => metronome.volume = metronomeVolume.value);
metronomeSpeed.addEventListener('input', () => {
bpmValue.textContent = metronomeSpeed.value;
adjustMetronomeSpeed();
});
audio1.addEventListener('play', () => syncPosition());
audio2.addEventListener('play', () => syncPosition());
function syncPosition() {
const maxTime = Math.max(audio1.duration, audio2.duration);
positionSlider.max = maxTime;
updateSliderPosition();
}
function updateSliderPosition() {
const time = Math.min(audio1.currentTime, audio2.currentTime);
positionSlider.value = time;
currentTimeDisplay.textContent = time.toFixed(1);
}
function updateTracksPosition() {
const newTime = positionSlider.value;
audio1.currentTime = newTime;
audio2.currentTime = newTime;
}
function updateBalance() {
const balance = balanceSlider.value;
let volumeA = 1;
let volumeB = 1;
if (balance < 0) { // Mehr Track A
volumeA = 1;
volumeB = (100 + parseInt(balance)) / 100;
} else if (balance > 0) { // Mehr Track B
volumeA = (100 - parseInt(balance)) / 100;
volumeB = 1;
} else { // Gleichgewicht
volumeA = 1;
volumeB = 1;
}
// Lautstärke der Tracks entsprechend dem Balance anpassen
audio1.volume = volumeA;
audio2.volume = volumeB;
// Anzeige der Balance im Text
balanceValueDisplay.textContent = `${(100 - balance)}% Track 1, ${balance}% Track 2`;
}
function playAll() {
audio1.play();
audio2.play();
startMetronome();
}
function stopAll() {
audio1.pause();
audio2.pause();
metronome.pause();
}
function resetAll() {
audio1.currentTime = 0;
audio2.currentTime = 0;
metronome.currentTime = 0;
updateSliderPosition();
}
function startMetronome() {
if (!metronomeMuted) {
metronome.play();
}
}
function setLoopStart() {
loopStart = Math.min(audio1.currentTime, audio2.currentTime);
document.getElementById('loopStart').value = loopStart.toFixed(1);
}
function setLoopEnd() {
loopEnd = Math.min(audio1.currentTime, audio2.currentTime);
document.getElementById('loopEnd').value = loopEnd.toFixed(1);
}
function toggleLoop() {
loopActive = !loopActive;
updateLoopButtonText();
if (loopActive) {
loopAudio();
}
}
function loopAudio() {
if (loopActive) {
if (audio1.currentTime >= loopEnd || audio2.currentTime >= loopEnd) {
audio1.currentTime = loopStart;
audio2.currentTime = loopStart;
}
requestAnimationFrame(loopAudio);
}
}
function updateLoopButtonText() {
const loopButton = document.getElementById('loopButton');
loopButton.textContent = loopActive ? "Loop deaktiviert" : "Loop aktivieren";
}
function adjustMetronomeSpeed() {
const bpm = metronomeSpeed.value;
metronome.playbackRate = bpm / 120;
}
function toggleMetronomeMute() {
metronomeMuted = !metronomeMuted;
metronome.muted = metronomeMuted;
document.getElementById('muteButton').textContent = metronomeMuted ? "Unmute" : "Mute";
}
function setBookmark() {
const time = Math.min(audio1.currentTime, audio2.currentTime);
bookmarks.push(time.toFixed(2));
updateBookmarkList();
}
function updateBookmarkList() {
const bookmarkList = document.getElementById('bookmarkList');
bookmarkList.innerHTML = '';
bookmarks.forEach((time, index) => {
const bookmarkItem = document.createElement('div');
bookmarkItem.classList.add('bookmark-item');
bookmarkItem.innerHTML = `
<span>Bookmark: ${time} Sekunden</span>
<button onclick="jumpToBookmark(${index})">Go</button>
<button onclick="deleteBookmark(${index})">Löschen</button>
`;
bookmarkList.appendChild(bookmarkItem);
});
}
function jumpToBookmark(index) {
const time = parseFloat(bookmarks[index]);
audio1.currentTime = time;
audio2.currentTime = time;
}
function deleteBookmark(index) {
bookmarks.splice(index, 1);
updateBookmarkList();
}
</script>
</body>
</html>