【问题标题】:Play audio from firefox extension's data directory从 firefox 扩展的数据目录播放音频
【发布时间】:2013-05-08 20:41:04
【问题描述】:

我正在制作一个 Firefox 扩展程序,但无法播放位于附加组件 data 目录中的声音。

  1. 我尝试的第一件事是以这种方式在内容脚本中播放它:

    var soundFile = self.options.soundFile;
    (new Audio(soundFile)).play();
    

    其中self.options.soundFile 是一个选项,它引用data 目录中的资源文件。但我符合安全限制:

    Security Error: Content at http://example.com may not load or link to resource://jid0-a02no8rrtu2pbize7g7sszzo0z8-at-jetpack/stackoverflow-reiew-helper/data/complete.oga.
    
  2. 然后我找到了一种在main.js 脚​​本中播放声音的方法(这里: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'));
    };
    

    这个失败,但有以下异常:

    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'));
    

    如果我用sound.beep 替换sound.play(...),我会得到一个很好的默认系统声音。因此,将资源路径传递给函数应该有问题。

如果有任何问题,我正在使用在线插件生成器。

请提出一个播放扩展音频资源的解决方案。

【问题讨论】:

    标签: javascript firefox firefox-addon firefox-addon-sdk


    【解决方案1】:

    nsISound.play() 采用 nsIURI 实例,而不是字符串。您必须先通过nsIIOService.newURI() 创建它:

    var uri = Cc["@mozilla.org/network/io-service;1"]
                .getService(Ci.nsIIOService)
                .newURI(data.url('complete.oga'), null, null);
    sound.play(uri);
    

    但我建议不要使用这种方法,nsISound.play() API 是 pretty much deprecated,恕我直言,无论如何都无法播放 ogg 文件。

    Audio 构造函数需要访问正确的 HTML 文档。在基于 SDK 的扩展中获取一个的最简单方法是使用 page-worker module:

    require("page-worker").Page({
      contentScript: "new Audio('complete.oga').play()",
      contentURL: data.url("blank.html")
    });
    

    您的声音文件和blank.html(一个空的 HTML 文件)都需要位于扩展程序的 data/ 目录中 - 请注意音频文件是如何通过相对 URL 加载的。现在我没有办法避免在扩展中包含一个空的 HTML 文件,扩展之外的 HTML 文件无法访问扩展文件并且无法播放它们。

    【讨论】:

    • 第一个解决方案完美运行(在用 wav 替换 ogg 文件后)。但是第二个是静默通过的,Error Console 中没有错误,也没有发出声音。这可能是什么原因,或者我该如何找到它?
    • @Alexey:你说得对,<audio> 标签显然不会播放,除非附加到正确的 HTML 文档(并且可能是它的加载组)。想变得聪明就这么多,page-worker 就是这样。我稍后会更新答案。
    • 非常有帮助的答案。如果我打算在程序的不同场合多次播放相同的声音,有没有比每次都创建一个新的Page 更好的方法?
    • @timgeb:这里的琐碎内容脚本只是一个示例,不必如此。您只需要一个页面工作者。创建完成后,您可以向其内容脚本发送消息,并告诉它在需要时播放音频文件。请参阅有关与内容脚本通信的文档。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多