Android:URL.createObjectURL无法正常工作(由于找不到受支持的源而无法加载.) [英] Android: URL.createObjectURL does not work properly (Failed to load because no supported source was found.)
问题描述
我正在尝试播放存储在我的Meteor Android应用程序的LocalForage中的音频文件.
I am trying to play an audio file that has been stored in LocalForage of my Meteor Android App.
LocalForage.getItem(track_id, (err, value)=>{
if(err)
throw err;
//the loaded value is an arraybuffer of an m4a file
let blob = new Blob([value]);
let url = (window.URL || window.webkitURL || window || {}).createObjectURL(blob);
let testAudio = new Audio(url);
testAudio.play().then(()=>{console.log("play successful")}).catch((err)=>{console.error(err)});
});
之前,我将URL传递给Howler.js的实例,但是为了更容易理解正在发生的事情,我添加了testAudio.
Before, I passed the url to an Instance of Howler.js, but to make it easier to comprehend what's happening, I added testAudio.
在浏览器(Chrome)中进行测试时,代码可以正常工作.网址已创建,音频正在播放.
When testing in a browser (Chrome), the code works as it should. The url is created and the Audio is playing.
Android(使用Chromium作为所有Meteor Android Apps)似乎不喜欢我的方法: 创建对象网址时,Chromium返回如下网址:
Android (using Chromium as all Meteor Android Apps) however, does not seem to like my approach: When creating the Object URL, Chromium returns an URL like this:
blob:http%3A//localhost%3A12128/4de4516a-2989-4e99-9269-0beff4517fc4
如您所见,即使我这样做,这也不是可用的URL
As you can see, this is not a usable URL, and even if I do this
url = url.replace(/%3A/g, ':');
结果控制台输出为
DOMException: Failed to load because no supported source was found.
有人知道为什么这在Android上不起作用吗?我在这里查看了其他与该问题相同的问题,但是我的代码对我来说看起来很正确,并且在Chrome中进行测试时可以正常工作,所以我真的不知道该如何处理.
Does anyone have an idea why this does not work on Android? I've taken a look at other questions here with the same problem, but my code looks right to me and works when tested in Chrome, so I really don't know how to approach this.
顺便说一下,音频缓冲区的保存方式如下:
By the way, the Audiobuffer is saved like so:
const request = new window.XMLHttpRequest();
request.addEventListener('readystatechange', () => {
if (request.readyState === 4) {
LocalForage.setItem(track.file_id, request.response, (err, value) => {
console.log('Successfully saved to locale forage: ' + track.name);
})
}
});
request.open('GET', track.audioLink, true);
request.responseType = 'arraybuffer';
request.send();
推荐答案
I ran into something similar a while ago, and used this workaround (found in this chromium issue)
您也许可以做类似的事情
You could maybe do something like
let url = (window.URL || window.webkitURL || window || {}).createObjectURL(blob);
// workaround for mobile playback, where it didn't work on chrome/android.
// fetch blob at url using xhr, and use url generated from that blob.
// see issue: https://code.google.com/p/chromium/issues/detail?id=227476
// thanks, gbrlg
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status == 200) {
var url = (window.URL || window.webkitURL || window || {}).createObjectURL(xhr.response);
// now url is ready
}
};
xhr.send();
基本上,在创建Blob网址后,您再次使用XHR来获取它,然后它就可以工作了.
basically, after you create the blob url, you fetch it using XHR again, and then it works.
It's not pretty at all, but perhaps you are experiencing this bug. I used this workaround successfully in an open source project, but like I mentioned in a comment, if memory serves, it only worked for Android 5+.
这篇关于Android:URL.createObjectURL无法正常工作(由于找不到受支持的源而无法加载.)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!