1

我想说一些文字;如果我在浏览器中输入格式正确的 url,我可以从谷歌翻译 tts 获取音频文件(mp3)。

但是如果我尝试 createSound 它,我只会在 firebug 中看到 404 错误。

我使用它,但它失败了:

soundManager.createSound( 
  {id:'testsound', 
   autoLoad:true,
   url:'http://translate.google.com/translate_tts?ie=UTF-8&tl=da&q=testing'}
 );

我已经使用 wget 预先获取了固定的语音提示,因此它们与页面一样位于同一网络服务器上的本地 mp3 文件。但我想说一个动态提示。

4

2 回答 2

1

我看到很久以前有人问过这个问题,但是我遇到了类似的问题,并且我能够使其适用于 Chrome 和 Firefox,但使用了音频标签。

这是我制作的演示页面

http://jsfiddle.net/royriojas/SE6ET/

这是对我有用的代码...

var sayIt;

function createSayIt() {

    // Tiny trick to make the request to google actually work!, they deny the request if it comes from a page but somehow it works when the function is inside this iframe!

    //create an iframe without setting the src attribute
    var iframe = document.createElement('iframe');

    // don't know if the attribute is required, but it was on the codepen page where this code worked, so I just put this here. Might be not needed.
    iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-pointer-lock');
    // hide the iframe... cause you know, it is ugly letting iframes be visible around...
    iframe.setAttribute('class', 'hidden-iframe')

    // append it to the body
    document.body.appendChild(iframe);

    // obtain a reference to the contentWindow
    var v = iframe.contentWindow;

    // parse the sayIt function in this contentWindow scope
    // Yeah, I know eval is evil, but its evilness fixed this issue...
    v.eval("function sayIt(query, language, cb) { var audio = new Audio(); audio.src = 'http://translate.google.com/translate_tts?ie=utf-8&tl=' + language + '&q=' + encodeURIComponent(query); cb && audio.addEventListener('ended', cb);  audio.play();}");

    // export it under sayIt variable
    sayIt = v.sayIt;
}

我想我能够绕过这个限制。我不知道他们将来可能会修复这个黑客。其实我希望他们不要...

也可以尝试使用Text2Speech HTML5 api,不过还很年轻……

IE 11 不适用于此 hack,未来某个时候我可能会尝试修复它

于 2014-03-29T09:14:40.103 回答
0

即使您将此视为 404 错误,您实际上也遇到了跨域限制。

来自 404 的一些响应标头也将为您提供有关正在发生的事情的线索:

X-Content-Type-Options:nosniff
X-XSS-Protection:1; mode=block

因此,您将无法在客户端执行此操作,因为 Google 不会(并且可能永远不会)允许您这样做。

为了动态加载音频,您需要通过在您自己的服务器上设置代理来解决此 x 域限制,该代理将从 Google 的服务器(通过 wget 或其他)下载最终用户请求的任何文件并吐出来自谷歌的任何数据。

我用来重现该问题的代码:

soundManager.setup({
    url: 'swf',
    onready: function() {
        soundManager.createSound({
            id:'testsound', 
            autoLoad:true,
            url:'http://translate.google.com/translate_tts?ie=UTF-8&tl=da&q=testing'
        });
    }
});

您的代码应如下所示:

soundManager.createSound({
    id:'testsound', 
    autoLoad:true,
    url:'/audioproxy.php?ie=UTF-8&tl=da&q=testing' // Same domain!
});

问候和祝你好运!

于 2013-06-01T13:58:33.240 回答