Как воспроизводить несколько аудио последовательно с помощью плагина ionic Media - PullRequest
0 голосов
/ 20 октября 2019

Я пытаюсь воспроизвести несколько аудиофайлов с помощью плагина ionic media: https://ionicframework.com/docs/native/media., но мне трудно заставить его работать в качестве списка воспроизведения без использования функции тайм-аута.

Вот чтоЯ попробовал

playOne(track: AudioFile): Promise<any> {


 return new Promise(async resolve =>{

      const AudFile =  await this.media.create(this.file.externalDataDirectory+track.trackUrl);


       await resolve(AudFile.play())

   });


  }

Затем, чтобы сыграть Все, у меня есть это:

async playAll(tracks: AudioFile[]): Promise<any>{
    let player = (acc, track:AudioFile) => acc.then(() => 

        this.playOne(track)


    );

   tracks.reduce(player, Promise.resolve());
  }

Таким образом, они все играют одновременно.

Но еслиМетод PlayOne обернут в функцию тайм-аута, интервал в миллисекунды, установленный для тайм-аута, существует среди списка воспроизведения, но один не обязательно заканчивается до запуска другого, а иногда он долго ждет, пока следующий файл не будет воспроизведен. .

Реализация тайм-аута выглядит следующим образом:

playOne(track: AudioFile): Promise<any> {


 return new Promise(async resolve =>{
     setTimeout(async ()=>{
      const AudFile =  await this.media.create(this.file.externalDataDirectory+track.trackUrl);


       await resolve(AudFile.play())
     },3000)
   });


  }

Копая в ионную оболочку плагина, метод создания выглядит так:

/**
 * Open a media file
 * @param src {string} A URI containing the audio content.
 * @return {MediaObject}
 */
Media.prototype.create = function (src) {
    var instance;
    if (checkAvailability(Media.getPluginRef(), null, Media.getPluginName()) ===
        true) {
        // Creates a new media object
        instance = new (Media.getPlugin())(src);
    }
    return new MediaObject(instance);
};
Media.pluginName = "Media";
Media.repo = "https://github.com/apache/cordova-plugin-media";
Media.plugin = "cordova-plugin-media";
Media.pluginRef = "Media";
Media.platforms = ["Android", "Browser", "iOS", "Windows"];
Media = __decorate([
    Injectable()
], Media);
return Media;
 }(IonicNativePlugin));

Любое предложение будетцениться

Ответы [ 3 ]

0 голосов
/ 12 ноября 2019

Я думаю, вам будет лучше с API Web Audio. Я использовал его раньше, и возможности безграничны.

Очевидно, что он может быть использован в Ionic без проблем: https://www.airpair.com/ionic-framework/posts/using-web-audio-api-for-precision-audio-in-ionic

Я использовал его на http://chordoracle.com, чтобы игратьнесколько аудиосэмплов одновременно (до 6 одновременных сэмплов для каждой струны гитары). В этом случае я также изменяю их высоту, чтобы получать разные ноты.

Чтобы воспроизвести несколько семплов, вам просто нужно создать несколько bufferSources: https://developer.mozilla.org/en-US/docs/Web/API/BaseAudioContext/createBufferSource

Некоторые ссылки, с которых можно начать:

0 голосов
/ 16 ноября 2019

Я в конце концов заставил его работать с рекурсивной функцией. Это работает как ожидалось.

PlayAllList(i,tracks: AudioFile[]){
    var self = this;

 this.Audiofile = this.media.create(this.file.externalDataDirectory+tracks[i].trackUrl);

 this.Audiofile.play()
   this.Audiofile.onSuccess.subscribe(() => {
    if ((i + 1) == tracks.length) {
      // do nothing
     } else {
       self.PlayAllList(i + 1, tracks)
     }



  })
}

Если что-то улучшится, я буду признателен.

0 голосов
/ 12 ноября 2019

Вы можете заставить его работать, зацикливая свои треки и ожидая playOne на каждом треке.

async playAll(tracks: AudioFile[]): Promise<any> {
  for (const track of tracks) {
    await this.playOne(track);
  }
}

Если я не ошибаюсь, функция play не блокируется, пока не будет воспроизведен аудиофайл. закончен. Это также не возвращает обещание. Обходным путем будет использование seTimeout на протяжении трека

playOne(track: AudioFile): Promise<any> {
  return new Promise((resolve, reject) => {
    const audFile =  await this.media.create(this.file.externalDataDirectory+track.trackUrl);
    const duration = audFile.getDuration(); // duration in seconds

    AudFile.play();
      setTimeout(() => {
        resolve();
      },
      duration * 1000 // setTimeout expect milliseconds
    );
  });
}
...