Что происходит с html5 звуковым тегом в iphone при переходе на экран блокировки? - PullRequest
1 голос
/ 14 марта 2020

Я пытаюсь "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. Кажется, в конце проблема с аудио-тегом. Все еще нет решения ...

...