I'm making a Firefox extension and I'm failing to play a sound that's located in add-on's data
directory.
The first thing I've tried was playing it in a content script this way:
var soundFile = self.options.soundFile;
(new Audio(soundFile)).play();
where self.options.soundFile
is an option that refers to a resource file in data
directory. But I meet security restrictions:
Security Error: Content at http://example.com may not load or link to resource://jid0-a02no8rrtu2pbize7g7sszzo0z8-at-jetpack/stackoverflow-reiew-helper/data/complete.oga.
Then I've found a way to play sounds in main.js
script (here: How to play audio in an extension?):
var data = require('sdk/self').data;
exports.main = function() {
var {Cc, Ci} = require("chrome");
var sound = Cc["@mozilla.org/sound;1"].createInstance(Ci.nsISound);
sound.play(data.url('complete.oga'));
};
This one fails with the following exception:
NS_ERROR_XPC_BAD_CONVERT_JS: Could not convert JavaScript argument arg 0 [nsISound.play]
undefined 8
Traceback (most recent call last):
File "resource://gre/modules/NetUtil.jsm", line 140, in null
aCallback(pipe.inputStream, aStatusCode, aRequest);
File "resource://jid0-a02no8rrtu2pbize7g7sszzo0z8-at-jetpack/addon-sdk/lib/sdk/net/url.js", line 49, in null
resolve(data);
File "resource://jid0-a02no8rrtu2pbize7g7sszzo0z8-at-jetpack/addon-sdk/lib/sdk/core/promise.js", line 143, in resolve
while (pending.length) result.then.apply(result, pending.shift())
File "resource://jid0-a02no8rrtu2pbize7g7sszzo0z8-at-jetpack/addon-sdk/lib/sdk/core/promise.js", line 37, in then
return { then: function then(resolve) { resolve(value) } }
File "resource://jid0-a02no8rrtu2pbize7g7sszzo0z8-at-jetpack/addon-sdk/lib/sdk/core/promise.js", line 117, in resolved
function resolved(value) { deferred.resolve(resolve(value)) }
File "resource://jid0-a02no8rrtu2pbize7g7sszzo0z8-at-jetpack/addon-sdk/lib/sdk/core/promise.js", line 143, in resolve
while (pending.length) result.then.apply(result, pending.shift())
File "resource://jid0-a02no8rrtu2pbize7g7sszzo0z8-at-jetpack/addon-sdk/lib/sdk/core/promise.js", line 37, in then
return { then: function then(resolve) { resolve(value) } }
File "resource://jid0-a02no8rrtu2pbize7g7sszzo0z8-at-jetpack/addon-sdk/lib/sdk/core/promise.js", line 117, in resolved
function resolved(value) { deferred.resolve(resolve(value)) }
File "resource://jid0-a02no8rrtu2pbize7g7sszzo0z8-at-jetpack/addon-sdk/lib/sdk/core/promise.js", line 143, in resolve
while (pending.length) result.then.apply(result, pending.shift())
File "resource://jid0-a02no8rrtu2pbize7g7sszzo0z8-at-jetpack/addon-sdk/lib/sdk/core/promise.js", line 37, in then
return { then: function then(resolve) { resolve(value) } }
File "resource://jid0-a02no8rrtu2pbize7g7sszzo0z8-at-jetpack/addon-sdk/lib/sdk/core/promise.js", line 117, in resolved
function resolved(value) { deferred.resolve(resolve(value)) }
File "resource://jid0-a02no8rrtu2pbize7g7sszzo0z8-at-jetpack/addon-sdk/lib/sdk/core/promise.js", line 143, in resolve
while (pending.length) result.then.apply(result, pending.shift())
File "resource://jid0-a02no8rrtu2pbize7g7sszzo0z8-at-jetpack/addon-sdk/lib/sdk/core/promise.js", line 37, in then
return { then: function then(resolve) { resolve(value) } }
File "resource://jid0-a02no8rrtu2pbize7g7sszzo0z8-at-jetpack/addon-sdk/lib/sdk/core/promise.js", line 117, in resolved
function resolved(value) { deferred.resolve(resolve(value)) }
File "resource://jid0-a02no8rrtu2pbize7g7sszzo0z8-at-jetpack/addon-sdk/lib/sdk/core/promise.js", line 143, in resolve
while (pending.length) result.then.apply(result, pending.shift())
File "resource://jid0-a02no8rrtu2pbize7g7sszzo0z8-at-jetpack/addon-sdk/lib/sdk/core/promise.js", line 37, in then
return { then: function then(resolve) { resolve(value) } }
File "resource://jid0-a02no8rrtu2pbize7g7sszzo0z8-at-jetpack/addon-sdk/lib/sdk/core/promise.js", line 117, in resolved
function resolved(value) { deferred.resolve(resolve(value)) }
File "resource://jid0-a02no8rrtu2pbize7g7sszzo0z8-at-jetpack/addon-sdk/lib/sdk/core/promise.js", line 143, in resolve
while (pending.length) result.then.apply(result, pending.shift())
File "resource://jid0-a02no8rrtu2pbize7g7sszzo0z8-at-jetpack/addon-sdk/lib/sdk/core/promise.js", line 123, in then
else result.then(resolved, rejected)
File "resource://jid0-a02no8rrtu2pbize7g7sszzo0z8-at-jetpack/addon-sdk/lib/sdk/core/promise.js", line 37, in then
return { then: function then(resolve) { resolve(value) } }
File "resource://jid0-a02no8rrtu2pbize7g7sszzo0z8-at-jetpack/addon-sdk/lib/sdk/core/promise.js", line 117, in resolved
function resolved(value) { deferred.resolve(resolve(value)) }
File "resource://jid0-a02no8rrtu2pbize7g7sszzo0z8-at-jetpack/addon-sdk/lib/sdk/core/promise.js", line 55, in effort
try { return f(options) }
File "resource://jid0-a02no8rrtu2pbize7g7sszzo0z8-at-jetpack/addon-sdk/lib/sdk/core/promise.js", line 117, in resolved
function resolved(value) { deferred.resolve(resolve(value)) }
File "resource://jid0-a02no8rrtu2pbize7g7sszzo0z8-at-jetpack/addon-sdk/lib/sdk/core/promise.js", line 143, in resolve
while (pending.length) result.then.apply(result, pending.shift())
File "resource://jid0-a02no8rrtu2pbize7g7sszzo0z8-at-jetpack/addon-sdk/lib/sdk/core/promise.js", line 37, in then
return { then: function then(resolve) { resolve(value) } }
File "resource://jid0-a02no8rrtu2pbize7g7sszzo0z8-at-jetpack/addon-sdk/lib/sdk/core/promise.js", line 117, in resolved
function resolved(value) { deferred.resolve(resolve(value)) }
File "resource://jid0-a02no8rrtu2pbize7g7sszzo0z8-at-jetpack/addon-sdk/lib/sdk/core/promise.js", line 55, in effort
try { return f(options) }
File "resource://jid0-a02no8rrtu2pbize7g7sszzo0z8-at-jetpack/addon-sdk/lib/sdk/addon/runner.js", line 90, in onLocalizationReady
run(options);
File "resource://jid0-a02no8rrtu2pbize7g7sszzo0z8-at-jetpack/addon-sdk/lib/sdk/addon/runner.js", line 134, in run
quit: exit
File "resource://jid0-a02no8rrtu2pbize7g7sszzo0z8-at-jetpack/stackoverflow-reiew-helper/lib/main.js", line 8, in exports.main
sound.play(data.url('complete.oga'));
If I replace sound.play(...)
with sound.beep
, I get a nice default system sound. So, there should be something wrong with passing resource path to the function.
If it matters in any way, I'm using online Add-on Builder.
Please suggest a solution of playing a solution of playing extension audio resources.
nsISound.play()
takes an nsIURI
instance, not a string. You have to create it via nsIIOService.newURI()
first:
var uri = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService)
.newURI(data.url('complete.oga'), null, null);
sound.play(uri);
I would recommend against this approach however, nsISound.play()
API is pretty much deprecated and IMHO not capable of playing ogg files anyway.
Audio
constructor requires access to a proper HTML document. Easiest way to get one in an SDK-based extension is using page-worker
module:
require("page-worker").Page({
contentScript: "new Audio('complete.oga').play()",
contentURL: data.url("blank.html")
});
Both your sound file and blank.html
(an empty HTML file) need to be located in the data/
directory of the extension - note how the audio file is loaded via a relative URL. Right now I don't see a way to avoid having an empty HTML file in the extension, HTML files outside the extension don't have access to extension files and cannot play them.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With