Signatur
Beschreibung
Die schreibgeschützte Eigenschaft currentTime gibt eine Gleitkommazahl (double) zurück. Sie zeigt an, wie viele Sekunden seit dem Start der Audiotimeline des Kontextes vergangen sind. Beim Erzeugen eines AudioContext steht sie auf 0 und steigt in Blöcken der Audio-Hardware an, sobald der Kontext läuft (state === "running"). Solange der Kontext angehalten (suspended) oder geschlossen (closed) ist, bleibt der Wert stehen.
Wichtig ist sie vor allem für das Planen von Audioereignissen. Methoden wie AudioScheduledSourceNode.start() und stop() sowie Automationsmethoden wie AudioParam.setValueAtTime() oder linearRampToValueAtTime() erwarten Zeitangaben in genau dieser Zeitbasis. Mit ctx.currentTime + 0.5 plant man also ein Ereignis eine halbe Sekunde in der Zukunft, und zwar sample-genau und unabhängig von Verzögerungen im Haupt-Thread.
Die Audiouhr ist nicht an Date.now() oder performance.now() gekoppelt. Sie läuft im Takt der Audio-Hardware und kann leicht von der Systemuhr abweichen. Wer Audio und Grafik synchronisieren will, nutzt beim AudioContext besser getOutputTimestamp(). Bei einem OfflineAudioContext läuft currentTime nur während des Renderns und steigt dabei schneller als in Echtzeit.
Rückgabewert
≥ 0). Der Wert ist schreibgeschützt und nimmt nie ab.Beispiele
Aktuelle Audiozeit auslesen
const ctx = new AudioContext();
console.log(ctx.currentTime); // direkt nach dem Erzeugen
document.querySelector('#start').addEventListener('click', async () => {
await ctx.resume(); // Autoplay-Richtlinie: erst nach einer Benutzeraktion
setTimeout(() => {
console.log(`Audiozeit: ${ctx.currentTime.toFixed(3)} s`);
}, 1000);
});
Ton exakt planen: Start in 0,5 s, Dauer 1 s
const ctx = new AudioContext();
const playBeep = (frequency = 440) => {
const osc = ctx.createOscillator();
const gain = ctx.createGain();
osc.frequency.value = frequency;
osc.connect(gain).connect(ctx.destination);
const t = ctx.currentTime + 0.5; // Startzeitpunkt in der Audiotimeline
gain.gain.setValueAtTime(0, t);
gain.gain.linearRampToValueAtTime(0.3, t + 0.05); // sanftes Einblenden
gain.gain.linearRampToValueAtTime(0, t + 1); // Ausblenden
osc.start(t);
osc.stop(t + 1);
};
document.querySelector('#beep').addEventListener('click', () => playBeep(660));
Metronom mit Look-ahead-Planung
const ctx = new AudioContext();
const bpm = 120;
const interval = 60 / bpm; // Sekunden pro Schlag
const lookAhead = 0.1; // so weit im Voraus planen (s)
let nextNote = ctx.currentTime + 0.1;
const click = (time) => {
const osc = ctx.createOscillator();
osc.frequency.value = 1000;
osc.connect(ctx.destination);
osc.start(time);
osc.stop(time + 0.03);
};
// Der Timer im Haupt-Thread darf ungenau sein, weil die Töne
// über currentTime sample-genau geplant werden.
const scheduler = () => {
while (nextNote < ctx.currentTime + lookAhead) {
click(nextNote);
nextNote += interval;
}
};
const timerId = setInterval(scheduler, 25);
// Stoppen: clearInterval(timerId);
currentTime im OfflineAudioContext
const offline = new OfflineAudioContext(1, 44100 * 2, 44100); // 2 s Mono
const osc = offline.createOscillator();
osc.connect(offline.destination);
osc.start(0);
console.log('Vor dem Rendern:', offline.currentTime);
const buffer = await offline.startRendering();
console.log('Nach dem Rendern:', offline.currentTime);
console.log('Pufferlänge:', buffer.duration, 's');
// Wichtig · Fallstricke
- Autoplay-Richtlinien: Ein ohne Benutzeraktion erzeugter
AudioContextstartet in vielen Browsern im Zustandsuspended. Dann bleibtcurrentTimeauf0stehen, bisresume()aufgerufen wird. - Nicht in der Vergangenheit planen: Liegt eine Zeitangabe für
start()odersetValueAtTime()untercurrentTime, wird das Ereignis sofort ausgeführt. Deshalb immer einen kleinen Vorlauf einplanen (z. B.+ 0.05). - Blockweise Aktualisierung: Der Wert springt in Schritten eines Render-Quantums (meist 128 Samples, bei 48 kHz etwa 2,7 ms) oder in noch größeren Hardware-Puffern weiter. Für Grafik-Synchronisation eignen sich
AudioContext.getOutputTimestamp()undoutputLatencybesser. - Datenschutz: Wegen Fingerprinting- und Timing-Angriffen runden manche Browser (z. B. Firefox mit
privacy.reduceTimerPrecision) den Wert gröber. - Kein setInterval-Ersatz:
setTimeoutundsetIntervalsind für das Timing von Audio zu ungenau. Sie eignen sich nur, um Ereignisse vorab übercurrentTimeeinzuplanen (Look-ahead-Muster). - Wird unterstützt in allen aktuellen Browsern (Chrome, Edge, Firefox, Safari inkl. iOS). Sehr alte Safari-Versionen benötigten
webkitAudioContext.