【问题标题】:Access 3rd party JS functions from angular service从 Angular 服务访问 3rd 方 JS 功能
【发布时间】:2016-06-04 17:07:25
【问题描述】:

我正在尝试访问在 index.html 中加载到 angular 之外的 javascript 函数。这是因为 google-tts for node 没有安装在 pi 上。我想使用 js 版本的 google-tts 来传递文本以将其转换为文本到语音。但是我似乎无法弄清楚如何访问我的角度服务所需的功能。

主控制器

(function(angular) {
    'use strict';

    function AppCtrl(AnnyangService, GeolocationService, WeatherService, MapService, HueService, CalendarService, SpeechService,SearchService,GoogleTTS, $scope, $rootScope, $timeout, $interval, $http, $window) {

$rootScope.speech_text = "";       
//command for speak testing.
AnnyangService.addCommand('Speak *term', function(term) {
        $rootScope.speech_text = term;
        SpeechService.Speech(GoogleTTS); 
});
    }

    angular.module('myApp')
        .controller('AppCtrl', AppCtrl);

}(window.angular));

我的服务

(function() {
  'use strict';

  function SpeechService($window, $http, $rootScope, $q, GoogleTTS) {
      var service = {};
      service.events = [];
      service.Speech = function(GoogleTTS) {

        var speech_text = $rootScope.speech_text.toString();
        console.log(speech_text);

        GoogleTTS.then(function(GoogleTTS){
            console.log("is ready");
            tts = new GoogleTTS();

            Say = function(text){
               tts.play(text, 'en', function(err) {
                    if (err) {
                        alert(err.toString());
                    }
                });
            }
            console.log("say");
            Say(speech_text);

        });

    };

    return service 
}

    angular.module('myApp')
        .factory('SpeechService', SpeechService);

}());

所以按照建议,我将 google-tts 包装在一个服务中

(function() {
  'use strict';

      function GoogleTTS($q){

        var deferred = $q.defer();

        fetch();

        function fetch(){

            if(window.GoogleTTS != undefined){ 
                console.log("It found it horray");
                deferred.resolve(window.GoogleTTS); 

            }

            else{
                console.log("bad angular");
                setTimeout(function(){ 

                    fetch();

                }, 500);

            }

        }
        return deferred.promise;
    }  

    angular.module('myApp')
        .factory('GoogleTTS', GoogleTTS);

}());

但它没有在 GoogleTTS 服务中解析 GoogleTTS,它只是保持未定义,就像它无法从窗口中找到函数一样。

<script type="text/javascript" src="js/google-tts.js"></script>
<script type="text/javascript" src="js/google-tts-service.js"></script>
<script type="text/javascript" src="js/soundmanager2.js"></script>

控制台输出

annyang.js:211 Speech recognized: speak hello
annyang.js:220 command matched: Speak *term
annyang.js:222 with parameters ["hello"]
speech-service.js:10 hello
annyang-service.js:32 End undefined
9google-tts-service.js:19 bad angular

这里是 google-tts.js 库脚本

! function(a, b) {
    "use strict";
    if ("function" == typeof define) define(b);
    else if ("undefined" != typeof module && module.exports) module.exports = b();
    else {
        var c = window || this,
            d = c[a],
            e = b();
        e.noConflict = function() {
            return c[a] = d, e
        }, c[a] = e
    }
}("GoogleTTS", function() {
    "use strict";
    var a = function(b) {
            var c = this,
                d = 100;
            c.defaultLanguage = b || "en";
            var e = {
                af: "Afrikaans",
                sq: "Albanian",
                ar: "Arabic",
                hy: "Armenian",
                ca: "Catalan",
                "zh-CN": "Mandarin (simplified)",
                "zh-TW": "Mandarin (traditional)",
                hr: "Croatian",
                cs: "Czech",
                da: "Danish",
                nl: "Dutch",
                en: "English",
                eo: "Esperanto",
                fi: "Finnish",
                fr: "French",
                de: "German",
                el: "Greek",
                ht: "Haitian Creole",
                hi: "Hindi",
                hu: "Hungarian",
                is: "Icelandic",
                id: "Indonesian",
                it: "Italian",
                ja: "Japanese",
                ko: "Korean",
                la: "Latin",
                lv: "Latvian",
                mk: "Macedonian",
                no: "Norwegian",
                pl: "Polish",
                pt: "Portuguese",
                ro: "Romanian",
                ru: "Russian",
                sr: "Serbian",
                sk: "Slovak",
                es: "Spanish",
                sw: "Swahili",
                sv: "Swedish",
                ta: "Tamil",
                th: "Thai",
                tr: "Turkish",
                vi: "Vietnamese",
                cy: "Welsh"
            };
            c._players = [new a.HTML5Player, new a.SM2Player], c.addPlayer = function(b) {
                if (!(b instanceof a.Player)) throw new Error("Must be a instance of base Player class");
                c._players.push(b)
            }, c.languages = function() {
                return e
            }, c.getPlayer = function(a) {
                if (c.availablePlayer) return a(null, c.availablePlayer);
                var b, d = -1;
                (b = function() {
                    return c._players.length <= ++d ? a() : (c._players[d].available(function(e) {
                        return e ? (c.availablePlayer = c._players[d], a(null, c.availablePlayer)) : (b(), void 0)
                    }), void 0)
                }).call()
            }, c.urls = function(a, b) {
                if (b = b || c.defaultLanguage, !a || 0 >= a.length) throw new Error("Need some text");
                for (var e = c._sliceInput(a, d), f = [], g = 0; g < e.length; ++g) {
                    var h = e[g];
                    f.push("http://translate.google.com/translate_tts?ie=UTF-8&tl=" + b + "&q=" + h + "&textlen=" + h.length + "&idx=" + g + "&total=" + e.length)
                }
                return f
            }, c._sliceInput = function(a, b) {
                var c = [],
                    d = 0;
                do c.push(a.slice(d, d + b)), d += b; while (a.length > d);
                return c
            }, c.play = function(a, b, d) {
                c.getPlayer(function(e, f) {
                    if (e) return d(e);
                    if (!f) return d(new Error("No playback mechanism is available"));
                    var g = c.urls(a, b),
                        h = null;
                    (h = function(a) {
                        return a ? d(a) : 0 >= g.length ? d() : (f.play(g.shift(), h), void 0)
                    }).call()
                })
            }
        },
        b = function(a, b) {
            a.prototype = new b, a.prototype.constructor = a, a.prototype.parent = b.prototype
        };
    return a.Player = function() {
        var a = this;
        a.available = function() {
            throw new Error("Not yet implemented")
        }, a.play = function() {
            throw new Error("Not yet implemented")
        }, a.toString = function() {
            throw new Error("Not yet implemented")
        }
    }, a.HTML5Player = function() {
        var a = this;
        a._available = null, a.available = function(b) {
            return null === a._available ? (function(a) {
                try {
                    if ("undefined" == typeof window.Audio) return a(null, !1);
                    var b = new Audio;
                    if ("probably" === b.canPlayType("audio/mpeg")) return a(null, !0);
                    b.addEventListener("canplaythrough", function() {
                        a(null, !0)
                    }, !1), b.addEventListener("error", function() {
                        a(null, !1)
                    }, !1), b.src = "data:audio/mpeg;base64,/+MYxAAAAANIAUAAAASEEB/jwOFM/0MM/90b/+RhST//w4NFwOjf///PZu////9lns5GFDv//l9GlUIEEIAAAgIg8Ir/JGq3/+MYxDsLIj5QMYcoAP0dv9HIjUcH//yYSg+CIbkGP//8w0bLVjUP///3Z0x5QCAv/yLjwtGKTEFNRTMuOTeqqqqqqqqqqqqq/+MYxEkNmdJkUYc4AKqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq", b.load()
                } catch (c) {
                    a(c)
                }
            }(function(c, d) {
                c && console.log(c), a._available = d, b(a._available)
            }), void 0) : (b(a._available), void 0)
        }, a.play = function(a, b) {
            try {
                var c = new Audio;
                c.src = a, c.addEventListener("ended", function() {
                    b()
                }), c.play()
            } catch (d) {
                return b(d)
            }
        }, a.toString = function() {
            return "HTML5 Audio"
        }
    }, b(a.HTML5Player, a.Player), a.SM2Player = function() {
        var a = this;
        a._available = null, a._soundId = 0, a._unique_instance_id = parseInt(1e3 * Math.random(), 10), a.available = function(b) {
            null === a._available && "undefined" != typeof window.soundManager && "function" == typeof window.soundManager.ok && (a._available = window.soundManager.ok()), b(a._available)
        }, a.play = function(b, c) {
            try {
                window.soundManager.createSound({
                    id: "googletts-" + a._unique_instance_id + "-" + ++a._soundId,
                    url: b,
                    onfinish: c
                }).play()
            } catch (d) {
                c(d)
            }
        }, a.toString = function() {
            return "SoundManager2"
        }
    }, b(a.SM2Player, a.Player), a
});

【问题讨论】:

  • 你能提供一个小提琴吗?谢谢

标签: javascript jquery angularjs node.js


【解决方案1】:

首先,您应该将GoogleTTS 包装在它自己的服务上。 其次,GoogleTTS 在 Angular 和您的 SpeechService 开始运行时可能尚未加载。

因此,当您将GoogleTTS 包装到服务中时,您可以在加载时返回一个承诺,并在您使用GoogleTTS 服务的then 中执行您的操作

创建一个将包装GoogleTTS的工厂

      angular.module('yourModule').factory('GoogleTTS', GoogleTTS)

      /* @ngInject */
      function GoogleTTS($q){

        var deferred = $q.defer();

        fetch();

        function fetch(){

            if(window.GoogleTTS != undefined){ //check if GoogleTTS is already loaded
                deferred.resolve(window.GoogleTTS); //if loaded, resolve the promise and return the object
            }
            else{
                setTimeout(function(){ //check every second until GoogleTTS is available
                    fetch();
                }, 1000);
            }
        }

        return deferred.promise;
    }       

然后你可以在你的服务中注入和使用它

(function() {
  'use strict';

  function SpeechService($window, $http, $rootScope, $q, GoogleTTS) {
      var service = {};
      service.events = [];
      service.Speech = function() {

        var speech_text = $rootScope.speech_text.toString();
        console.log(speech_text);

        console.log(this);

        GoogleTTS.then(function(GoogleTTS){

            tts = new GoogleTTS();

            Say = function(text){
               tts.play(text, 'en', function(err) {
                    if (err) {
                        alert(err.toString());
                    }
                });
            }
            Say(speech_text);

        });

    };

    return service 
}

    angular.module('TestApp')
        .factory('SpeechService', SpeechService);

}());

代码未经测试,但你会做类似的事情

【讨论】:

  • 你能给我一个我刚接触 Angular 的例子吗?
  • 我一定是不小心按下了它。我试图给你+1,它只是给你-1
  • 你的答案有效,但我没有得到声音只是没有错误。
  • 抱歉@Louie Almeda 这不是答案,仍在尝试找出我缺少的内容。
  • @GrantZukel 你能在console.log(GoogleTTS) 里面GoogleTTS.then(function(GoogleTTS){ 吗?是否记录GoogleTTS 对象?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-04
  • 2021-03-18
  • 1970-01-01
  • 1970-01-01
  • 2023-01-20
  • 2020-12-07
相关资源
最近更新 更多