Я пытаюсь "Sequential Play aka playlist" по html аудио тегу. Источники файлов с самого мобильного телефона пользователя. Пользователь выберет несколько файлов из входных данных, и он начнет воспроизводиться автоматически при загрузке, если Android, и пользователь должен сначала нажать кнопку воспроизведения, если iphone.
. Поэтому я попытался URL.createObjectURL , веб-аудио API , программа чтения файлов . Все отлично работает в Android. Когда первый аудиофайл заканчивает воспроизведение, с включенным слушателем, он воспроизводит следующий файл. Кнопка назад / вперед тоже работает нормально. Но на iphone (ios 13) он не работает, когда экран блокируется. Позволяет завершить только первый файл.
Сначала я думал, что проблема в том, что
safari не позволяет audio.play () без взаимодействия с пользователем.
Чтобы сузить причину ошибки, я связал источник файлов с Google Drive или Dropbox. В этом случае следующий файл воспроизводится без проблем, независимо от того, заблокирован экран или нет на iphone.
Таким образом, проблема заключается в использовании локальных файлов в iphone. Он играет в первую очередь, когда нажата кнопка воспроизведения. Затем первый файл завершит воспроизведение sh, и когда он перейдет к следующей загрузке, он выдаст ошибку (код: 4 из события ошибки аудиоэлемента), если файлы будут локальными, а экран на некоторое время отключен. Событие Onended, а также нажатие кнопки «предыдущий / следующий».
Я не могу проверить с помощью web audio api, потому что тот же код не работает на iphone, который работает в Android. Он даже не воспроизводит даже первый файл. Кнопка воспроизведения не работает вообще.
Исходные коды
Html
<label class="custom-file-upload">
<input type="file" accept='audio/*' multiple> Load </label>
<audio type="audio/mp4" controls></audio>
Javascript
const input = document.querySelector("input[type=file]");
const audio = document.querySelector("audio");
const output = document.getElementById("output");
const speedzone = document.querySelector('#speedzone');
const choice = document.getElementById('cnext');
const choice1 = document.getElementById('cprev');
let listLength, j, files;
const playList = files => {
if (j-- >=0) {
let listFile ='';
for (let i = listLength-1 ; i>=0 ;i--) {
listFile += (i==j)?`<div class=list><b>${files[i].name} ${(+files[i].size/1024/1024).toFixed(2)} MB</div>`
: `<div>${files[i].name}</div>`;
}
output.innerHTML = listFile;
let listDiv = document.querySelector('.list');
output.scrollTop = listDiv.offsetTop;
audio.src = URL.createObjectURL(files[j]);
audio.load();
}
}
input.addEventListener("change", (e) => {
files = [...e.target.files].sort((a, b) => { return b.name.localeCompare(a.name); });
j = listLength = files.length;
playList(files);
});
audio.addEventListener("loadeddata", () => {audio.play();});
audio.addEventListener("ended", () => {choice.click();});
audio.addEventListener("error", (e) => {
const err = e.target.error;
let txt = speedzone.innerHTML;
txt += `<div><font color=red>${err.code}: ${err.message}</font></div>`;
speedzone.innerHTML = txt;
});
choice.addEventListener('click', () => {if (j>0) playList(files);});
choice1.addEventListener('click', () => {
//previous
if (j<listLength-1) {
j+=2;
choice.click();
}
});
В настоящее время я сомневаюсь, что при блокировке экрана, в отличие от Android, файлы iphone теряют свою ссылку. Потому что URL.createObjectURL вызываются только тогда, когда они необходимы, поэтому вопрос об URL-адресе истек. Как ни странно, массив файлов по-прежнему содержит информацию, которая была выделена первой. Поэтому, где я храню список, вывод, он дает список и правильный размер выбранного файла. Я все еще могу нажимать предыдущий / следующий, и они делают свою работу, кроме аудио. Кажется, я не знаю, откуда возникла ошибка.
Вот когда я попробовал веб-аудио API.
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
Затем в функции playList
const track = audioContext.createMediaElementSource(audio);
track.connect(audioContext.destination);
if (audioContext.state === 'suspended') {
audioContext.resume();
}
Работает так же, как и другие два метода в Android. Но он не будет играть на iphone.
В крайнем случае, я хочу попробовать этот веб-аудио API. Но так как это не сыграет, я не могу быть уверен, что результат будет таким же, как у двух других. Также, как я сомневаюсь, если проблема заключается в получении самих файлов.
Как заставить этот веб-аудио API работать на iphone? И есть ли какие-либо ограничения на использование input [type = file] на iphone?
** Edit ** Я обнаружил, что даже аудиоэлемент выдает ошибку, url-файл filereader и URL.createObjectURL получают url ok. Кажется, в конце проблема с аудио-тегом. Все еще нет решения ...