Загрузка аудио с помощью URL-адреса Blob в Safari
Следующий код работает в 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 не вызывается ни обратный вызов (загруженные данные, ни ошибка).
Используемый контент - это mp3 файл, который обычно воспроизводится с помощью звукового тега.
Есть ли какой-то особый уход для Safari?
Ответы
Ответ 1
У меня та же проблема, и я потратил пару дней на устранение неполадок.
Как pwray, упомянутых в этом другом сообщении, Safari требует расширения файлов для медиа-запросов:
HTML5 Аудиофайлы не загружаются в Safari
Я попытался сохранить свой blob в файл, назвал его file.mp3, и Safari смог загрузить звук таким образом, но после того, как я переименовал файл, чтобы иметь расширение (просто "файл" ), он не нагрузки.
Когда я попробовал url, созданный из blob на другой вкладке Safari:
url = webkitURL.createObjectURL(blob);
он сразу же загружает файл под названием "unknown", но когда я пробовал то же самое в Chrome (также на Mac), он показывал содержимое файла в браузере (mp3 файлы начинаются с ID3, затем куча нечитаемые символы).
Я еще не мог понять, как я могу заставить url из blob иметь расширение, потому что обычно это выглядит так:
blob:https://example.com/a7e38943-559c-43ea-b6dd-6820b70ca1e2
поэтому конец его выглядит как переменная сеанса.
Здесь я застрял, и мне бы очень хотелось увидеть решение от некоторых умных людей.
Благодаря,
Стивен
Ответ 2
Иногда звук HTML5 может просто прекратить загрузку без каких-либо видимых причин.
Если вы посмотрите на медиа-события (http://www.w3schools.com/tags/ref_eventattributes.asp), вы увидите событие с именем: onStalled ", определение" Script будет запущено, когда браузер не сможет извлечь медиаданные по какой-либо причине ", и кажется, что это должно быть полезно для вас.
Попробуйте прослушивать это событие и при необходимости перезагружать файл с помощью следующего:
audio.addEventListener('onstalled', function(e) {
audio.load();
}, false);
Надеюсь, это поможет!
Ответ 3
Много лет спустя, я считаю, что пример в ОП должен работать просто отлично. До тех пор, пока вы каким-то образом устанавливаете тип 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';
Я предпочитаю просто устанавливать тип MIME BLOB-объекта при его создании. Атрибут/свойство src
элемента <source>
не может быть обновлен динамически.