18

I would like to play sound in chrome extension. How can I do it? What should I write in myscript.js file?

I tried to write in myscript.js:

var audio = new Audio("alarm.wav");
audio.play();

and:

document.write('<audio id="player" src="alarm.wav" >');
document.getElementById('player').play();

but it does not work. I did not add anything more, so there are no unfulfilled conditions.

My manifest.json file:

{
  "name": "Alarm",
  "version": "1.0.0",
  "icons": {"64": "icon64.png"},
  "permissions": [
    "http://site1/",
    "http://site2/"
  ],
  "content_scripts": [
    {
      "matches": ["http://site1/", "http://site2/"],
      "js": ["myscript.js"],
      "run_at": "document_end"
    }
  ],
  "manifest_version": 2
}

If I add button to site in myscript.js file, this button works well, but i can't play sound. My audio file is mp3 and is in the same folder as manifest.json and myscript.js, and my myscript.js is:

var myAudio = new Audio();
myAudio.src = "alarm.mp3";
myAudio.play();
Marco Bonelli
  • 63,369
  • 21
  • 118
  • 128

4 Answers4

38

Update: as of Chrome Extension Manifest v3, Chrome Extensions have switched to service workers for background pages, so if you are using Manifest v3, it is no longer possible to play audio directly from the background page of your extension. See also: Play a sound from a Service Worker. If you are still using Manifest v2, then go ahead and read the answer below.


The easiest way to play some sound/music using JavaScript is by using an Audio object: you just need to have the file you want to play inside your extension folder, and you can play it like this:

var myAudio = new Audio(chrome.runtime.getURL("path/to/file.mp3"));
myAudio.play();

You can play using play() and pause using pause().

Remember that if you want to play the sound in a content script (or anywhere else that is not under a chrome://extension URL) you'll have to declare the audio file in the web_accessible_resources manifest field:

"web_accessible_resources": [
    "path/to/file.mp3"
]

Working example

You can download a test extension I made from HERE. It plays a sound through a content script when you click anything inside a stackoverflow.com page.

Marco Bonelli
  • 63,369
  • 21
  • 118
  • 128
  • 3
    Also don't forget to use `chrome.extension.getURL(src)` to get a correct path like this: `var myAudio = new Audio(); myAudio.src = chrome.extension.getURL("path/to/file.mp3"); myAudio.play(); ` This code should run after any js actions. And include `"web_accessible_resources": [ "*.mp3" ]` to your manifest.json file – Vlad Hilko Sep 11 '18 at 08:03
  • it has to be in the background script? – SuperUberDuper Jan 09 '19 at 17:27
  • @SuperUberDuper no it hasn't, you can do this wherever you like. – Marco Bonelli Jan 09 '19 at 17:37
  • chrome.extension is undefined when I try it – SuperUberDuper Jan 09 '19 at 21:17
  • @SuperUberDuper where are you trying to use it? If you are in a script where the `chrome.extension` API is not defined then that's probably not an extension script and you cannot do this. – Marco Bonelli Jan 09 '19 at 21:34
  • its in a content script, i want to play an mp3 sound thats in the chrome extension dir – SuperUberDuper Jan 09 '19 at 21:39
  • @SuperUberDuper works fine for me, just tested. You are doing it somewhere else. Remember that content scripts and the document they are inside are two different things! You should put your code in the content script, and not inject it in the page. Other than this I can't help you much. If you cannot figure it out I suggest you to ask a question about it. – Marco Bonelli Jan 09 '19 at 22:03
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/186458/discussion-between-superuberduper-and-marco-bonelli). – SuperUberDuper Jan 10 '19 at 09:48
  • I know I shouldn't say useless stuff in comments but thanks so much Marco <3 this really helped me, the answer is very well written. And I have to say in my case, browser.runtime.getURL("song.ogg") worked since I'm making a Firefox extension. I also had to allow audio playback on the website by clicking the lock icon next to browser URL and allow audio/video playback. – Shayan Oct 02 '19 at 19:33
  • 1
    @Shayan glad I could help :) – Marco Bonelli Oct 02 '19 at 19:57
  • I wonder if the same restrictions apply to a Chrome extension as do to normal pages, where playing an audio file must be preceded with a user action such as a click? – Scruffy Mar 24 '20 at 18:50
  • 2
    @Scruffy no they don't, an extension has fewer restrictions and can do a wider range of things, including cross-domain requests and calling functions that are usually restricted like for example playing audio without user interaction. – Marco Bonelli Mar 24 '20 at 19:13
  • But sound does not play if tab is not the active one. https://stackoverflow.com/questions/64058877/sound-does-not-play-in-background-tab – user5858 Sep 25 '20 at 06:38
  • 1
    `chrome.extension.getURL` is deprecated. Now you should use `chrome.runtime.getURL`. – L. Pier Roberto Aug 07 '21 at 13:51
  • Chromium 97 gives this error: Error handling response: ReferenceError: Audio is not defined. in DevTools if you try to run "Audio", you get the same message. – sander Jan 28 '22 at 02:30
  • Seems to work OK with manifest v3 in a content script. – Donn Lee Feb 07 '22 at 23:15
  • @DonnLee well, that makes sense, content scripts are just injected in web pages, they are not service workers. – Marco Bonelli Feb 08 '22 at 01:37
3

According to the documentation, chrome.sound is deprecated in mv3.

An alternative is to use chrome.tts to read a message like "Hey, wake up". :/

Another way is to open a new tab which plays the audio. You could use the chrome.tabs.create() or window.open("https://....", "_blank")

1

If the sound is from an external url like https://upload.wikimedia.org/wikipedia/commons/5/55/En-us-house-noun.ogg, you can simply call the link with an Audio without adding anything to your extension manifest:

var myAudio = new Audio();
myAudio.src = "https://upload.wikimedia.org/wikipedia/commons/5/55/En-us-house-noun.ogg";
myAudio.play();
MagTun
  • 5,619
  • 5
  • 63
  • 104
1

Chrome finally added a solution for Manifest V3: The Offscreen API.

To use it, you need to add 'offscreen' to the permissions list in the manifest.json.

Here is an example how you can use it:

function createSoundHtml(){
  chrome.offscreen.createDocument({
    url: chrome.runtime.getURL('audio.html'),
    reasons: ['AUDIO_PLAYBACK'],
    justification: 'notification',
  });
}

The audio.html with the audio.mp3 in the same folder:

<!DOCTYPE html>
<html>
<head>
<title>Play MP3 File</title>
</head>
<body>
    <audio autoplay>
        <source src="audio.mp3" type="audio/mpeg">
    </audio>
</body>
</html>

You can easily combine the createSoundHtml() function call with the Chrome Message API in the service worker.