2017-10-05 3 views
0

Ich habe eine "Player" -Klasse, die meinen globalen Musikplayer verwalten soll. Das funktioniert auch so weit. Die Klasse ist ganz unten. Wenn Sie Verbesserungsvorschläge haben, können Sie uns diese gerne geben.Starten Sie den nächsten Song, während einer spielt

Ich möchte einen zweiten Song starten, während der aktuelle Song endet. Also ein FadeIn in den nächsten Song und ein FadeOut vom aktuellen Song, der den Song leiser macht.

Mein Ansatz ist im Moment, dass ein Song im "waveOutDevice1" -Objekt läuft und der zweite im zweiten Objekt wartet. Und sobald der aktuelle Song kurz vor dem Ende steht, startet der zweite WavePlayer. Aber ich weiß nicht, wie ich darauf reagieren kann, sobald das aktuelle Lied zu Ende geht.

Haben Sie eine Idee oder Vorschläge? Mit freundlichen Grüßen

meine Spielerklasse:

public class Player 
{ 
    #region Properties, Fields 
    private IWavePlayer waveOutDevice1; 
    private IWavePlayer waveOutDevice2; 
    private AudioFileReader fileReader1; 
    private AudioFileReader fileReader2; 

    public AudioFile CurrentSong { get; private set; } 
    public Playlist CurrentPlaylist { get; private set; } 

    public List<AudioFile> lstPastSongs { get; private set; } 

    public List<AudioFile> lstNextSongs { get; set; } 

    public PlaybackState PlaybackState { get; private set; } 

    public bool Muted { get; private set; } 

    private float OldVolume = 0.0f; 
    #endregion 

    public Player() 
    { 
     this.lstNextSongs = new List<AudioFile>(); 
     this.lstPastSongs = new List<AudioFile>(); 
    } 

    #region Methods 
    public void Play(int index) 
    { 
     if (this.lstNextSongs.Count > 0 && index >= 0 && index < this.lstNextSongs.Count) 
     { 
      this.ResetFileReader(); 
      this.CurrentSong = this.lstNextSongs[index]; 
      this.CurrentPlaylist = this.CurrentSong.Playlist; 
      this.lstNextSongs.RemoveAt(index); 
      this.fileReader1 = new AudioFileReader(this.CurrentSong.Path); 
      this.waveOutDevice1 = new WaveOut(); 
      this.waveOutDevice1.PlaybackStopped += WaveOutDevice1_PlaybackStopped; 

      this.waveOutDevice1.Init(this.fileReader1); 
      this.PlaybackState = PlaybackState.Playing; 
      this.waveOutDevice1.Play(); 
     } 
    } 

    private void WaveOutDevice1_PlaybackStopped(object sender, StoppedEventArgs e) 
    { 
     this.Next(); 
    } 

    private void ResetFileReader() 
    { 
     if (this.fileReader1 != null) 
     {     
      this.fileReader1.Dispose(); 
      this.fileReader1 = null; 
     } 
     if (this.fileReader2 != null) 
     { 
      this.fileReader2.Dispose(); 
      this.fileReader2 = null; 
     } 
     if(this.waveOutDevice1 != null) 
     { 
      this.waveOutDevice1.Dispose(); 
      this.waveOutDevice1 = null; 
     } 
     if(this.waveOutDevice2 != null) 
     { 
      this.waveOutDevice2.Dispose(); 
      this.waveOutDevice2 = null; 
     } 
    } 

    public void Pause() 
    { 
     if(this.waveOutDevice1 != null) 
      if (this.waveOutDevice1.PlaybackState == PlaybackState.Playing) 
       this.waveOutDevice1.Pause(); 
     if(this.waveOutDevice2 != null) 
      if (this.waveOutDevice2.PlaybackState == PlaybackState.Playing) 
       this.waveOutDevice2.Pause(); 
     this.PlaybackState = PlaybackState.Paused; 
    } 

    public void Continue() 
    { 
     if (this.waveOutDevice1 != null) 
      if (this.waveOutDevice1.PlaybackState == PlaybackState.Paused) 
       this.waveOutDevice1.Play(); 
     if (this.waveOutDevice2 != null) 
      if (this.waveOutDevice2.PlaybackState == PlaybackState.Paused) 
       this.waveOutDevice2.Play(); 
     this.PlaybackState = PlaybackState.Playing; 
    } 

    public void Next() 
    { 
     if(this.lstNextSongs.Count > 0) 
     { 
      if (this.CurrentSong != null) 
       this.lstPastSongs.Add(this.CurrentSong); 
      if (GlobalSettings.Shuffle) 
      { 
       System.Random random = new System.Random(); 
       int randomNumber = random.Next(0, this.lstNextSongs.Count - 1); 
       this.Play(randomNumber); 
      } 
      else 
       this.Play(0); 
     } 
     else 
     { 
      if(GlobalSettings.Replay) 
       if(GlobalSettings.CurrentPlaylist != null) 
        for (int i = 0; i < GlobalSettings.CurrentPlaylist.panPlaylist.SongPlaylist.NumberOfSongs; i++) 
         this.lstNextSongs.AddRange(GlobalSettings.CurrentPlaylist.panPlaylist.SongPlaylist.AllSongs); 
     } 
    } 

    public void Previous() 
    { 
     if(this.CurrentSong == null) 
     { 
      if(this.lstPastSongs.Count > 0) 
      { 
       this.lstNextSongs.Insert(0, this.lstPastSongs[this.lstPastSongs.Count - 1]); 
       this.lstPastSongs.RemoveAt(this.lstPastSongs.Count - 1); 
       this.Play(0); 
      } 
     } 
     else 
     { 
      if(this.fileReader1 != null) 
       this._Previous(this.waveOutDevice1, this.fileReader1); 
      else if(this.fileReader2 != null) 
       this._Previous(this.waveOutDevice2, this.fileReader2); 
     } 
    } 

    private void _Previous(IWavePlayer waveOutDevice, AudioFileReader fileReader) 
    { 
     if (fileReader.CurrentTime.Seconds >= 10 || this.lstPastSongs.Count == 0) 
     { 
      waveOutDevice.Pause(); 
      fileReader.CurrentTime = new System.TimeSpan(0, 0, 0); 
      waveOutDevice.Play(); 
     } 
     else 
     { 
      this.lstNextSongs.Insert(0, this.CurrentSong); 
      this.lstNextSongs.Insert(0, this.lstPastSongs[this.lstPastSongs.Count - 1]); 
      this.lstPastSongs.RemoveAt(this.lstPastSongs.Count - 1); 
      this.Play(0); 
     } 
    } 

    public void SetVolume(int Volume) 
    { 
     if (Volume > -1 && Volume < 101) 
     { 

      float vol = (float)Volume/100; 
      if (this.fileReader1 != null) 
       this.fileReader1.Volume = vol; 
      if (this.fileReader2 != null) 
       this.fileReader2.Volume = vol; 
      this.Muted = false; 
     } 
    } 

    public void Mute() 
    { 
     if(this.Muted) 
     { 
      if(this.fileReader1 != null) 
      { 
       this.fileReader1.Volume = this.OldVolume; 
       this.Muted = false; 
      } 
      else if(this.fileReader2 != null) 
      { 
       this.fileReader2.Volume = this.OldVolume; 
       this.Muted = false; 
      } 
     } 
     else 
     { 
      this.Muted = true; 
      if(this.fileReader1 != null) 
      { 
       this.OldVolume = this.fileReader1.Volume; 
       this.fileReader1.Volume = 0; 
      } 
      else if(this.fileReader2 != null) 
      { 
       this.OldVolume = this.fileReader2.Volume; 
       this.fileReader2.Volume = 0; 
      } 
     } 
    } 
    #endregion 
} 

Antwort

0

Wenn Sie die Dauer des Songs bekommen kann, wenn es beginnt zu spielen, können Sie einen Timer für duration - fadeInTime einstellen und Ihre verblassen beginnen, wenn der Timer ausgelöst wird.

+0

yesthat wäre eine Alternative. aber meiner Meinung nach wäre ein Timer eine schlechte Idee für eine gute Leistung. – ExclusivAtom

+0

Es sollte nicht sein. Vor allem, wenn Sie es in einem anderen Thread ausführen. 'Thread.Sleep()' ist SEHR geringe Auswirkung. – theGleep

+0

Dann werde ich einen anderen Timer verwenden, bis ich eine bessere Lösung finde. – ExclusivAtom

0

Ein anderer Ansatz besteht darin, ein einzelnes Wave-Out-Gerät und MixingSampleProvider zu verwenden, um den zweiten Song als neuen Eingang in den Mixer einzufügen, wenn der erste endet. Sie können dies tun, indem Sie Ihren eigenen Wrapper ISampleProvider erstellen, dessen Read Methode genau verfolgen kann, wo Sie gerade sind.

+0

Ich habe jetzt für ein paar Stunden auf einem Übergang gesessen, aber ich kann nicht scheinen, es richtig zu machen. Ich habe mir auch das Projekt "MusicToCodeBy" angeschaut, die Musik läuft zur gleichen Zeit, aber Songs mit Übergängen nacheinander, ich komme da nicht hin. Hast du ein Beispiel für mich? – ExclusivAtom

+0

Ich beobachtete auch die Klasse "https://stackoverflow.com/questions/9468083/fading-sound-in-out-using-naudio" Aber die Klasse brachte mich nirgends. – ExclusivAtom

Verwandte Themen