angular - Att ställa in Tone.js vid knappklick misslyckas fortfarande med: The AudioContext was not allowed to start
Jag har en Angular-komponent som har en knapp för att starta en animation och samtidigt spela några toner varje gång ett nummer markeras
Jag ställer in tone.js-synt när knappen trycks, se escalaPentatonicaToggle, men jag får fortfarande ett fel om The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page
Varför får jag det felet även när ljudet försöker spelas upp efter en KLICK-händelse? Hur kan jag lösa det.
Jag har sett denna liknande fråga men erbjuder ett annat scenario Tone.js - AudioContext tilläts inte starta
Här är komponentlogiken
import { Component } from '@angular/core';
import { ElementoPentatonica, EscalaPentatonica, NotasEscalaPentatonica } from '../../models/EscalaPentatonica';
import { CommonModule } from '@angular/common';
import { ElementoPentatonicaComponent } from '../elemento-pentatonica/elemento-pentatonica.component';
import * as Tone from 'tone';
@Component({
selector: 'app-escala-pentatonica',
standalone: true,
imports: [CommonModule, ElementoPentatonicaComponent],
templateUrl: './escala-pentatonica.component.html',
styleUrl: './escala-pentatonica.component.css'
})
export class EscalaPentatonicaComponent {
escala: EscalaPentatonica;
highlightedIndex: number = 0;
timer: any;
lapse: number = 600;
running: boolean = false;
soundEnabled: boolean = true;
sonido = "LA";
start = 1;
lineasFlat: ElementoPentatonica[] = [];
synth: Tone.Synth | null = null;
constructor() {
this.escala = new EscalaPentatonica(this.start, NotasEscalaPentatonica.SI_MAYOR, this.sonido);
this.lineasFlat = this.escala.lineas.flat();
}
onSelectionChange(event: Event) {
this.stopAnimation();
this.start = Number((event.target as HTMLSelectElement).value);
this.escala = new EscalaPentatonica(this.start, NotasEscalaPentatonica.SI_MAYOR, this.sonido);
}
ngOnInit() {
}
async escalaPentatonicaToggle() {
await Tone.start();
if (!this.running) {
await this.startAnimation();
} else {
this.stopAnimation();
}
this.running = !this.running;
}
async startAnimation() {
this.synth = new Tone.Synth().toDestination();
this.highlightedIndex = 0;
this.startTimer();
}
stopAnimation() {
if (this.timer) {
clearInterval(this.timer);
}
if (this.synth) {
this.synth.dispose();
this.synth = null;
}
}
ngOnDestroy() {
this.stopAnimation();
}
startTimer() {
this.timer = setInterval(() => {
this.highlightedIndex = (this.highlightedIndex + 1) % this.lineasFlat.length;
this.playSound(this.highlightedIndex);
}, this.lapse);
}
getIndex(i: number, j: number): number {
let index = 0;
for (let x = 0; x < i; x++) {
index += this.escala.lineas[x].length;
}
return index + j;
}
playSound(index: number) {
let note = this.escala.notas[this.lineasFlat[index].numero - this.escala.start];
if (this.synth) {
console.log('Playing note:', note);
this.synth.triggerAttackRelease(note, '2s');
}
}
}
och här är html
<div class="escala-container">
<select #escalaSelect (change)="onSelectionChange($event)">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<button class="nextButton" (click)="escalaPentatonicaToggle()">
{{ running ? 'DETENER' : 'INICIAR' }}
</button>
<div *ngFor="let linea of escala.lineas; let i = index" class="linea" [style.margin-left.px]="(4 - i) * 20">
<app-elemento-pentatonica *ngFor="let elemento of linea; let j = index" [numero]="elemento.numero"
[sonido]="elemento.sonido" [highlight]="highlightedIndex === getIndex(i, j)">
</app-elemento-pentatonica>
</div>
</div>
Svar #1
Problem löst, orsaken "Fliken var avstängd". Ja, det är pinsamt ;-)
Även meddelandena i konsolen är VARNINGAR, inte fel, och ljudet spelas upp utan problem.
