This class implements the basic audio player behavior. The actual playback implementation is defined in the IMediaPlayerCallback implementations.
Inheritance: IEnableLogger
            public async Task LoadsIntoAudioPlayerIfSongIsAudio()
            {
                var audioPlayer = new AudioPlayer();
                var mediaPlayerCallback = Substitute.For<IMediaPlayerCallback>();
                audioPlayer.RegisterAudioPlayerCallback(mediaPlayerCallback);

                var song = Helpers.SetupSongMock("C://", TimeSpan.Zero);
                song.IsVideo.Returns(false);

                await audioPlayer.LoadAsync(song);

                mediaPlayerCallback.ReceivedWithAnyArgs().LoadAsync(Arg.Any<Uri>());
            }
            public async Task DisposesCurrentAudioPlayerIfNewOneRegistered()
            {
                var audioPlayer = new AudioPlayer();

                var oldMediaPlayer = Substitute.For<IMediaPlayerCallback, IDisposable>();
                var newMediaPlayer = Substitute.For<IMediaPlayerCallback, IDisposable>();

                audioPlayer.RegisterAudioPlayerCallback(oldMediaPlayer);
                await audioPlayer.LoadAsync(Helpers.SetupSongMock());

                audioPlayer.RegisterAudioPlayerCallback(newMediaPlayer);

                ((IDisposable)oldMediaPlayer).DidNotReceive().Dispose();

                await audioPlayer.LoadAsync(Helpers.SetupSongMock());

                ((IDisposable)oldMediaPlayer).Received().Dispose();
            }
Beispiel #3
0
        public Library(ILibraryReader libraryReader, ILibraryWriter libraryWriter, CoreSettings settings,
            IFileSystem fileSystem, Func<string, ILocalSongFinder> localSongFinderFunc = null)
        {
            if (libraryReader == null)
                throw new ArgumentNullException("libraryReader");

            if (libraryWriter == null)
                throw new ArgumentNullException("libraryWriter");

            if (settings == null)
                throw new ArgumentNullException("settings");

            if (fileSystem == null)
                throw new ArgumentNullException("fileSystem");

            this.libraryReader = libraryReader;
            this.libraryWriter = libraryWriter;
            this.settings = settings;
            this.fileSystem = fileSystem;
            this.localSongFinderFunc = localSongFinderFunc ?? (x => new LocalSongFinder(x));

            this.globalSubscriptions = new CompositeDisposable();
            this.accessControl = new AccessControl(settings);
            this.songLock = new ReaderWriterLockSlim();
            this.songs = new HashSet<LocalSong>();
            this.playlists = new ReactiveList<Playlist>();
            this.songsUpdated = new Subject<Unit>();
            this.audioPlayer = new AudioPlayer();
            this.manualUpdateTrigger = new Subject<Unit>();

            this.LoadedSong = this.audioPlayer.LoadedSong;
            this.TotalTime = this.audioPlayer.TotalTime;
            this.PlaybackState = this.audioPlayer.PlaybackState;

            this.WhenAnyValue(x => x.CurrentPlaylist.CanPlayNextSong).SampleAndCombineLatest(this.audioPlayer.PlaybackState
                    .Where(p => p == AudioPlayerState.Finished), (canPlayNextSong, _) => canPlayNextSong)
                .SelectMany(x => this.HandleSongFinishAsync(x).ToObservable())
                .Subscribe();

            this.CurrentPlaybackTime = this.audioPlayer.CurrentTimeChanged;

            this.volume = this.settings.WhenAnyValue(x => x.Volume)
                .ToProperty(this, x => x.Volume);
        }
        public async Task StopsCurrentMediaPlayerWhenSwitchingAndPlaying()
        {
            var audioPlayer = new AudioPlayer();

            var oldMediaPlayer = Substitute.For<IMediaPlayerCallback>();
            var newMediaPlayer = Substitute.For<IMediaPlayerCallback>();

            audioPlayer.RegisterAudioPlayerCallback(oldMediaPlayer);

            var song = Helpers.SetupSongMock();

            await audioPlayer.LoadAsync(song);
            await audioPlayer.PlayAsync();

            audioPlayer.RegisterAudioPlayerCallback(newMediaPlayer);

            var song2 = Helpers.SetupSongMock();

            await audioPlayer.LoadAsync(song2);
            await audioPlayer.PlayAsync();

            oldMediaPlayer.Received(1).StopAsync();
        }
Beispiel #5
0
        private void InternPlaySong(int playlistIndex)
        {
            if (playlistIndex < 0)
                Throw.ArgumentOutOfRangeException(() => playlistIndex, 0);

            if (this.isWaitingOnCache)
            {
                this.overrideCurrentCaching = true;

                // Let the song that is selected to be played wait here, if there is currently another song caching
                cacheResetHandle.WaitOne();
            }

            if (this.currentPlayingPlaylist != null)
            {
                this.currentPlayingPlaylist.CurrentSongIndex = null;
            }

            this.currentPlayingPlaylist = this.currentPlaylist;

            this.currentPlaylist.CurrentSongIndex = playlistIndex;

            Song song = this.currentPlaylist[playlistIndex];

            if (this.currentPlayer != null)
            {
                this.currentPlayer.Dispose();
            }

            this.currentPlayer = song.CreateAudioPlayer();

            this.currentPlayer.SongFinished += (sender, e) => this.HandleSongFinish();
            this.currentPlayer.Volume = this.volume;

            Task.Factory.StartNew(() =>
            {
                if (song.HasToCache && !song.IsCached)
                {
                    bool cached = this.AwaitCaching(song);

                    if (!cached)
                    {
                        return;
                    }
                }

                this.overrideCurrentCaching = false;

                this.currentPlayer.Load(song);
                this.currentPlayer.Play();

                this.SongStarted.RaiseSafe(this, EventArgs.Empty);
            });
        }
Beispiel #6
0
        private void RenewCurrentPlayer(Song song)
        {
            if (this.currentPlayer != null)
            {
                this.currentPlayer.Dispose();
            }

            this.currentPlayer = song.CreateAudioPlayer();

            if (this.currentPlayer is IVideoPlayerCallback)
            {
                this.VideoPlayerCallbackChanged.RaiseSafe(this, EventArgs.Empty);
            }

            this.currentPlayer.SongFinished += (sender, e) => this.HandleSongFinish();
            this.currentPlayer.Volume = this.Volume;
        }
Beispiel #7
0
        private void HandleSongFinish()
        {
            if (!this.CurrentPlaylist.CanPlayNextSong)
            {
                this.CurrentPlaylist.CurrentSongIndex = null;
            }

            this.currentPlayer.Dispose();
            this.currentPlayer = null;

            this.SongFinished.RaiseSafe(this, EventArgs.Empty);

            if (this.CurrentPlaylist.CanPlayNextSong)
            {
                this.InternPlayNextSong();
            }
        }
Beispiel #8
0
        private void InternPlaySong(int playlistIndex)
        {
            playlistIndex.ThrowIfLessThan(0, () => playlistIndex);

            this.playlist.CurrentSongIndex = playlistIndex;

            Song song = this.playlist[playlistIndex];

            if (this.currentPlayer != null)
            {
                this.currentPlayer.Dispose();
            }

            this.currentPlayer = song.CreateAudioPlayer();

            this.currentPlayer.SongFinished += (sender, e) => this.HandleSongFinish();
            this.currentPlayer.Volume = this.Volume;

            Task.Factory.StartNew(() =>
            {
                // Wait till the song is cached
                while (!song.IsCached)
                {
                    Thread.Sleep(250);
                }

                this.currentPlayer.Load(song);
                this.currentPlayer.Play();

                this.SongStarted.RaiseSafe(this, EventArgs.Empty);
            });
        }
 public void CanSetVolumeAfterConstruction()
 {
     var audioPlayer = new AudioPlayer();
     audioPlayer.SetVolume(0);
 }
        public void CanGetCurrentTimeAfterConstruction()
        {
            var audioPlayer = new AudioPlayer();

            Assert.Equal(TimeSpan.Zero, audioPlayer.CurrentTime);
        }
            public async Task DisposesDanglingAudioPlayer()
            {
                var audioPlayer = new AudioPlayer();
                var mediaPlayer = Substitute.For<IMediaPlayerCallback>();
                audioPlayer.RegisterAudioPlayerCallback(mediaPlayer);
                await audioPlayer.LoadAsync(Helpers.SetupSongMock());

                var danglingPlayer = Substitute.For<IMediaPlayerCallback, IDisposable>();

                audioPlayer.RegisterAudioPlayerCallback(danglingPlayer);

                var newPlayer = Substitute.For<IMediaPlayerCallback>();

                audioPlayer.RegisterAudioPlayerCallback(newPlayer);

                ((IDisposable)danglingPlayer).Received(1).Dispose();
            }
            public async Task StopsCurrentPlayback()
            {
                var audioPlayer = new AudioPlayer();

                var states = audioPlayer.PlaybackState.CreateCollection();

                var mediaPlayer = Substitute.For<IMediaPlayerCallback>();
                mediaPlayer.Finished.Returns(Observable.Never<Unit>());
                audioPlayer.RegisterAudioPlayerCallback(mediaPlayer);

                await audioPlayer.LoadAsync(Helpers.SetupSongMock());
                await audioPlayer.PlayAsync();

                await audioPlayer.LoadAsync(Helpers.SetupSongMock());

                Assert.Equal(new[] { AudioPlayerState.None, AudioPlayerState.Stopped, AudioPlayerState.Playing, AudioPlayerState.Stopped }, states);
            }