Efekty dźwiękowe w JavaScript / HTML5

Używam HTML5 do programowania gier; przeszkodą, na którą teraz natknąłem się, jest sposób odtwarzania efektów dźwiękowych.

Specyficzne wymagania są nieliczne:

  • odtwarzaj i miksuj wiele dźwięków,
  • odtwarzanie tej samej próbki wiele razy, możliwe nakładanie się odtworzeń,
  • Przerwanie odtwarzania próbki w dowolnym momencie,
  • najlepiej odtwarzać pliki WAV zawierające (niskiej jakości) raw PCM, ale mogę je oczywiście przekonwertować.

Moim pierwszym podejściem było użyj elementu HTML5 <audio> i zdefiniuj wszystkie efekty dźwiękowe na mojej stronie. Firefox odtwarza pliki WAV, ale wywołanie #play wiele razy tak naprawdę nie odtworzy próbki wiele razy. Z mojego zrozumienia specyfikacji HTML5, element <audio> śledzi również stan odtwarzania, więc to wyjaśnia dlaczego.

Moją natychmiastową myślą było sklonowanie elementów audio, więc stworzyłem następującą małą bibliotekę JavaScript, aby to zrobić dla mnie (zależy od jQuery):

var Snd = {
  init: function() {
    $("audio").each(function() {
      var src = this.getAttribute('src');
      if (src.substring(0, 4) !== "snd/") { return; }
      // Cut out the basename (strip directory and extension)
      var name = src.substring(4, src.length - 4);
      // Create the helper function, which clones the audio object and plays it
      var Constructor = function() {};
      Constructor.prototype = this;
      Snd[name] = function() {
        var clone = new Constructor();
        clone.play();
        // Return the cloned element, so the caller can interrupt the sound effect
        return clone;
      };
    });
  }
};

Więc teraz mogę zrobić Snd.boom(); z konsolę Firebug I play snd/boom.wav, ale nadal nie mogę odtworzyć tej samej próbki wiele razy. Wydaje się, że element <audio> jest bardziej funkcją streamingu niż czymś, z czym można odtwarzać efekty dźwiękowe.

Czy istnieje sprytny sposób, aby to się stało, że brakuje mi, najlepiej używając tylko HTML5 i JavaScript?

Powinienem również wspomnieć, że moim środowiskiem testowym jest Firefox 3.5 na Ubuntu 9.10. Inne przeglądarki, które wypróbowałem-Opera , Midori, Chromium, Epiphany-produkowane różne wyniki. Niektórzy nic nie grają, a niektórzy rzucają wyjątki.

Author: vaxquis, 2009-12-19

16 answers

HTML5 Audio obiekty

Nie musisz przejmować się <audio> elementami. HTML 5 pozwala na dostęp Audio obiekty bezpośrednio:

var snd = new Audio("file.wav"); // buffers automatically when created
snd.play();

Nie ma wsparcia dla miksowania w obecnej wersji spec.

Aby odtwarzać ten sam dźwięk wiele razy, Utwórz wiele instancji obiektu Audio. Możesz również ustawić snd.currentTime=0 na obiekcie po zakończeniu odtwarzania.


Ponieważ konstruktor JS nie obsługuje elementów awaryjnych <source>, należy użyć

(new Audio()).canPlayType("audio/ogg; codecs=vorbis")

Aby sprawdzić, czy przeglądarka obsługuje Ogg Vorbis.


Jeśli piszesz grę lub aplikację muzyczną (więcej niż tylko odtwarzacz), będziesz chciał użyć bardziej zaawansowanego Web Audio API, który jest teraz obsługiwany przez większość przeglądarek.

 435
Author: Kornel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-30 07:30:39

Wyjec.js

Do tworzenia gier jednym z najlepszych rozwiązań jest użycie biblioteki, która rozwiązuje wiele problemów, z którymi stykamy się pisząc kod dla sieci, takich jak howler.js . wyjec.js abstrahuje wielki (ale niskopoziomowy) Web Audio API w łatwy w użyciu framework. Jeśli Web Audio API jest niedostępne, spróbuje wrócić do HTML5 Audio Element.

var sound = new Howl({
  urls: ['sound.mp3', 'sound.ogg']
}).play();
// it also provides calls for spatial/3d audio effects (most browsers)
sound.pos3d(0.1,0.3,0.5);

Wad.js

Kolejną wielką biblioteką jest wad.js , które jest szczególnie przydatny do produkcji dźwięku syntezatorów, takich jak muzyka i efekty. Na przykład:

var saw = new Wad({source : 'sawtooth'})
saw.play({
    volume  : 0.8,
    wait    : 0,     // Time in seconds between calling play() and actually triggering the note.
    loop    : false, // This overrides the value for loop on the constructor, if it was set. 
    pitch   : 'A4',  // A4 is 440 hertz.
    label   : 'A',   // A label that identifies this note.
    env     : {hold : 9001},
    panning : [1, -1, 10],
    filter  : {frequency : 900},
    delay   : {delayTime : .8}
})

Dźwięk do gier

Kolejna biblioteka podobna do Wad.js to " Sound for Games ", ma większy nacisk na produkcję efektów, zapewniając jednocześnie podobny zestaw funkcji poprzez stosunkowo wyraźne (i być może bardziej zwięzłe odczucia) API:

function shootSound() {
  soundEffect(
    1046.5,           //frequency
    0,                //attack
    0.3,              //decay
    "sawtooth",       //waveform
    1,                //Volume
    -0.8,             //pan
    0,                //wait before playing
    1200,             //pitch bend amount
    false,            //reverse bend
    0,                //random pitch range
    25,               //dissonance
    [0.2, 0.2, 2000], //echo array: [delay, feedback, filter]
    undefined         //reverb array: [duration, decay, reverse?]
  );
}

Podsumowanie

Każda z tych bibliotek jest warta obejrzenia, niezależnie od tego, czy chcesz odtworzyć pojedynczy dźwięk lub stwórz własny edytor muzyczny oparty na html, generator efektów lub grę wideo.

 25
Author: d13,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-02 03:16:33

Możesz również użyć tego do wykrycia dźwięku HTML 5 w niektórych przypadkach:

Http://diveintohtml5.ep.io/everything.html

HTML 5 js Detect function

function supportsAudio()
{
    var a = document.createElement('audio'); 
    return !!(a.canPlayType && a.canPlayType('audio/mpeg;').replace(/no/, ''));
}
 9
Author: Rob,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-05 20:28:32

Oto jedna z metod pozwalających na jednoczesne odtwarzanie nawet tego samego dźwięku. Połącz z preloaderem i gotowe. Działa to przynajmniej z Firefoksem 17.0.1, nie testowałem go jeszcze z niczym innym.

// collection of sounds that are playing
var playing={};
// collection of sounds
var sounds={step:"knock.ogg",throw:"swing.ogg"};

// function that is used to play sounds
function player(x)
{
    var a,b;
    b=new Date();
    a=x+b.getTime();
    playing[a]=new Audio(sounds[x]);
    // with this we prevent playing-object from becoming a memory-monster:
    playing[a].onended=function(){delete playing[a]};
    playing[a].play();
}

Połącz to z klawiszem klawiatury i ciesz się:

player("step");
 5
Author: F-3000,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-24 14:04:31

Brzmi jak to, czego chcesz, to Dźwięki wielokanałowe. Załóżmy, że masz 4 kanały (jak w naprawdę starych grach 16-bitowych), nie mam rundy do gry z funkcją audio HTML5 jeszcze, ale nie potrzebujesz tylko 4 elementów i cyklu, który jest używany do odtwarzania następnego efektu dźwiękowego? Próbowałeś tego? Co się dzieje? Jeśli to działa: aby odtworzyć więcej dźwięków jednocześnie, dodaj więcej elementów .

Robiłem to wcześniej bez elementu HTML5 , używając trochę Obiekt Flash z http://flash-mp3-player.net / - napisałem quiz muzyczny ( http://webdeavour.appspot.com / ) i używała go do odtwarzania klipów muzycznych, gdy użytkownik kliknął przycisk pytania. Początkowo miałem jeden Odtwarzacz na pytanie, i można było odtwarzać je nad sobą, więc zmieniłem go tak, że był tylko jeden odtwarzacz, który wskazywałem na różne Klipy muzyczne.

 4
Author: Lee Kowalkowski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-18 21:43:14

Spójrz na jai (-> lustro) (javascript audio interface) site. Patrząc na ich źródło, wydają się wywoływać play() wielokrotnie i wspominają, że ich biblioteka może być odpowiednia do użycia w grach opartych na HTML5.

Możesz odpalić wiele zdarzeń audio jednocześnie, które mogą być wykorzystane do tworzenia gier Javascript, lub mając głos mówiący nad niektórymi muzyka w tle

 4
Author: Raul Agrait,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-22 15:26:41

Aby odtworzyć tę samą próbkę wiele razy, czy nie byłoby możliwe zrobić coś takiego:

e.pause(); // Perhaps optional
e.currentTime = 0;
e.play();

(e jest elementem audio)

Być może całkowicie źle zrozumiałem twój problem, czy chcesz, aby efekt dźwiękowy grał wiele razy w tym samym czasie? Więc to jest całkowicie błędne.

 3
Author: adamse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-19 20:19:58

Mam pomysł. Załaduj cały dźwięk dla określonej klasy dźwięków do pojedynczego elementu audio, w którym dane src są wszystkimi samplami w sąsiednim pliku audio (prawdopodobnie potrzebujesz ciszy między nimi, aby można było złapać i wyciąć próbki z limitem czasu z mniejszym ryzykiem krwawienia do następnej próbki). Następnie Szukaj próbki i odtwarzaj ją w razie potrzeby.

Jeśli potrzebujesz więcej niż jednego z nich do odtwarzania, możesz utworzyć dodatkowy element audio z tym samym src, aby jest w pamięci podręcznej. Teraz faktycznie masz wiele "ścieżek". Możesz używać grup utworów z ulubionym schematem alokacji zasobów, takim jak Round Robin itp.

Możesz również określić inne opcje, takie jak kolejkowanie dźwięków do ścieżki do odtworzenia, gdy zasób stanie się dostępny lub wycinanie aktualnie odtwarzanej próbki.

 3
Author: digitalicarus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-30 13:48:17

Http://robert.ocallahan.org/2011/11/latency-of-html5-sounds.html

Http://people.mozilla.org / ~roc/audio-latency-repeating.html

Działa OK w Firefoksie i Chrome dla mnie.

Aby zatrzymać dźwięk, który zacząłeś, zrób var sound = document.getElementById ("strzał").cloneNode (true); dźwięk.play(); i Później dźwięk.pause ();

 2
Author: Robert O'Callahan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-11 23:58:17

Zalecałbym użycie SoundJS, biblioteki, którą pomogłem rozwinąć. Pozwala na napisanie pojedynczej bazy kodu, która działa wszędzie, z SoundJS wybierając audio web, audio html lub flash odpowiednio.

To pozwoli Ci zrobić wszystko, co chcesz:

  • odtwarzaj i miksuj wiele dźwięków,
  • odtwarzanie tej samej próbki wiele razy, możliwe nakładanie się odtworzeń
  • Przerwanie odtwarzania próbki w dowolnym punkcie
  • odtwarzanie plików WAV zawierających (w zależności od obsługi przeglądarki)

Mam nadzieję, że to pomoże.

 2
Author: OJay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-03 18:21:14

Nie jest możliwe wykonywanie gry wieloostrzowej z pojedynczym elementem <audio>. Musisz użyć do tego wielu elementów.

 1
Author: Eli Grey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-19 23:04:48

Natknąłem się na to podczas programowania generatora kart muzycznych. Zaczęło się od różnych bibliotek, ale za każdym razem była jakaś usterka. Opóźnienie przy normalnej implementacji audio było złe, brak wielokrotnych odtworzeń... ostatecznie skończyło się na użyciu biblioteki lowlag + soundmanager:

Http://lowlag.alienbill.com / oraz http://www.schillmania.com/projects/soundmanager2/

Możesz sprawdzić realizację tutaj: http://musicbox.grit.it/

Wygenerowałem pliki wav + ogg do odtwarzania w wielu przeglądarkach. Ten odtwarzacz musicbox działa responsywnie na ipad, iphone, Nexus, mac, pc,... mi pasuje.

 1
Author: Grit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-01 06:24:47

Wiem, że to totalny hack, ale pomyślałem, że powinienem dodać tę przykładową bibliotekę audio open source, którą umieściłem na GitHubie jakiś czas temu...

Https://github.com/run-time/jThump

Po kliknięciu poniższego linku wpisz klawisze home row, aby odtworzyć bluesowy riff (wpisz również kilka klawiszy jednocześnie itp.)

Przykładowe Użycie biblioteki jThump > > http://davealger.com/apps/jthump/

W zasadzie działa poprzez tworzenie niewidocznych <iframe> elementów ładujących stronę, która odtwarza dźwięk na ekranie ().

To z pewnością nie jest idealne , ale można +1 To rozwiązanie oparte na samej kreatywności (i fakt, że jest to open source i działa w każdej przeglądarce, że próbowałem go na) mam nadzieję, że to daje komuś innemu poszukiwania jakieś pomysły przynajmniej.

:)

 0
Author: DaveAlger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-27 22:29:16

Wybrana odpowiedź będzie działać we wszystkim oprócz IE. Napisałem tutorial Jak to działa cross browser = http://www.andy-howard.com/how-to-play-sounds-cross-browser-including-ie/index.html

Oto funkcja, którą napisałem;

function playSomeSounds(soundPath)
 {

 var trident = !!navigator.userAgent.match(/Trident\/7.0/);
 var net = !!navigator.userAgent.match(/.NET4.0E/);
 var IE11 = trident && net
 var IEold = ( navigator.userAgent.match(/MSIE/i) ? true : false );
 if(IE11 || IEold){
 document.all.sound.src = soundPath;
 }
 else
 {
 var snd = new Audio(soundPath); // buffers automatically when created
 snd.play();
 }
 };

Musisz również dodać następujący tag do strony html:

<bgsound id="sound">

Wreszcie możesz wywołać funkcję i po prostu przejść przez ścieżkę tutaj:

playSomeSounds("sounds/welcome.wav");
 0
Author: Andrew Junior Howard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-12 12:05:02

Zawsze możesz spróbować AudioContext ma ograniczone wsparcie, ale jest częścią projektu roboczego web audio api. Może warto, jeśli planujesz wydać coś w przyszłości. A jeśli programujesz tylko dla chrome i Firefox jesteś złoty.

 0
Author: haelmic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-29 03:23:52