W ostatnich miesiącach interfejs Web Audio API w WebKit stał się atrakcyjną platformą do tworzenia gier i aplikacji audio w internecie. Gdy deweloperzy zapoznają się z tymi materiałami, słyszę, że często zadają podobne pytania. Ta krótka aktualizacja ma na celu odpowiedzenie na niektóre z najczęściej zadawanych pytań, aby ułatwić Ci korzystanie z Web Audio API.
Pytanie: Pomoc, nie mogę wydawać dźwięków.
Odp.: jeśli nie znasz jeszcze interfejsu Web Audio API, zapoznaj się z samouczkiem na temat korzystania z niego lub obejrzyj film Erica o odtwarzaniu dźwięku na podstawie interakcji z użytkownikiem.
Pytanie: Ile kontekstów audio powinienem mieć?
Ogólnie zalecamy umieszczanie na stronie 1 elementu AudioContext
, a jeden kontekst audio może obejmować wiele połączonych z nim węzłów. Możesz umieścić na jednej stronie wiele kontekstów audio, ale może to wpłynąć na wydajność.
Pytanie: mam AudioBufferSourceNode, który został właśnie odtworzony za pomocą noteOn()
. Chcę go odtworzyć ponownie, ale noteOn()
nic nie robi. Dlaczego
O: Po zakończeniu odtwarzania przez węzeł źródłowy nie można go odtworzyć ponownie. Aby odtworzyć podstawowy bufor, utwórz nowy obiekt AudioBufferSourceNode
i wywołaj funkcję noteOn()
.
Tworzenie kopii węzła źródłowego może wydawać się nieefektywne, ale węzły źródłowe są w dużej mierze zoptymalizowane pod kątem tego wzorca. Jeśli zachowasz uchwyt do bufora audio, nie musisz wysyłać kolejnego żądania do zasobu, aby ponownie odtworzyć ten sam dźwięk. Jeśli chcesz powtórzyć ten wzór, użyj prostej funkcji pomocniczej, takiej jak playSound(buffer)
.
P: Dlaczego podczas odtwarzania dźwięku za każdym razem musisz tworzyć nowy węzeł źródła?
Odp.: Idea tej architektury polega na oddzieleniu zasobu audio od stanu odtwarzania. Jeśli posłużymy się analogią do gramofonu, bufory są analogiczne do płyt, a źródła do igieł. Ten wzór jest niezbędny, ponieważ wiele aplikacji odtwarza jednocześnie wiele wersji tego samego bufora.
P: Jak mogę przetworzyć dźwięk z tagów audio
i video
?
O: MediaElementAudioSourceNode
jest w fazie opracowywania. Gdy będzie dostępna, będzie działać w przybliżeniu w ten sposób (dodawanie efektu filtra do próbki odtwarzanej za pomocą tagu audio):
<audio src="sounds/sample.wav" controls>
var audioElement = document.querySelector('audio');
var mediaSourceNode = context.createMediaElementSource(audioElement);
mediaSourceNode.connect(filter);
filter.connect(context.destination);
Ta funkcja jest śledzona w tym raporcie o błędach. Pamiętaj, że w tej konfiguracji nie musisz wywoływać funkcji mediaSourceNode.noteOn()
, ponieważ odtwarzanie kontroluje tag audio.
P: Kiedy mogę usłyszeć dźwięk z mikrofonu?
Odp.: część dotycząca wejścia audio zostanie zaimplementowana w ramach WebRTC za pomocą getUserMedia
i będzie dostępna jako specjalny węzeł źródłowy w Web Audio API. Będzie ona działać w połączeniu z createMediaElementSource
.
P: Jak sprawdzić, kiedy AudioSourceNode
zakończyło odtwarzanie?
ODP: obecnie musisz użyć timera JavaScript, ponieważ interfejs Web Audio API nie obsługuje tej funkcji. Oto fragment kodu z samouczka Pierwsze kroki z interfejsem Web Audio API:
// Assume source and buffer are previously defined.
source.noteOn(0);
var timer = setTimeout(function() {
console.log('playback finished');
}, buffer.duration * 1000);
Istnieje otwarta usterka dotycząca Web Audio API, która ma na celu wdrożenie bardziej dokładnego wywołania zwrotnego.
Pytanie: wczytywanie dźwięków powoduje zablokowanie całego wątku interfejsu, przez co interfejs przestaje odpowiadać. Pomocy!**
Odp.: użyj interfejsu API decodeAudioData
do ładowania asynchronicznego, aby uniknąć blokowania wątku głównego. Zobacz ten przykład.
P: Czy interfejs Web Audio API może być używany do przetwarzania dźwięku szybciej niż w czasie rzeczywistym?
Odp.: tak, pracujemy nad rozwiązaniem. Sprawdź ją za jakiś czas!
Pyt.: Mam świetną aplikację korzystającą z interfejsu Web Audio API, ale gdy karta, na której jest uruchomiona, przechodzi do działania w tle, dźwięki stają się dziwne.
Odp.: Prawdopodobnie używasz setTimeouts
, które działa inaczej, gdy strona jest w tle. W przyszłości interfejs Web Audio API będzie mógł wywoływać funkcję zwrotną w określonych momentach za pomocą wewnętrznego timera dźwięku internetowego (atrybut context.currentTime
). Więcej informacji znajdziesz w tej prośbie o funkcję.
Zazwyczaj warto zatrzymać odtwarzanie, gdy aplikacja przechodzi w stan w tle. Możesz wykryć, kiedy strona zostaje przeniesiona na drugi plan, korzystając z interfejsu Page Visibility API.
P: Jak za pomocą interfejsu Web Audio API zmienić ton dźwięku?
Odp.: zmień playbackRate
na węźle źródłowym.
P: Czy mogę zmienić ton bez zmiany szybkości?
Odp.: interfejs Web Audio API może mieć PitchNode w kontekście audio, ale jest to trudne do wdrożenia. Dzieje się tak, ponieważ w społeczności zajmującej się dźwiękiem nie ma prostego algorytmu przesunięcia wysokości dźwięku. Znane techniki powodują powstawanie artefaktów, zwłaszcza w przypadku dużych zmian wysokości dźwięku. Istnieją 2 sposoby rozwiązania tego problemu:
- algorytmy czasu, które powodują artefakty echa powtarzających się segmentów;
- Techniki dotyczące częstotliwości, które powodują artefakty dźwiękowe.
Chociaż nie ma domyślnego węzła do stosowania tych technik, możesz to zrobić za pomocą węzła JavaScriptAudioNode
. Jako punkt wyjścia możesz użyć tego fragmentu kodu.
P: Jak utworzyć AudioContext z wybranym przeze mnie współczynnikiem próbkowania?
O: Obecnie nie obsługujemy tej funkcji, ale pracujemy nad nią. Zobacz prośbę o dodanie tej funkcji.
Jeśli masz dodatkowe pytania, zadaj je na StackOverflow, używając tagu web-audio.