通过Blob URL加载音频在Safari中失败

kuu*_*kuu 11 safari blob html5-audio

以下代码适用于Chrome(22.0)但不适用于Safari(6.0)

<!DOCTYPE html>
<html>
<head>
<script>
function onGo(e) {
  var fr = new FileReader();
  var file = document.getElementById("file").files[0];
  fr.onload = function(e) {
      var data = new Uint8Array(e.target.result);
      var blob = new Blob([data], {type: 'audio/mpeg'});
      var audio = document.createElement('audio'); 
      audio.addEventListener('loadeddata', function(e) { 
          audio.play();
        }, false);
      audio.addEventListener('error', function(e) {
          console.log('error!', e);
        }, false);
      audio.src = webkitURL.createObjectURL(blob);    
    };
  fr.readAsArrayBuffer(file);
}
</script>
</head>
<body>
  <input type="file" id="file" name="file" />
  <input type="submit" id="go" onclick="onGo()" value="Go" />
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

在Safari中,既不调用回调(loadeddata也不错误).使用的内容是一个mp3文件,通常用音频标签回放.Safari需要特别小心吗?

las*_*mjs 9

许多年后,我相信 OP 中的示例应该可以正常工作。只要您在创建 blob 时以某种方式设置了 mime 类型,就像上面的 OP 使用传入的选项的 type 属性所做的那样:

new Blob([data], {type: 'audio/mpeg'});
Run Code Online (Sandbox Code Playgroud)

您还可以<source>在音频元素内使用元素并设置该元素的type属性<source>。我在这里有一个例子:

https://lastmjs.github.io/safari-object-url-test

这是代码:

const response = await window.fetch('https://upload.wikimedia.org/wikipedia/commons/transcoded/a/ab/Alexander_Graham_Bell%27s_Voice.ogg/Alexander_Graham_Bell%27s_Voice.ogg.mp3');

const audioArrayBuffer = await response.arrayBuffer();
const audioBlob = new Blob([audioArrayBuffer]);
const audioObjectURL = window.URL.createObjectURL(audioBlob);

const audioElement = document.createElement('audio');

audioElement.setAttribute('controls', true);
document.body.appendChild(audioElement);

const sourceElement = document.createElement('source');

audioElement.appendChild(sourceElement);

sourceElement.src = audioObjectURL;
sourceElement.type = 'audio/mp3';
Run Code Online (Sandbox Code Playgroud)

我更喜欢在创建 blob 时只设置它的 mime 类型。该<source>元件src的属性/特性不能被动态地更新。


Ste*_*ven 5

我也有同样的问题,我花了几天时间解决了这个问题。正如pwray在另一篇文章中提到的,Safari 需要媒体请求的文件扩展名:

HTML5 音频文件无法在 Safari 中加载

我尝试将我的 blob 保存到一个文件中,将其命名为 file.mp3,Safari 能够以这种方式加载音频,但在我将文件重命名为没有扩展名(只是“文件”)后,它没有加载。当我在 Safari 的另一个选项卡中尝试从 blob 创建的 url 时:

url = webkitURL.createObjectURL(blob);
Run Code Online (Sandbox Code Playgroud)

它立即下载一个名为“未知”的文件,但是当我在Chrome(也在Mac上)中尝试相同的操作时,它在浏览器中显示了该文件的内容(mp3文件以ID3开头,然后是一堆不可读的文件)人物)。我还不知道如何强制由 blob 组成的 url 具有扩展名,因为通常它看起来像这样:

blob:https://example.com/a7e38943-559c-43ea-b6dd-6820b70ca1e2
Run Code Online (Sandbox Code Playgroud)

所以它的结尾看起来像一个会话变量。

这就是我陷入困境的地方,我真的很希望看到这里一些聪明人的解决方案。谢谢,史蒂文


小智 0

有时,HTML5 音频可能会在没有任何明显原因的情况下停止加载。\n如果您查看媒体事件 ( http://www.w3schools.com/tags/ref_eventattributes.asp ),您\xc2\xb4 将看到一个名为: “ onStalled ”,定义是“当浏览器因任何原因无法获取媒体数据时运行的脚本”,看起来它应该对您有帮助。

\n\n

尝试监听该事件并在必要时重新加载文件,如下所示:

\n\n
audio.addEventListener(\'onstalled\', function(e) { \n      audio.load();\n    }, false);\n
Run Code Online (Sandbox Code Playgroud)\n\n

我希望它有帮助!

\n