Software zum "live" mischen von Spuren (als MP3) gesucht

Der Leitende

[Hier könnte Ihre Werbung stehen!]
Beiträge
45
Bassix
ß1.656
Hallo Freunde,

ich suche ein Programm (möglichst Freeware), mit dem ich jeweils zwei Tonspuren (liegen als mp3 vor) synchron abspielen und "on-the-fly" über eine Art Balance-Regler mischen kann.

Anwendungszweck: Ich habe mit eine ganze Reihe MP3-Tracks aufgesplittet in Versionen mit "nur Bass" und "alles außer Bass". Die sind natürlich exakt gleich lang und würden synchron abgespielt den originalen Mix ergeben.
Die Version "nur Bass" nutze ich einfach zum besseren heraushören der Bass-Linie und die Version "alles außer Bass" als Play-Along.
Im Augenblick spiele ich die MP3s über Riffstation ab, weil ich da relativ einfach das Tempo in BPM und die Tonhöhe in Halbtonschritten wechseln und ein Metronom rein und raus mischen kann. Eine Loop-Funktion für Wiederholungen gibt es auch und die Tonart liest er mir auch raus, wobei letzteres nicht unbedingt nötig wäre.

Nur kann ich darüber halt immer nur eine Datei laufen lassen. Manchmal möchte ich aber zur Orientierung den Bass in den Original-Mix mischen bzw. ebenfalls zur Orientierung die Melodie leise unter die Bass-Spur legen. Und das ganze möglichst aus dem Begleit-Spiel heraus. Die Features von Riffstation bräuchte ich nicht zwingend, wären aber nett, insbesondere das Tempo in BPM und das Metronom.

Nun sagt ihr: Da gibt's 1000 Programme, die das können. Glaube ich auch sofort. Aber letztlich brauche ich nur das oben Beschriebene und nicht mehr. Also keine Software mit 30 Spuren und 200 Filtern, VST-/MIDI-Schnittstelle, Recorder, Converter, etc., sondern eher was simples. Könnt ihr mir das was empfehlen?

Grüße,
Carsten
 

Ganz simple:


<!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: Arial, sans-serif;
text-align: center;
margin: 20px;
}
.audio-container {
margin: 20px auto;
width: 300px;
}
.slider {
width: 100%;
}
</style>
</head>
<body>

<h2>MP3 Mixer</h2>

<div class="audio-container">
<h3>Track 1</h3>
<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">
<h3>Track 2</h3>
<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>

<button onclick="playAll()">Play</button>
<button onclick="pauseAll()">Pause</button>

<script>
const audio1 = document.getElementById('audio1');
const audio2 = document.getElementById('audio2');
const volume1 = document.getElementById('volume1');
const volume2 = document.getElementById('volume2');

volume1.addEventListener('input', () => {
audio1.volume = volume1.value;
});

volume2.addEventListener('input', () => {
audio2.volume = volume2.value;
});

function playAll() {
audio1.play();
audio2.play();
}

function pauseAll() {
audio1.pause();
audio2.pause();
}
</script>

</body>
</html>


Speicher das als player.html in das Verzeichnis deiner beiden Files. Pass die Dateinamen an deine Files an.
Und starte sie.
 
Ganz simple:


<!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: Arial, sans-serif;
text-align: center;
margin: 20px;
}
.audio-container {
margin: 20px auto;
width: 300px;
}
.slider {
width: 100%;
}
</style>
</head>
<body>

<h2>MP3 Mixer</h2>

<div class="audio-container">
<h3>Track 1</h3>
<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">
<h3>Track 2</h3>
<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>

<button onclick="playAll()">Play</button>
<button onclick="pauseAll()">Pause</button>

<script>
const audio1 = document.getElementById('audio1');
const audio2 = document.getElementById('audio2');
const volume1 = document.getElementById('volume1');
const volume2 = document.getElementById('volume2');

volume1.addEventListener('input', () => {
audio1.volume = volume1.value;
});

volume2.addEventListener('input', () => {
audio2.volume = volume2.value;
});

function playAll() {
audio1.play();
audio2.play();
}

function pauseAll() {
audio1.pause();
audio2.pause();
}
</script>

</body>
</html>


Speicher das als player.html in das Verzeichnis deiner beiden Files. Pass die Dateinamen an deine Files an.
Und starte sie.
Sehr geil :-)
 
<!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: Arial, sans-serif;
text-align: center;
margin: 20px;
}
.audio-container {
margin: 20px auto;
width: 300px;
}
.slider {
width: 100%;
}
</style>
</head>
<body>

<h2>MP3 Mixer</h2>

<div class="audio-container">
<h3>Track 1</h3>
<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">
<h3>Track 2</h3>
<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>

<button onclick="playAll()">Play</button>
<button onclick="pauseAll()">Pause</button>
<button onclick="resetAll()">Zurück an Start</button>
<br><br>
<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 (B):</label>
<input type="number" id="loopEnd" min="0" step="0.1" readonly> Sekunden
<button onclick="setLoopEnd()">Setze B</button>
<br>
<button onclick="startLoop()">Loop aktivieren</button>
<button onclick="stopLoop()">Loop stoppen</button>

<script>
const audio1 = document.getElementById('audio1');
const audio2 = document.getElementById('audio2');
const volume1 = document.getElementById('volume1');
const volume2 = document.getElementById('volume2');
let loopActive = false;
let loopStart = 0;
let loopEnd = 0;

volume1.addEventListener('input', () => {
audio1.volume = volume1.value;
});

volume2.addEventListener('input', () => {
audio2.volume = volume2.value;
});

function playAll() {
audio1.play();
audio2.play();
}

function pauseAll() {
audio1.pause();
audio2.pause();
}

function resetAll() {
audio1.currentTime = 0;
audio2.currentTime = 0;
}

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 startLoop() {
loopStart = parseFloat(document.getElementById('loopStart').value) || 0;
loopEnd = parseFloat(document.getElementById('loopEnd').value) || 0;
if (loopEnd > loopStart) {
loopActive = true;
checkLoop(audio1);
checkLoop(audio2);
}
}

function stopLoop() {
loopActive = false;
}

function checkLoop(audio) {
if (!loopActive) return;
audio.addEventListener('timeupdate', function () {
if (audio.currentTime >= loopEnd) {
audio.currentTime = loopStart;
audio.play();
}
});
}
</script>

</body>
</html>
 
Mit Metronom... aber du musst noch ein Soundfile fürs clicken in den Ordner legen ...

Aber Spielerei mal bei Seite, suchst du was für Win/Mac/Linux/iOS oder Android?

<!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: Arial, sans-serif;
text-align: center;
margin: 20px;
}
.audio-container {
margin: 20px auto;
width: 300px;
}
.slider {
width: 100%;
}
</style>
</head>
<body>

<h2>MP3 Mixer</h2>

<div class="audio-container">
<h3>Track 1</h3>
<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">
<h3>Track 2</h3>
<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">
<h3>Metronom</h3>
<audio id="metronome" loop>
<source src="metronome.mp3" type="audio/mpeg">
Dein Browser unterstützt kein Audio-Element.
</audio>
<br>
<label>Lautstärke:</label>
<input type="range" id="metronomeVolume" class="slider" min="0" max="1" step="0.01" value="0.5">
<br>
<label>Tempo (BPM):</label>
<input type="range" id="metronomeSpeed" class="slider" min="40" max="240" step="1" value="120">
</div>

<button onclick="playAll()">Play</button>
<button onclick="pauseAll()">Pause</button>
<button onclick="resetAll()">Zurück an Start</button>
<br><br>
<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 (B):</label>
<input type="number" id="loopEnd" min="0" step="0.1" readonly> Sekunden
<button onclick="setLoopEnd()">Setze B</button>
<br>
<button onclick="startLoop()">Loop aktivieren</button>
<button onclick="stopLoop()">Loop stoppen</button>

<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');
let loopActive = false;
let loopStart = 0;
let loopEnd = 0;

volume1.addEventListener('input', () => {
audio1.volume = volume1.value;
});

volume2.addEventListener('input', () => {
audio2.volume = volume2.value;
});

metronomeVolume.addEventListener('input', () => {
metronome.volume = metronomeVolume.value;
});

function playAll() {
audio1.play();
audio2.play();
startMetronome();
}

function pauseAll() {
audio1.pause();
audio2.pause();
metronome.pause();
}

function resetAll() {
audio1.currentTime = 0;
audio2.currentTime = 0;
metronome.currentTime = 0;
}

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 startLoop() {
loopStart = parseFloat(document.getElementById('loopStart').value) || 0;
loopEnd = parseFloat(document.getElementById('loopEnd').value) || 0;
if (loopEnd > loopStart) {
loopActive = true;
checkLoop(audio1);
checkLoop(audio2);
}
}

function stopLoop() {
loopActive = false;
}

function checkLoop(audio) {
if (!loopActive) return;
audio.addEventListener('timeupdate', function () {
if (audio.currentTime >= loopEnd) {
audio.currentTime = loopStart;
audio.play();
}
});
}

function startMetronome() {
metronome.play();
adjustMetronomeSpeed();
}

function adjustMetronomeSpeed() {
const bpm = metronomeSpeed.value;
const interval = 60 / bpm;
metronome.playbackRate = 1 / interval;
}

metronomeSpeed.addEventListener('input', adjustMetronomeSpeed);
</script>

</body>
</html>
 
"Spielerei" schreibt er... Mir fallen hier die Augen aus dem Kopf und er schreibt "Spielerei" :D

Das ist wirklich ganz erstaunlich! Das ist ja komplett aus Hüfte geschossen und bis auf verzichtbare Features ist alles abgedeckt.
Einzig der Fader, der "einhändig" zwischen "Track A" und "Track B" mischt, fehlt. Aber so, wie es da jetzt ist, könnte man schon damit arbeiten.

Aber um deine Frage zu beantworten: Ich Suche was für Windows. Idealerweise etwas, wo ich nicht im Quellcode rumpfuschen muss, um ein anderes Lied zu spielen. :stars:
Aber alle Achtung vor diesem Ansatz! Mit solchen Fertigkeiten kann man sich bestimmt für allerhand Situationen ne Extrawurst programmieren.
 

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 (B):</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>
 
Ich bin ein Fan von Audacity, kostet nix und hat sehr viele Möglichkeiten zur Bearbeitung, wie auch Tempo, Tonhöhe und vieles mehr.
Beide Tracks auf 2 Spuren laden und zB über Panoramaregler mischen.
 
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 (B):</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>
Der Vorteil dieses Ansatzes ist, dass es auf jedem Gerät läuft. Händie, iPad, Microwelle…. Wenn die Verbindung das hergibt, kann man es auch direkt vom Server aus laufen lassen.
@CPerschke programmierst du mir mal schnell Doom in HTML?
 
Der Vorteil dieses Ansatzes ist, dass es auf jedem Gerät läuft. Händie, iPad, Microwelle…. Wenn die Verbindung das hergibt, kann man es auch direkt vom Server aus laufen lassen.
@CPerschke programmierst du mir mal schnell Doom in HTML?
Ja, aber es fehlt schon dann komfort. Aber erstaunlich, was HTML / JS alles kann.

Ich bleib dann bei meiner Kombination aus SpectraLayers, Transcribe und Papier (zum raushören).
 
Zuletzt bearbeitet:
Aber erstaunlich, was HTML / JS alles kann.
Yeah! Ich komme selbst von der C Programmierung (Ende 80er/Anfang 90er), habe lange Zeit die Nase über HTML/ CSS3 / Javascript gerümpft (Kinderkram!) ... aber inzwischen programmiere ich Spass Demos nur noch fürn Browser, egal ob lokal oder Client/Server.

ist schön einfach ... und mit der Performance von Rechner heutzutage überhaupt kein Problem mehr für die meisten Anwendungen.
 

Beliebte Themen



Zurück
Oben Unten