Beispiel #1
0
        internal async void HandleMetadata(SongMetadata songMetadata, StationStream currentStream)
        {
            if (songMetadata == null || songMetadata.IsUnknownMetadata)
            {
                SetCurrentMetadataToUnknown();
                return;
            }

            await metadataLock.WaitAsync();

            try
            {
                CurrentStation = await NepApp.Stations.GetStationByNameAsync(currentStream.ParentStation);

                StationProgram currentProgram = null;
                if (IsHostedStationProgramBeginning(songMetadata, CurrentStation, out currentProgram))
                {
                    //we're tuning into a hosted radio program. this may be a DJ playing remixes, for example.

                    ActivateStationProgrammingMode(songMetadata, currentStream, currentProgram);

                    //block programs are handled differently.
                }
                else
                {
                    //we're tuned into regular programming/music

                    HandleStationSongMetadata(songMetadata, currentStream, CurrentStation);
                }
            }
            finally
            {
                metadataLock.Release();
            }
        }
Beispiel #2
0
        public override async Task TryConnectAsync(StationStream stream)
        {
            var httpRequest  = new HttpRequestMessage(HttpMethod.Get, stream.StreamUrl); //some servers don't support head. we need a better way to poke the server
            var httpResponse = await httpClient.SendRequestAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead);

            if (!httpResponse.IsSuccessStatusCode)
            {
                throw new Neptunium.Core.NeptuniumStreamConnectionFailedException(stream);
            }

            //collect header information here

            httpRequest.Dispose();
            httpResponse.Dispose();
            httpClient.Dispose();

            await Task.Delay(500);

            StreamMediaSource = MediaSource.CreateFromUri(stream.StreamUrl);

            var station = await NepApp.Stations.GetStationByNameAsync(stream.ParentStation);

            RaiseMetadataChanged(new Core.Media.Metadata.SongMetadata()
            {
                Artist          = "Unknown Artist", Track = "Unknown Song",
                StationPlayedOn = stream.ParentStation, StationLogo = station.StationLogoUrl, IsUnknownMetadata = true
            });
        }
        public NeptuniumStreamConnectionFailedException(StationStream stream, Exception inner = null) : base(inner)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            Stream = stream;

            _message = string.Format("We were unable to stream {0} for some reason. ", Stream.SpecificTitle) + inner?.Message;
        }
Beispiel #4
0
        private void ActivateStationProgrammingMode(SongMetadata songMetadata, StationStream currentStream, StationProgram currentProgram)
        {
            StationRadioProgramStarted?.Invoke(this, new NepAppStationProgramStartedEventArgs()
            {
                RadioProgram = currentProgram,
                Metadata     = songMetadata,
                Station      = currentStream?.ParentStation
            });

            CurrentProgram = currentProgram;
            SetCurrentMetadataToUnknownInternal(currentProgram.Name);
        }
        public NeptuniumStreamConnectionFailedException(StationStream stream, string message, Exception inner = null) : base(inner)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }
            if (string.IsNullOrWhiteSpace(message))
            {
                throw new ArgumentNullException(nameof(message));
            }

            Stream   = stream;
            _message = message;
        }
Beispiel #6
0
        private async void HandleStationSongMetadata(SongMetadata songMetadata, StationStream currentStream, StationItem currentStation)
        {
            if (CurrentProgram != null)
            {
                if (CurrentProgram.Style == StationProgramStyle.Hosted)
                {
                    CurrentProgram = null; //hosted program ended.
                }
            }

            //filter out station messages
            if (!string.IsNullOrWhiteSpace(currentStream.ParentStation))
            {
                if (currentStation.StationMessages != null)
                {
                    if (currentStation.StationMessages.Contains(songMetadata.Track) ||
                        currentStation.StationMessages.Contains(songMetadata.Artist))
                    {
                        NepAppStationMessageReceived?.Invoke(this, new NepAppStationMessageReceivedEventArgs(songMetadata));
                        metadataLock.Release();
                        return;
                    }
                }
            }

            if (CurrentSong != null)
            {
                if (CurrentSong.ToString().Equals(songMetadata.ToString()))
                {
                    return;
                }
            }

            CurrentSong = songMetadata;
            //this is used for the now playing bar via data binding.
            RaisePropertyChanged(nameof(CurrentSong));

            PreSongChanged?.Invoke(this, new NepAppSongChangedEventArgs(songMetadata));

            await HandleStationSongMetadataStage2Async(songMetadata);
        }
        private static async Task StreamLastPlayedStationAsync()
        {
            var station = await NepApp.Stations.GetStationByNameAsync(NepApp.Stations.LastPlayedStationName);

            if (station != null)
            {
                var controller = await NepApp.UI.Overlay.ShowProgressDialogAsync(string.Format("Connecting to {0}...", station.Name), "Please wait...");

                controller.SetIndeterminate();

                try
                {
                    StationStream stream = null;
                    if (stream == null)
                    {
                        //check if we need to automatically choose a lower bitrate.
                        if ((int)NepApp.Network.NetworkUtilizationBehavior < 2) //check if we're on "conservative" or "opt-in"
                        {
                            //grab the stream with the lowest bitrate
                            stream = station.Streams.OrderBy(x => x.Bitrate).First();
                        }
                        else
                        {
                            stream = station.Streams.OrderByDescending(x => x.Bitrate).First(); //otherwise, grab a higher bitrate
                        }
                    }

                    await NepApp.MediaPlayer.TryStreamStationAsync(stream);
                }
                catch (Exception ex)
                {
                    await NepApp.UI.ShowInfoDialogAsync("Uh-oh! Couldn't do that!", ex.Message);
                }
                finally
                {
                    await controller.CloseAsync();
                }
            }
        }
        public override async Task TryConnectAsync(StationStream stream)
        {
            try
            {
                streamSource = await ShoutcastStreamFactory.ConnectAsync(stream.StreamUrl, new ShoutcastStreamFactoryConnectionSettings()
                {
                    UserAgent          = "Neptunium (http://github.com/Amrykid/Neptunium)",
                    RelativePath       = stream.RelativePath,
                    RequestSongMetdata = stream.RequestMetadata
                });

                streamSource.Reconnected       += StreamSource_Reconnected;
                streamSource.MetadataChanged   += ShoutcastStream_MetadataChanged;
                StreamMediaSource               = MediaSource.CreateFromMediaStreamSource(streamSource.MediaStreamSource);
                StreamMediaSource.StateChanged += StreamMediaSource_StateChanged;
                this.StationPlaying             = await NepApp.Stations.GetStationByNameAsync(stream.ParentStation);

                ShoutcastStationInfo = streamSource.StationInfo;
                RaiseStationInfoAcquired(streamSource.StationInfo);
            }
            catch (Exception ex)
            {
                if (ex is System.Runtime.InteropServices.COMException)
                {
                    if (ex.HResult == -2147014836)
                    {
                        /* A connection attempt failed because the connected party did not properly respond after a period of time, or
                         * established connection failed because connected host has failed to respond. */

                        //At this point, we've already timed out and informed the user. We can use return out of this.

                        return;
                    }
                }

                throw new Neptunium.Core.NeptuniumStreamConnectionFailedException(stream, ex);
            }
        }
 public abstract Task TryConnectAsync(StationStream stream);
        public async Task TryStreamStationAsync(StationStream stream)
        {
            if (!NepApp.Network.IsConnected)
            {
                throw new NeptuniumNetworkConnectionRequiredException();
            }

            await playLock.WaitAsync();

            ConnectingBegin?.Invoke(this, EventArgs.Empty);

            BasicNepAppMediaStreamer streamer = CreateStreamerForServerFormat(stream.ServerFormat);

            Task timeoutTask    = null;
            Task connectionTask = null;


            timeoutTask = Task.Delay(10000);

            connectionTask = streamer.TryConnectAsync(stream); //a failure to connect is caught as a Neptunium.Core.NeptuniumStreamConnectionFailedException by AppShellViewModel

            Task result = await Task.WhenAny(connectionTask, timeoutTask);

            if (result == timeoutTask || connectionTask.IsFaulted)
            {
                ConnectingEnd?.Invoke(this, EventArgs.Empty);
                streamer.Dispose();
                playLock.Release();
                throw new NeptuniumStreamConnectionFailedException(stream, connectionTask.Exception?.InnerException?.Message ?? "Connection timed out.");
            }

            ShutdownPreviousPlaybackSession();

            CurrentPlayer = new MediaPlayer();

            MediaTransportControls = CurrentPlayer.SystemMediaTransportControls;
            MediaTransportControls.IsChannelDownEnabled = false;
            MediaTransportControls.IsChannelUpEnabled   = false;
            MediaTransportControls.IsFastForwardEnabled = false;
            MediaTransportControls.IsNextEnabled        = false;
            MediaTransportControls.IsPreviousEnabled    = false;
            MediaTransportControls.IsRewindEnabled      = false;
            MediaTransportControls.IsRewindEnabled      = false;
            MediaTransportControls.IsPlayEnabled        = true;
            MediaTransportControls.IsPauseEnabled       = true;

            CurrentPlayer.AudioCategory            = MediaPlayerAudioCategory.Media;
            CurrentPlayer.CommandManager.IsEnabled = true;
            CurrentPlayer.AudioDeviceType          = MediaPlayerAudioDeviceType.Multimedia;
            CurrentPlayer.Volume       = playerVolume;
            CurrentPlayer.MediaFailed += CurrentPlayer_MediaFailed;
            CurrentPlayerSession       = CurrentPlayer.PlaybackSession;
            CurrentPlayerSession.PlaybackStateChanged += PlaybackSession_PlaybackStateChanged;

            streamer.InitializePlayback(CurrentPlayer);

            await CurrentPlayer.WaitForMediaOpenAsync();

            streamer.MetadataChanged += Streamer_MetadataChanged;

            CurrentStreamer = streamer;
            CurrentStream   = stream;

            NepApp.SongManager.SetCurrentStation(await NepApp.Stations.GetStationByNameAsync(CurrentStream.ParentStation));

            SetMediaEngagement(true);

            NepApp.Stations.SetLastPlayedStation(stream.ParentStation, DateTime.Now);
            NepApp.SongManager.SetCurrentMetadataToUnknown();

            streamer.Play();

            ConnectingEnd?.Invoke(this, EventArgs.Empty);
            playLock.Release();
        }