如何使用离子媒体插件顺序播放多个音频
How to play multiple audio sequentially with ionic Media plugin
我正在尝试使用 ionic 媒体插件播放多个音频文件: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方法被包裹在一个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)
});
}
深入研究插件的离子包装器,创建方法如下所示:
/**
* 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));
如有任何建议,我们将不胜感激
您可以通过循环遍历您的曲目并在每个曲目上等待 playOne
来让它工作。
async playAll(tracks: AudioFile[]): Promise<any> {
for (const track of tracks) {
await this.playOne(track);
}
}
如果我没记错的话 play
函数在播放完音频文件之前不会阻塞。它也不是 return 承诺。解决方法是在轨道持续期间使用 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
);
});
}
我认为使用 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
一些帮助您入门的链接:
我最终让它与递归函数一起工作。这按预期工作。
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)
如果有任何改进,我将不胜感激。
我正在尝试使用 ionic 媒体插件播放多个音频文件: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方法被包裹在一个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)
});
}
深入研究插件的离子包装器,创建方法如下所示:
/**
* 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));
如有任何建议,我们将不胜感激
您可以通过循环遍历您的曲目并在每个曲目上等待 playOne
来让它工作。
async playAll(tracks: AudioFile[]): Promise<any> {
for (const track of tracks) {
await this.playOne(track);
}
}
如果我没记错的话 play
函数在播放完音频文件之前不会阻塞。它也不是 return 承诺。解决方法是在轨道持续期间使用 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
);
});
}
我认为使用 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
一些帮助您入门的链接:
我最终让它与递归函数一起工作。这按预期工作。
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)
如果有任何改进,我将不胜感激。