在Angular2中一个接一个地播放2个声音

时间:2017-07-26 13:54:58

标签: angular typescript

我有两个声音

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

我需要这种方法,因为如果我离开页面(通过路由器转到下一页),前一页的音乐仍然会播放。

我怎么能修改我的方法,所以它会一个接一个地发出声音?

1 个答案:

答案 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');

    }
}