我有两个声音
say_1() { //music
this.audio.src = './sound1.wav';
this.audio.load();
// auto-start
this.audio.play();
}
say_2() { //speech
this.audio.src = './sound2.wav';
this.audio.load();
// auto-start
this.audio.play();
}
我想制作一个接着播放一个声音的方法play_all();
play_all () {
this.say_1();
this.say_2();
}
所以,我想先播放我的音乐,然后演讲, 但在我的方法中,它只播放第二个wav,我猜它是因为我有这个方法
ngOnDestroy() {
// destroy audio here
if (this.audio) {
this.audio.pause();
this.audio = null;
}
}
我需要这种方法,因为如果我离开页面(通过路由器转到下一页),前一页的音乐仍然会播放。
我怎么能修改我的方法,所以它会一个接一个地发出声音?
答案 0 :(得分:3)
原因是音频正在异步播放。这意味着此play()
方法不会等到播放结束。
为了一个接一个地播放这些声音,你必须在ended
事件发生时开始播放你的第二个文件。
最天真的解决方案可能如下所示:
say_1() { //music
this.audio.src = './sound1.wav';
// whenever playback ends call the next function
this.audio.onended = () => {
this.audio.onended = null;
this.say_2();
}
this.audio.load();
this.audio.play();
}
say_2() { //speech
this.audio.src = './sound2.wav';
this.audio.load();
this.audio.play();
}
然后您可以调用playAll()
方法而不是say_1()
。
你也可以这样将它提取到AudioPlayerService中:
@Injectable()
export class AudioPlayerService {
playbackEndedSource = new Subject<string>();
playbackEnded$ = this.playbackEndedSource.asObservable();
constructor() {
// this.audio initialization
this.audio.addEventListener('ended', () => this.playbackEndedSource.next());
}
play(path: string): void {
this.audio.src = path;
this.audio.load();
this.audio.play();
}
}
然后你就可以这样做
export class AppComponent {
constructor(private player: AudioPlayerService) {}
playAll() {
const subscription = player.playbackEnded$
.subscribe(() => {
player.play('audio2.wav');
// to prevent it from playing over and over again
subscription.unsubscribe();
});
player.play('audio1.wav');
}
}