【问题标题】:Getting SoundJS to work with Cordova/Phonegap让 SoundJS 与 Cordova/Phonegap 一起工作
【发布时间】:2015-12-16 20:27:42
【问题描述】:

我正在构建一个具有广泛音频要求的应用程序,因此我为此使用 SoundJS,并且我正在使用 phonegap 编译该应用程序。

我正在使用mobile safe approach 构建一个soundJS 应用程序。似乎有不同的audio plugins,包括一个特殊的 Cordova 音频插件。因此,我无法在已编译的应用程序上注册任何这些插件。这是因为注册任何插件都需要检查是否支持该插件。如果是cordova,isSupported 方法会检查以下内容:

if (s._capabilities != null || !(window.cordova || window.PhoneGap || window.phonegap) || !window.Media) { return;}

这意味着当应用程序编译时,没有名为 window.cordova 或 phonegap 的全局变量,也没有名为 window.media 的全局变量(我认为这是需要安装的媒体插件才能让 soundjs 工作,并且我已将它添加到我用于 phonegap 构建的 config.xml 中。

所以问题是,如何调查出了什么问题,如何知道媒体插件是否安装不正确(全部来自我们可以使用的 javascript 变量,因为我无法使用任何其他调试) , 还是当我使用 phonegap build 编译时没有用于 cordova 或 phonegap 的变量.. 我们可以列出所有全局变量以查看使用了哪些变量吗?

编辑 感谢 Jesse 让我注意到关于 phonegap 的这些点,所以我构建了一个小应用程序只是为了测试 deviceready 事件,但由于某种原因,它在通过 phonegap build 编译时仍然无法正常工作:

<!DOCTYPE html>
<html>
  <head>
    <title>Cordova Device Ready Example</title>

    <script type="text/javascript" charset="utf-8" src="js/soundjs-NEXT.min.js"></script>
    <script type="text/javascript" charset="utf-8" src="js/cordovaaudioplugin-NEXT.min.js"></script>
    <script type="text/javascript" charset="utf-8">

    // Call onDeviceReady when Cordova is loaded.
    //
    // At this point, the document has loaded but cordova-2.3.0.js has not.
    // When Cordova is loaded and talking with the native device,
    // it will call the event `deviceready`.
    //
    function onLoad() {
        document.getElementById("doc_loaded").innerHTML="Document Loaded"
        document.addEventListener("deviceready", onDeviceReady, false);
    }

    // Cordova is loaded and it is now safe to make calls Cordova methods
    //
    function onDeviceReady() {
        // Now safe to use the Cordova API\
        document.getElementById("device_loaded").innerHTML="Device Loaded"

        if (window.cordova || window.PhoneGap || window.phonegap){ 
            document.getElementById("phonegap_loaded").innerHTML="Phonegap Loaded"
        }
        if (window.Media){
            document.getElementById("media_loaded").innerHTML="Media Loaded"
        }

    }

    </script>
  </head>
  <body onload="onLoad()">
  Hello Hello, testing phonegap deviceready
  <div id="doc_loaded">Loading Doc</div>
  <div id="device_loaded">Loading Device</div>
  <div id="phonegap_loaded">Detecting Phonegap</div>
  <div id="media_loaded">Detecting Media</div>
  </body>
</html>

你能帮我找出问题所在吗?

EDIT2 我发现 deviceready 无法正常工作,因为我没有添加cordova:

<script type="text/javascript" src="cordova.js"></script>

所以,当我这样做时,我能够初始化 cordova 音频插件。但是,尽管使用了移动安全方法,我仍然无法播放声音:

(此代码托管在 arbsq.net/h6/ 上)

<!DOCTYPE html>
<html>
<head>
    <title>SoundJS: Mobile Safe</title>

    <link href="css/shared.css" rel="stylesheet" type="text/css"/>
    <link href="css/examples.css" rel="stylesheet" type="text/css"/>
    <link href="css/soundjs.css" rel="stylesheet" type="text/css"/>
    <script src="js/examples.js"></script>
</head>

<body onload="loading_doc()">

<header  class="SoundJS">
    <h1>Mobile Safe Play</h1>

    <p>This example registers and plays a sound with SoundJS in a way that will
        work on mobile devices.</p>
</header>

<div class="content" id="content" style="height: auto">
    <p id="status">Hello World.</p>
</div>

<div id="error">
    <h2>Sorry!</h2>

    <p>SoundJS is not currently supported in your browser.</p>

    <p>Please <a href="http://github.com/CreateJS/SoundJS/issues" target="_blank">log a bug</a>
        with the device and browser you are using. Thank you.</p>
</div>

<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" charset="utf-8" src="js/soundjs-NEXT.min.js"></script>
<script type="text/javascript" charset="utf-8" src="js/cordovaaudioplugin-NEXT.min.js"></script>


<!-- We also provide hosted minified versions of all CreateJS libraries.
    http://code.createjs.com -->

<script id="editable">
    var displayMessage;     // the HTML element we use to display messages to the user
    this.myNameSpace = this.myNameSpace || {};
    function loading_doc() {
         if(( /(ipad|iphone|ipod|android|windows phone)/i.test(navigator.userAgent) )) {
            document.addEventListener('deviceready', init, false);
        } else {
            init();
        }
    }

    function init() {
        // store this off because walking the DOM to get the reference is expensive
        displayMessage = document.getElementById("status");

        // if this is on mobile, sounds need to be played inside of a touch event
        if (createjs.BrowserDetect.isIOS || createjs.BrowserDetect.isAndroid || createjs.BrowserDetect.isBlackberry || createjs.BrowserDetect.isWindowPhone) {
            //document.addEventListener("click", handleTouch, false);   // works on Android, does not work on iOS
            displayMessage.addEventListener("click", handleTouch, false);   // works on Android and iPad
            displayMessage.innerHTML = "Touch to Start";
        }
        else {
            handleTouch(null);
        }
    }

    // launch the app inside of this scope
    function handleTouch(event) {
        displayMessage.removeEventListener("click", handleTouch, false);
        // launch the app by creating it
        var thisApp = new myNameSpace.MyApp();
    }

    // create a namespace for the application


    // this is a function closure
    (function () {
        // the application
        function MyApp() {
            this.init();
        }

        MyApp.prototype = {
            src: null,            // the audio src we are trying to play
            soundInstance: null,  // the soundInstance returned by Sound when we create or play a src
            displayStatus: null,  // the HTML element we use to display messages to the user
            loadProxy: null,

            init: function () {
                // store the DOM element so we do repeatedly pay the cost to look it up
                this.displayStatus = document.getElementById("status");

                // this does two things, it initializes the default plugins, and if that fails the if statement triggers and we display an error
                // NOTE that WebAudioPlugin plays an empty sound when initialized, which activates web audio on iOS if played inside of a function with a touch event in its callstack
                if (!createjs.Sound.initializeDefaultPlugins()) {
                    document.getElementById("error").style.display = "block";
                    document.getElementById("content").style.display = "none";
                    return;
                }

                // Create a single item to load.
                var assetsPath = "audio/";
                this.src = assetsPath + "M-GameBG.ogg";

                this.displayStatus.innerHTML = "Waiting for load to complete.";  // let the user know what's happening
                // NOTE createjs.proxy is used to apply scope so we stay within the touch scope, allowing sound to play on mobile devices
                this.loadProxy = createjs.proxy(this.handleLoad, this);
                createjs.Sound.alternateExtensions = ["mp3"];   // add other extensions to try loading if the src file extension is not supported
                createjs.Sound.addEventListener("fileload", this.loadProxy); // add event listener for when load is completed.
                createjs.Sound.registerSound(this.src);  // register sound, which preloads by default

                return this;
            },

            // play a sound inside
            handleLoad: function (event) {
                this.soundInstance = createjs.Sound.play(event.src);    // start playback and store the soundInstance we are currently playing
                this.displayStatus.innerHTML = "Playing source: " + event.src;  // let the user know what we are playing
                createjs.Sound.removeEventListener("fileload", this.loadProxy); // we only load 1 sound, so remove the listener
            }
        }

        // add MyApp to myNameSpace
        myNameSpace.MyApp = MyApp;
    }());

</script>

</body>
</html>

【问题讨论】:

  • @hmghaly 你知道你的库只使用 HTML5 音频来播放源吗?
  • @MysterX 可能是的
  • 很遗憾,如果是这样,您将无法在没有用户操作的情况下在移动平台上播放 HTML5 音频。它受到安全政策的限制。试试看移动硬件解决方案,玩mediaObject,由它提供。几个月前,我在我的一个项目中使用了它。 github.com/apache/cordova-plugin-media 这是一个训练应用程序,我必须在每个动作点击时播放不同的声音(.mp3 和 .ogg)

标签: javascript cordova phonegap-build soundjs


【解决方案1】:

@hmghaly,
检查Phonegap 可用性的一般方法是使用Cordova/Phonegap 提供的'deviceready' 事件。此外,您要求等到此事件完成。

您将需要阅读本文常见问题解答的第 4 条:
Top Mistakes by Developers new to Cordova/Phonegap

我将引用重要的part from the documentation(您应该阅读):

这是每个 Cordova 应用程序都应该使用的非常重要的事件。

Cordova 包含两个代码库:native 和 JavaScript。在加载本机代码时,会显示自定义加载图像。 但是,只有在 DOM 加载后才会加载 JavaScript。这意味着您的 Web 应用程序可能会调用 Cordova JavaScript 函数 在加载之前。

Cordova deviceready 事件在 Cordova 完全加载后触发。设备启动后,您可以安全地调用 Cordova 函数。

文档包含与您的特定移动设备和平台相关的代码示例。

祝你好运

【讨论】:

  • 嗨@jesseMonroy650,非常感谢这些关于phonegap的提示。所以我试着测试一下关于deviceready的这一点,你能检查一下原帖编辑部分的代码吗,因为它在phonegap build编译时不起作用?
  • 您好,好像只是缺少了cordova,但是添加后还是有问题,请您检查edit2和赏金声明吗?
【解决方案2】:

虽然这不是一个完整的答案,但我目前正在解决完全相同的问题,并且在完全相同的时间点出现问题。

如果 (s._capabilities != null || !(window.cordova || window.PhoneGap || 窗口.phonegap) || !window.Media) { return;}

确保安装了 cordova 之后,下一件大事就是确保您确实安装了 cordova-plugin-media。上面一行中的 !window.Media 位。听起来很简单,但如果您只是添加插件并构建而不读取所有输出,您可能会遇到困难。

媒体插件需要 cordova 版本 > 5.0 。问题在于,cordova 被固定在 4.1.1 版本 - 尽管反复完全删除了 cordova,但至少我的是 - 多次通过 npm 和手动完全删除所有 npm 缓存。

Cordova 内部硬连线以安装特定版本,除非您告诉它不要这样做。

所以请确保您正在使用

cordova平台添加android@5.X.X

适合您的版本,而不仅仅是普通的旧版本

cordova 平台添加 android (BAD)

这将安装固定版本

如果你这样做,尽管有 cli 命令,但 Cordova 将很高兴使用 4.1.1 版构建

科尔多瓦-v

报告您使用的是更高版本 - 在我的情况下是 5.4.1

然后它将进入插件步骤 - 确定环境不适合您的插件 - 发出警告并愉快地继续构建 - 减去媒体插件。其他一切似乎都可以工作 - 应用程序会运行,除非您深入研究它,否则您不会注意到您使用的是旧版本的 cordova。

注意:他们刚刚发布了一个新版本,它将固定版本向前移动 - 所以如果你更新到最新版本 - 你应该没问题。

New Cordova Version Released

【讨论】:

    【解决方案3】:

    如果您使用的是 SoundJS 0.6.2,则不必包含 MobileSafe 代码。参考Official Doc

    我长期面临的问题是本地声音文件在 iOS 中没有成功加载。

    我发现了什么: 最新的 iOS 使用 WKWebView。它似乎将本地文件视为来自远程服务器,即使它们位于应用程序本身中,并且此类请求被阻止。参考Source

    最后经过大量的调试和记录, 以下解决方案对我有用:

    1. 添加 Corodova 文件插件。

      cordova plugin add cordova-plugin-file

    2. 把本地文件路径改成这样:

      cdvfile://localhost/bundle/www/you_folder_name/file_name.mp3

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-13
      • 2016-10-06
      相关资源
      最近更新 更多