【问题标题】:How to play multiple audio sequentially with ionic Media plugin如何使用 ionic Media 插件顺序播放多个音频
【发布时间】:2020-02-16 21:37:09
【问题描述】:

我正在尝试使用离子媒体插件播放多个音频文件: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())

   });


  }

然后玩 All ,我有这个:

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

        this.playOne(track)


    );

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

这样他们就可以同时玩了。

但是如果PlayOne方法被包裹在一个timeout函数中,则在播放列表中存在timeout设置的毫秒间隔,但不一定在另一个开始之前完成,有时会等待很长时间才开始后面的文件是格子的。

超时实现如下所示:

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)
   });


  }

深入研究插件的 ionic 包装器,create 方法如下所示:

/**
 * 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));

任何建议将不胜感激

【问题讨论】:

  • 在链接到插件之后,我没有看到任何迹象表明create 返回了一个承诺,因此await 它没有任何意义。另外,永远不要async 函数传递给new Promise,这是没有意义的。您能否指出该 create 函数的一些文档?您链接到链接here 的页面,但没有显示create 函数(您的代码和您链接的页面使用),它使用Media 作为构造函数new Media),所以...
  • @T.J.Crowder 感谢您的 cmets。我已经编辑了我的问题以包含离子创建包装器
  • 插件的 API 文档在哪里?据我所知,您链接到的页面有使用示例,而不是 API 信息。
  • 除了github链接,我知道的另一个链接是cordova.apache.org/docs/en/latest/reference/…

标签: javascript angular ionic-framework ionic4 cordova-media-plugin


【解决方案1】:

您可以通过循环播放曲目并在每个曲目上等待 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
    );
  });
}

【讨论】:

  • 谢谢@ismod,我之前尝试将超时设置为曲目的持续时间,但我不知道为什么它无法获取曲目的持续时间,所以它返回-1。所以还没有运气。
【解决方案2】:

我最终让它与递归函数一起工作。这按预期工作。

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)
     }



  })
}

然后

this.PlayAllList(0,tracks)

如果这方面有任何改进,我将不胜感激。

【讨论】:

  • 问题是:如果你放一个按钮来停止音乐,你的代码会播放下一首曲目,因为onSuccess也是通过停止曲目触发的。
【解决方案3】:

我认为使用 Web Audio API 会更好。我以前用过,可能性是无穷的。

显然它可以毫无问题地在 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

一些帮助您入门的链接:

【讨论】:

  • 我使用的是 Ionic 4,而不是 V1。另外,我发现了一个适用于播放列表的插件(Cordova Native Audio)。但挑战在于它只能播放应用程序附带的曲目。但我希望能够下载远程文件并稍后播放。
  • 我不认为你的离子版本有那么重要吗? Web Audio API 得到广泛支持...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-14
  • 2010-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多