983

I am making a game with HTML5 and JavaScript.

How could I play game audio via JavaScript?

Flip
  • 6,233
  • 7
  • 46
  • 75
rshea0
  • 11,769
  • 9
  • 27
  • 40
  • 13
    Since it's html5, there's ` – Marc B Feb 23 '12 at 18:50
  • 17
    I bet you're wondering where the documentation is for all of the audio methods: http://stackoverflow.com/questions/4589451/documentation-for-javascript-audio-methods – Bryan Downing Feb 23 '12 at 19:08

22 Answers22

1899

If you don't want to mess with HTML elements:

var audio = new Audio('audio_file.mp3');
audio.play();

function play() {
  var audio = new Audio('https://interactive-examples.mdn.mozilla.net/media/cc0-audio/t-rex-roar.mp3');
  audio.play();
}
<button onclick="play()">Play Audio</button>

This uses the HTMLAudioElement interface, which plays audio the same way as the <audio> element.


If you need more functionality, I used the howler.js library and found it simple and useful.

<script src="https://cdnjs.cloudflare.com/ajax/libs/howler/2.1.1/howler.min.js"></script>
<script>
    var sound = new Howl({
      src: ['https://interactive-examples.mdn.mozilla.net/media/cc0-audio/t-rex-roar.mp3'],
      volume: 0.5,
      onend: function () {
        alert('Finished!');
      }
    });
    sound.play()
</script>
Tharindu Sathischandra
  • 1,654
  • 1
  • 15
  • 37
Uri
  • 25,622
  • 10
  • 45
  • 72
  • 14
    This method works for playing mp3 but not for wav files. Is there some way to play wav files? – guagay_wk Apr 24 '14 at 02:21
  • 19
    @user3293156 This method supports the same formats as HTML5’s ` – Rory O'Kane Mar 15 '15 at 14:18
  • 426
    @RoryO'Kane so everyone can play microsoft's audio format except microsoft? lol – Dave Cousineau Mar 29 '15 at 00:04
  • 12
    Couple caveats: (1) [Firefox won't play mp3](http://stackoverflow.com/questions/4923136/why-doesnt-firefox-support-mp3-file-format-in-audio). You'll need an ogg file instead. (2) [Safari/iOS won't play if you're serving the content over https](http://stackoverflow.com/a/30248688/777443). You'll need to have a valid certificate. – Peter Nov 29 '15 at 13:57
  • 5
    Chrome (48.0.2564.95) on Android 4.4.2.: **Failed to execute 'play' on 'HTMLMediaElement': API can only be initiated by a user gesture.** – Tamás Bolvári Feb 19 '16 at 21:07
  • 2
    Can I control the volume? – Jim Oct 22 '16 at 09:46
  • Sorry I know this seems like a dumb question... But since Javascript is confined to the browser, what goes in place of `'audio_file.mp3'`? – Musixauce3000 Dec 14 '16 at 13:53
  • 1
    @Musixauce3000 this is a relative path to the file / url. – Uri Dec 17 '16 at 15:25
  • 2
    howler.js is the kind of random finding that I just love here in this community. – D. Melo Mar 23 '17 at 23:19
  • Hum just saying while walking around here, you're doing like `HTMLAudioElement` and ` – Kaiido Jun 16 '17 at 13:45
  • 21
    Notice that from april 2018 on Chrome will not play audio files unless the user has at least clicked once in the document. See [here](https://developers.google.com/web/updates/2017/09/autoplay-policy-changes). – Nils Lindemann Aug 27 '18 at 21:46
  • howler.js is a great suggestion - it's easy to use, cross-platform, and performant – tonethar Sep 30 '18 at 19:52
  • 1
    Non howler code causes this error in Chrome dev tools console: `Uncaught (in promise) DOMException` in Chrome Version 74.0.3729.169 – user1063287 Jun 08 '19 at 01:46
  • 1
    Update - Oh just tried [howler.js](https://howlerjs.com) with simple node import `import {Howl, Howler} from 'howler';` and `var sound = new Howl( { src: ['/path/sound.mp3'] }); sound.play();` - no errors and works great! All per docs here: https://github.com/goldfire/howler.js – user1063287 Jun 08 '19 at 02:02
  • Update 2 - For reference, sometimes getting this error: `howler.js:497 The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page` - I think just after page reload though. – user1063287 Jun 08 '19 at 02:19
  • @Uri It does not seem to work on iPhone Safari. Any idea? – Basj Feb 16 '20 at 14:24
  • Ok, let's say it is a mobile device with two speakers, loudspeaker and the phone speaker you hold on your ear while on a call, can one select the speaker to output the audio? – sçuçu Mar 22 '20 at 08:24
  • What should we do with the new audio policy that they brought? I get the error ```Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first``` I haven't find the answer yet – Panagiss May 26 '20 at 13:23
  • Is it possible to play the sound through mobile's speakers instead from Media? – Raz Buchnik Jun 26 '20 at 11:10
  • with "howler.js", one thing I could not figure out is why it has a big delay when playing audio streaming on Google Chrome, it plays instantly on Firefox. – Root Loop Mar 30 '21 at 01:04
  • Do I need to remove that element somehow once I'm done playing it? (like 'audio.destroy()'? I wouldn't want any memory leaks. – Glenn Carver Jan 31 '22 at 17:00
  • I copied and pasted this exact code into my site and for over an hour was fiddling but couldn't even get an error message. Finally I noticed a tiny 'no sound' icon where my favicon icon should be, as well as at the beginning of the URL. Clicking on this revealed that my settings disallowed sound by default, not matter how much interaction! – Andrei Cleland Sep 16 '22 at 21:16
  • Perfect! Thanks. Working much better than html I was using because I need dynamic events inside of a blazor dom. This works great. – Cobysan Oct 11 '22 at 18:48
  • This will only work if the code runs on an event triggered by the user. If this runs on a page load event, for example, you will get a `DOMException`. – Leonardo Raele Dec 29 '22 at 22:12
218

It's easy, just get your audio element and call the play() method:

document.getElementById('yourAudioTag').play();

Check out this example: http://www.storiesinflight.com/html5/audio.html

This site uncovers some of the other cool things you can do such as load(), pause(), and a few other properties of the audio element.

Obsidian Age
  • 41,205
  • 10
  • 48
  • 71
shanabus
  • 12,989
  • 6
  • 52
  • 78
  • this works also on iOS without UI interfaction (put audio tag with autoplay and muted) then set muted false and call play – luky Nov 09 '20 at 11:49
  • 2
    It cannot be used in a function which activates using `onload`, see [this](https://developers.google.com/web/updates/2017/09/autoplay-policy-changes). However, it worked well for me using `onclick`. The user needs first to interact with a page in order to play a sound (this is the regular, expected and user-friendly behavior). – BarryCap Jul 04 '21 at 22:15
  • 1
    It WAS easy but not now ;) – Reza Dec 20 '21 at 16:36
56

This is a quite old question but I want to add some useful info. The topic starter has mentioned that he is "making a game". So for everybody who needs audio for game development there is a better choice than just an <audio> tag or an HTMLAudioElement. I think you should consider the use of the Web Audio API:

While audio on the web no longer requires a plugin, the audio tag brings significant limitations for implementing sophisticated games and interactive applications. The Web Audio API is a high-level JavaScript API for processing and synthesizing audio in web applications. The goal of this API is to include capabilities found in modern game audio engines and some of the mixing, processing, and filtering tasks that are found in modern desktop audio production applications.

Konstantin Smolyanin
  • 17,579
  • 12
  • 56
  • 56
  • 1
    This should be the accepted answer here. Especially for game development. The example there is pretty easy to follow. – birgersp Aug 17 '20 at 18:18
39

http://www.schillmania.com/projects/soundmanager2/

SoundManager 2 provides a easy to use API that allows sound to be played in any modern browser, including IE 6+. If the browser doesn't support HTML5, then it gets help from flash. If you want stricly HTML5 and no flash, there's a setting for that, preferFlash=false

It supports 100% Flash-free audio on iPad, iPhone (iOS4) and other HTML5-enabled devices + browsers

Use is as simple as:

<script src="soundmanager2.js"></script>
<script>
    // where to find flash SWFs, if needed...
    soundManager.url = '/path/to/swf-files/';

    soundManager.onready(function() {
        soundManager.createSound({
            id: 'mySound',
            url: '/path/to/an.mp3'
        });

        // ...and play it
        soundManager.play('mySound');
    });
</script>

Here's a demo of it in action: http://www.schillmania.com/projects/soundmanager2/demo/christmas-lights/

LordZardeck
  • 7,953
  • 19
  • 62
  • 119
  • I tried the demo in both Safari and Chrome (latest versions, 2022) in macos, and there's no sound. – endavid Jan 04 '22 at 23:40
  • 4
    @endavid This is a 10 year old answer, and I wouldn't recommend it anymore. Use Uri's accepted answer above: https://stackoverflow.com/a/18628124 – LordZardeck Jan 06 '22 at 00:20
25

Easy with Jquery

// set audio tags with no preload

<audio class="my_audio" controls preload="none">
    <source src="audio/my_song.mp3" type="audio/mpeg">
    <source src="audio/my_song.ogg" type="audio/ogg">
</audio>

// add jquery to load

$(".my_audio").trigger('load');

// write methods for playing and stopping

function play_audio(task) {
      if(task == 'play'){
           $(".my_audio").trigger('play');
      }
      if(task == 'stop'){
           $(".my_audio").trigger('pause');
           $(".my_audio").prop("currentTime",0);
      }
 }

// decide how to control audio

<button onclick="play_audio('play')">PLAY</button>
<button onclick="play_audio('stop')">STOP</button>

EDIT

To address @stomy's question, here is how you would use this approach to play a playlist:

Set your songs in an object:

playlist = {
    'song_1' : 'audio/splat.mp3',
    'song_2' : 'audio/saw.mp3',
    'song_3' : 'audio/marbles.mp3',
    'song_4' : 'audio/seagulls.mp3',
    'song_5' : 'audio/plane.mp3'
}

Use the trigger and play functions as before:

$(".my_audio").trigger('load');

function play_audio(task) {
      if(task == 'play'){
           $(".my_audio").trigger('play');
      }
      if(task == 'stop'){
           $(".my_audio").trigger('pause');
           $(".my_audio").prop("currentTime",0);
      }
 }

Load the first song dynamically:

keys = Object.keys(playlist);
$('.my_audio').append("<source id='sound_src' src=" + playlist[keys[0]] + " type='audio/mpeg'>");

Reset the audio source to the next song in the playlist, when the current song ends:

count = 0; 
$('.my_audio').on('ended', function() { 
   count++;  
   $("#sound_src").attr("src", playlist[keys[count]])[0];
   $(".my_audio").trigger('load');
   play_audio('play');
});

See here for an example of this code in action.

Cybernetic
  • 12,628
  • 16
  • 93
  • 132
  • This plays all audio tags with class = "my_audio" at the same time. How do you play one after another (in a play list)? – stomy Nov 15 '17 at 02:50
  • @stomy did you post this as it's own question on StackOverflow? If you do let me know. I could help you with that. otherwise, I'll offer this -- you could (after you start playing a song) listen for the `ended` event to be emitted and start the next audio file in the list (presumably you are keeping track either in the DOM, JS memory, etc). https://developer.mozilla.org/en-US/docs/Web/Events/ended – Sgnl Jan 25 '18 at 02:21
  • @stomy please check the EDIT in my answer to create a playlist that plays songs consecutively. – Cybernetic Jan 26 '18 at 03:32
22

Add a hidden <audio> element and play it as shown.

function playSound(url) {
  var ourAudio = document.createElement('audio'); // Create a audio element using the DOM
  ourAudio.style.display = "none"; // Hide the audio element
  ourAudio.src = url; // Set resource to our URL
  ourAudio.autoplay = true; // Automatically play sound
  ourAudio.onended = function() {
    this.remove(); // Remove when played.
  };
  document.body.appendChild(ourAudio);
}
Missing User
  • 109
  • 5
Rey
  • 331
  • 4
  • 8
22

If you are getting the following error:

Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first.

That means the user needs to interact with the website first (as the error message says). In this case you need to use click or just another event listener, so the user can interact with your website.

If you want to auto load the audio and don't want the user to interact with the document first, you could use setTimeout.

setTimeout(() => {
  document.getElementById('mySound').play();
}, 500)
<audio id="mySound" src="sound.mp3"></audio>

The sound will start after 0.5 second.

Reza Saadati
  • 5,018
  • 4
  • 27
  • 64
11
new Audio('./file.mp3').play()
Maxmaxmaximus
  • 2,098
  • 1
  • 19
  • 17
9

With the security requirements that a user must interact with a webpage for audio to be allowed this is how I do it, based on reading many articles, including on this site

  1. Define the required audio files in your html
  2. Have a start game button with an onclick
  3. When the button is clicked then play and pause ALL the audio files bar the one you want to play at the beginning

Because all the audio files have been "played" on the same OnClick, you can now play them any time in the game without restrictions

Note that for best compatability do not use wav files, MS do not support them

Use mp3 and ogg, that covers all devices

Example:

<audio id="welcome">
    <source src="URL/welcome.ogg" type="audio/ogg">
    <source src="URL/welcome.mp3" type="audio/mpeg">
    Your browser does not support the audio element.
</audio>

repeat as needed for all audio in the game

Then:

document.getElementById("welcome").play();
document.getElementById("welcome").pause();

repeat as needed except do not pause the audio you want to hear when the game starts

Phil Allen
  • 153
  • 2
  • 7
8

Pretty simple solution if you have an HTML tag like below:

<audio id="myAudio" src="some_audio.mp3"></audio>

Just use JavaScript to play it, like so:

document.getElementById('myAudio').play();
Sgnl
  • 1,808
  • 22
  • 30
Ben Stafford
  • 155
  • 2
  • 7
7
var song = new Audio();
song.src = 'file.mp3';
song.play();
mamadaliev
  • 71
  • 1
  • 2
5

I had some issues related to audio promise object returns and some issues related to user interaction with sounds I end up using this small object,

I would recommend to implement the play sounds the closest to the interaction event user is using.

var soundPlayer = {
  audio: null,
  muted: false,
  playing: false,
  _ppromis: null,
  puse: function () {
      this.audio.pause();
  },
  play: function (file) {
      if (this.muted) {
          return false;
      }
      if (!this.audio && this.playing === false) {
          this.audio = new Audio(file);
          this._ppromis = this.audio.play();
          this.playing = true;

          if (this._ppromis !== undefined) {
              this._ppromis.then(function () {
                  soundPlayer.playing = false;
              });
          }

      } else if (!this.playing) {

          this.playing = true;
          this.audio.src = file;
          this._ppromis = soundPlayer.audio.play();
          this._ppromis.then(function () {
              soundPlayer.playing = false;
          });
      }
  }
};

And implement it as follow:

<button onclick="soundPlayer.play('https://interactive-examples.mdn.mozilla.net/media/examples/t-rex-roar.mp3');">Play</button>
talsibony
  • 8,448
  • 6
  • 47
  • 46
  • Not working on a Safari if I trigger autoplay from JS. – maki10 Feb 05 '19 at 10:15
  • 1
    @maki10 Hi, I tested it in safari desktop Version 12.0.3 (14606.4.5) and it works here: https://jsfiddle.net/xf5zyv4q/5/ – talsibony Feb 08 '19 at 10:04
  • I update link for my problem https://jsfiddle.net/6431mfb5/ . For me, autoplay work only first time in safari and newer more. – maki10 Feb 08 '19 at 10:29
  • @maki10 because you call it without user interaction, autoplay wont work without interaction of the user like click touch, remove the last line: soundPlayer.play('https://interactive-examples.mdn.mozilla.net/media/examples/t-rex-roar.mp3'); – talsibony Feb 09 '19 at 06:24
4

I used this method to play a sound...

var audioElement;
if(!audioElement) {
  audioElement = document.createElement('audio');
  audioElement.innerHTML = '<source src="' + '/audio/sound.mp3'+ '" type="audio/mpeg" />'
}
audioElement.play();
Bilal Soomro
  • 661
  • 1
  • 7
  • 12
3

If you want to be able to play the sound even when the browser-tab is currently not selected, you have to load the audio-resource on page load.

Like so:

var audio = new Audio('audio/path.mp3');

function playSound(){
    audio.play();
}

See this question for more detail

3
const playAudio = (path = 'defaultPath') => new Audio(path).play()
playAudio('path')
Poker Player
  • 146
  • 1
  • 4
  • Welcome to Stack Overflow! Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the [help center](https://stackoverflow.com/help/how-to-answer). – Ethan Jul 11 '22 at 01:36
  • 3
    Even though additional information "could" improve this answer, this is exactly what I was looking for. Sometimes code itself is a good answer :-) – Loudenvier Mar 19 '23 at 22:59
2

if you want to play your audio whenever the page is opened then do like this.

<script>
  function playMusic(){
  music.play();
  }
  </script>
<html>
  <audio id="music" loop src="sounds/music.wav" autoplay> </audio>
  </html>

and call this playMusic() whenever you need in your game code.

Suhani Mendapara
  • 297
  • 1
  • 3
  • 10
2

You can use Web Audio API for playing sounds. There are quite some audio libraries out there like howler.js, soundjs etc. If you don't worry about old browsers then you can also check on http://musquitojs.com/. It provides a simple API to create and play sounds.

For example, to play a sound all you've to do is.

import $buzz from 'musquito';

const buzz = $buzz('gunfire.mp3');

buzz.play();

The library also supports Audio Sprites.

VJAI
  • 32,167
  • 23
  • 102
  • 164
1

Just use this:

<video controls="" autoplay="" name="media"><source src="Sound URL Here" type="audio/mpeg" /></video>

Or, to make it simpler:

<video controls="" autoplay="" name="media">

<source src="Sound URL Here" type="audio/mpeg" />

</video>

Sample:

<video controls="" autoplay="" name="media">
<source src="https://interactive-examples.mdn.mozilla.net/media/examples/t-rex-roar.mp3" type="audio/mpeg">
</video>

Have NO IDEA if this works on other browsers other than Chrome 73!!

0

This is some JS i came up with on a baby AI project im working with. i hope this is able to help you out.

<!DOCTYPE html>
<html>
<head>
    <title>
        js prompt AI
    </title>
    <style>
        #button {
            border: 1px solid black;
            border-radius: 10px;
            font-size: 22px;
            height:65px;
            width:100px;
            text-align: center;
            line-height: 65px;
        }
    </style>
</head>
<body>

    <audio id="myAudio" src="./how_are_you.m4a"></audio>
    <p>To Interact with the AI please click the button</p>
    <div id=button>click</div>

    <script>

       var button = document.getElementById("button");
       function playBack() {
           button.addEventListener("click", function (){
            var talk = prompt("If you wish for the AI to respond type hi");
            var myAudio = document.getElementById("myAudio");

            if(talk === "hi") {
                    myAudio.play();
            }
           }) ;



       }
       playBack();
   </script>
</body>

</html>
0

I had some issues with playing audio, especially since Chrome has updated that the user has to interact with the document first.

However, across almost all solutions I found is that the JS code has to actively set listeners (e.g. button clicks) to receive user events in order to play the audio.

In my case I just wanted my game to play BGM as soon as the player interacts with it, so I made myself a simple listener that keeps checking whether the web page is being interacted or not.

const stopAttempt = setInterval(() => {
    const audio = new Audio('your_audio_url_or_file_name.mp3');
    const playPromise = audio.play();
    if (playPromise) {
      playPromise.then(() => {
        clearInterval(stopAttempt)
      }).catch(e=>{
        console.log('' + e);
      })
    }
}, 100 )
Danny
  • 114
  • 4
  • 9
0

In react, you can use ref:

// typescript
const audRef = useRef(null);
const playAudio = () => {
  (audRef.current as any).play();
}
...
// html
<audio controls src={your_audio} ref={audRef} />
<button onClick={playAudio}>Play</button>
Hung
  • 459
  • 5
  • 15
-1

Here is a solution for the year 2020 when you are seeing the error:

[Error] Unhandled Promise Rejection: NotSupportedError: The operation is not supported. (anonymous function) rejectPromise play (anonymous function) (testaudio.html:96) dispatch (jquery-3.4.1.min.js:2:42577)


<div onclick="new Audio('/assets/test.mp3').play()">aaa</div>

Don't be slick and think ooh that's an old school oclick, I'll just move that down the page to my jQuery or my external JavaScript file. Nope. It needs to be an onclick.

William Entriken
  • 37,208
  • 23
  • 149
  • 195
  • 1
    This code works perfectly fine outside of a click event. It just requires a user to have interacted with the page first – mousetail Mar 07 '22 at 14:13