以下代码适用于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需要特别小心吗?
答案 0 :(得分:3)
我遇到了同样的问题,我已经花了几天时间对其进行故障排除。 正如其他帖子中提到的 pwray 一样,Safari需要媒体请求的文件扩展名:
HTML5 Audio files fail to load in Safari
我试图将我的blob保存到一个文件中,将其命名为file.mp3并且Safari能够以这种方式加载音频,但是在我将文件重命名为没有扩展名(只是“文件”)之后,它没有加载。 当我在Safari中的另一个标签中尝试从blob创建的url时:
url = webkitURL.createObjectURL(blob);
它立即下载一个名为“unknown”的文件,但是当我在Chrome中尝试相同的东西时(也在Mac上),它在浏览器中显示了该文件的内容(mp3文件以ID3开头,然后是一堆不可读的字符)。 我无法弄清楚如何强制blob制作的url有一个扩展名,因为通常它看起来像这样:
blob:https://example.com/a7e38943-559c-43ea-b6dd-6820b70ca1e2
所以它的结尾看起来像一个会话变量。
这是我陷入困境的地方,我真的希望看到一些聪明人的解决方案。 谢谢, 史蒂芬
答案 1 :(得分:0)
有时,HTML5音频可以在没有任何明显原因的情况下停止加载。 如果你看一下媒体事件(http://www.w3schools.com/tags/ref_eventattributes.asp),你会看到一个名为“ onStalled ”的事件,定义是“当浏览器无法获取时要运行的脚本无论出于什么原因,媒体数据“似乎对你有用。
尝试侦听该事件并在必要时重新加载文件,如下所示:
audio.addEventListener('onstalled', function(e) {
audio.load();
}, false);
我希望它有所帮助!
答案 2 :(得分:0)
很多年后,我相信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
的属性/属性无法动态更新。