17

以下代码适用于 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>

在 Safari 中,既不会调用回调(loadeddata 也不会调用错误)。使用的内容是一个 mp3 文件,通常使用音频标签播放。Safari 有什么特别需要注意的吗?

4

3 回答 3

10

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

new Blob([data], {type: 'audio/mpeg'});

您还可以<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';

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

于 2019-05-27T18:08:19.620 回答
4

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

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

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

url = webkitURL.createObjectURL(blob);

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

blob:https://example.com/a7e38943-559c-43ea-b6dd-6820b70ca1e2

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

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

于 2017-11-08T15:41:01.200 回答
0

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

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

audio.addEventListener('onstalled', function(e) { 
      audio.load();
    }, false);

我希望它有帮助!

于 2014-02-14T11:57:05.643 回答