Как заставить Web Audio API работать на iPhone? - PullRequest
0 голосов
/ 03 ноября 2019

Я создал веб-приложение, которое воспроизводит 16 звуковых дорожек в цикле, используя API-интерфейс Web Audio и ванильный JavaScript. Пока что он работает на настольных компьютерах в Safari, Chrome и Firefox и на устройствах Android. Однако он не работает на iPhone или iPad.

Запуск звукового контекста запускается нажатием кнопки «Пуск» на странице, которая затем отображает элементы управления (кнопку воспроизведения и кнопку отключения звука для каждого из 16 треков).

На iPhone страница не загружается после начального экрана, поэтому я предполагаю, что аудио-контекст не запускается, хотя я не уверен, почему это так. В предыдущем посте я читал, что это связано с тем, что iOS не позволяет запускать аудио-контекст, если он не запущен пользователем. Я подумал, что кнопки «Пуск» на странице будет достаточно, но это, к сожалению, не сработало.

Любая экспертиза по веб-аудио API будет принята с благодарностью!

  constructor(context, urlList, callback) {
    this.context = context;
    this.urlList = urlList;
    this.onload = callback;
    this.bufferList = [];
    this.loadCount = 0;
  }
  loadBuffer = (url, index) => {
    // Load buffer asynchronously
    const request = new XMLHttpRequest();
    request.open('GET', url, true);
    request.responseType = 'arraybuffer';

    const loader = this;

    request.onload = function() {
      // Asynchronously decode the audio file data in request.response
      loader.context.decodeAudioData(
        request.response,
        function(buffer) {
          if (!buffer) {
            alert('error decoding file data: ' + url);
            return;
          }
          loader.bufferList[index] = buffer;
          if (++loader.loadCount == loader.urlList.length)
            loader.onload(loader.bufferList);
          loadingScreen.style.display = 'none';
          loadedContent.style.display = 'block';
        },
        function(error) {
          console.error('decodeAudioData error', error);
        }
      );
    };

    request.onerror = function() {
      alert('BufferLoader: XHR error');
    };

    request.send();
  };
  load = () => {
    for (let i = 0; i < this.urlList.length; ++i)
      this.loadBuffer(this.urlList[i], i);
  };
}

//INIT

// Keep track of all loaded buffers.
const buffers = {};
// Page-wide audio context.
let context = null;

const trackRef = {
  rhodes: { bufferToLoad: './audio/rhodes.mp3', muteRef: muteRhodes },
  rhodes2: { bufferToLoad: './audio/rhodes2.mp3', muteRef: muteRhodes2 },
  conga: { bufferToLoad: './audio/conga.mp3', muteRef: muteConga },
  kick: { bufferToLoad: './audio/kick.mp3', muteRef: muteKick },
  clap: { bufferToLoad: './audio/clap.mp3', muteRef: muteClap },
  snare: { bufferToLoad: './audio/snare.mp3', muteRef: muteSnare },
  ohh: { bufferToLoad: './audio/ohh.mp3', muteRef: muteOhh },
  chh: { bufferToLoad: './audio/chh.mp3', muteRef: muteChh },
  piano: { bufferToLoad: './audio/piano.mp3', muteRef: mutePiano },
  bass1: { bufferToLoad: './audio/bass1.mp3', muteRef: muteBass1 },
  bass2: { bufferToLoad: './audio/bass2.mp3', muteRef: muteBass2 },
  vox1: { bufferToLoad: './audio/vox1.mp3', muteRef: muteVox1 },
  vox2: { bufferToLoad: './audio/vox2.mp3', muteRef: muteVox2 },
  vox3: { bufferToLoad: './audio/vox3.mp3', muteRef: muteVox3 },
  vox4: { bufferToLoad: './audio/vox4.mp3', muteRef: muteVox4 },
  vox5: { bufferToLoad: './audio/vox5.mp3', muteRef: muteVox5 }
};

const tracks = Object.keys(trackRef);

// console.log(buffersToLoad);

// Loads all sound samples into the buffers object.
function loadBuffers() {
  // Array-ify
  const trackNames = [];
  const paths = [];
  for (let trackName in trackRef) {
    const path = trackRef[trackName].bufferToLoad;
    trackNames.push(trackName);
    paths.push(path);
  }
  bufferLoader = new BufferLoader(context, paths, function(bufferList) {
    for (let i = 0; i < bufferList.length; i++) {
      const buffer = bufferList[i];
      const trackName = trackNames[i];
      buffers[trackName] = buffer;
    }
  });
  bufferLoader.load();
}

const setUpAudioContext = () => {
  try {
    // Fix up prefixing
    const AudioContext = (window.AudioContext =
      window.AudioContext || window.webkitAudioContext);
    context = new AudioContext();
  } catch (e) {
    alert('Web Audio API not supported in this browser');
  }
  loadBuffers();
};

// document.addEventListener('DOMContentLoaded', setUpAudioContext);

startButton.addEventListener('click', setUpAudioContext);
...