如何在Android设备上实现锁屏音频控件。使用SimpleAudioPlayer

时间:2019-07-16 17:57:22

标签: c# android xamarin xamarin.forms audio-streaming

我正在尝试为基于媒体的应用程序实现锁屏音频控件。

我发现了许多尝试完成相同任务的人,但是我使用插件SimpleAudioPlayer https://github.com/adrianstevens/Xamarin-Plugins/tree/master/SimpleAudioPlayer时,大多数人都在使用Xamarin的MediaPlayer。

当前,我正在尝试遵循本文档,并查看是否可以将其连接到我当前正在使用的插件https://devblogs.microsoft.com/xamarin/lock-screen-music-controls-in-xamarin.android/

有人对如何进行连接有任何建议吗? Xamarin.Forms,Android项目。

当我第一次尝试关注该博客时,我将他们的RemoteControlBroadcastReceiver类信息与共享项目DABPlayer.cs一起放入,但找不到找到方法

StreamingBackgroundService.ActionTogglePlayback; break;
      case Keycode.MediaPlay: action = StreamingBackgroundService.ActionPlay; break;
      case Keycode.MediaPause: action = StreamingBackgroundService.ActionPause; break;

上班。具体找到可能是我的StreamingBackgroundService。然后,我尝试制作一个单独的StreamingBackgroundService,但他们使用的是MediaPlayer,而我正开始迷失在使我的SimpleAudioPlayer可以使用此代码的方式上。

如果有人对此有任何建议或更好的方法,将不胜感激。如果您需要更多或更少的信息,请告诉我。谢谢。

这是我共享的项目媒体播放器类的大致外观

public class DabPlayerEventArgs : EventArgs
    {
        public string ChannelTitle;
        public string EpisodeTitle;
        public double Duration;
        public double CurrentPosition;

        public DabPlayerEventArgs(DabPlayer player)
        {
            //Init the object with known values
            ChannelTitle = player.ChannelTitle;
            EpisodeTitle = player.EpisodeTitle;
            Duration = player.Duration;
            CurrentPosition = player.CurrentPosition;
        }
    }

    //Class that extends the basic player used by the apps.

    public class DabPlayer : ISimpleAudioPlayer, INotifyPropertyChanged
    {
        private IDabNativePlayer nativePlayer;
        private ISimpleAudioPlayer player;
        private string _channelTitle = "";
        private string _episodeTitle = "";
        private double _episodeDuration = 1; //Estimated duration of the episode
        private Timer timer = new Timer(500);
        private double LastPosition = 0;




        //Constructor 
        public DabPlayer(ISimpleAudioPlayer Player, bool IntegrateWithLockScreen)
        {
            player = Player; //store reference to the player

            //Set up events tied to the player
            player.PlaybackEnded += Player_PlaybackEnded;


            //Connect the native player interface
            nativePlayer = DependencyService.Get<IDabNativePlayer>();
            nativePlayer.Init(this, IntegrateWithLockScreen);


            //Set up the timer for tracking progress
            timer.Elapsed += OnTimerFired;
            timer.Enabled = true;
            timer.AutoReset = true;
            timer.Stop(); //Don't use it till we need it.
        }


        /* Event Handlers */
        public event EventHandler EpisodeDataChanged;
        protected virtual void OnEpisodeDataChanged(object sender, DabPlayerEventArgs e)
        {
            EventHandler handler = EpisodeDataChanged;
            handler?.Invoke(this, new DabPlayerEventArgs(this));
        }

        public event EventHandler EpisodeProgressChanged;
        protected virtual void OnEpisodeProgressChanged(object sender, DabPlayerEventArgs e)
        {
            EventHandler handler = EpisodeProgressChanged;
            handler?.Invoke(this, new DabPlayerEventArgs(this));
        }




        void Player_PlaybackEnded(object sender, EventArgs e)
        {
            //Handle playback ending (update button image)
            OnPropertyChanged("PlayPauseButtonImageBig");
        }

        public ISimpleAudioPlayer SimpleAudioPlayer
        {
            get
            {
                return player;
            }
        }

        /********************************
        ISimpleAudioPlayer Implementation 
        ********************************/

        public double Duration
        {
            get
            {
                //Return the duration of the player, ensuring it's >0
                if (player.Duration <= 0)
                {
                    //TODO: Use the episodes total length if possible
                    return _episodeDuration;
                }
                else
                {
                    return player.Duration;
                }
            }
        }

        //Current position of the player
        public double CurrentPosition
        {
            get
            {
                return player.CurrentPosition;
            }
        }

        //Remaining time for the player
        public double RemainingSeconds
        {
            get
            {
                return player.Duration - CurrentPosition;
            }
        }

        //Current position of the player as a percentage
        public double CurrentProgressPercentage
        {
            get
            {
                if (Duration > 0)
                {
                    return CurrentPosition / Duration;
                }
                else
                {
                    return 0;
                }
            }
        }

        public double Volume
        {
            get
            {
                return player.Volume;

            }
            set
            {
                player.Volume = value;
                OnPropertyChanged("Volume");
            }
        }
        public double Balance
        {
            get
            {
                return player.Balance;
            }
            set
            {
                player.Balance = value;
                OnPropertyChanged("Balance");
            }
        }

        public bool IsPlaying => player.IsPlaying;

        public bool Loop
        {
            get
            {
                return player.Loop;
            }
            set
            {
                player.Loop = value;
                OnPropertyChanged("Loop");
            }
        }

        public bool CanSeek => player.CanSeek;

        public event EventHandler PlaybackEnded
        {
            add
            {
                player.PlaybackEnded += value;
            }

            remove
            {
                player.PlaybackEnded -= value;
            }
        }

        public void Dispose()
        {
            player.Dispose();
        }


        public bool Load(Stream audioStream)
        {
            //Load a stream
            bool rv = player.Load(audioStream);
            OnPropertyChanged("Duration");
            OnPropertyChanged("IsReady");
            return rv;
        }

        public bool Load(string fileName)
        {
            //Load file, determine local or remote first
            //If remote, use a stream.
            bool rv;

            if (fileName.ToLower().StartsWith("http", StringComparison.Ordinal))
            {
                //Remote file
                WebClient wc = new WebClient();
                Stream fileStream = wc.OpenRead(fileName);
                rv = Load(fileStream);
            }
            else
            {
                //Local file
                FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
                rv = Load(fs);
            }
            return rv;

        }

        public bool Load(dbEpisodes episode)
        {
            try
            {
                //Stop playing the current episode if needed
                if (IsPlaying)
                {
                    Pause(); //Have to use PAUSE on Android or it will reset current time to 0.
                    //Stop();
                }

                //Load a specific episode (sets text properties as well
                EpisodeTitle = episode.title;
                ChannelTitle = episode.channel_title;

                OnEpisodeDataChanged(this, new DabPlayerEventArgs(this));
                return Load(episode.File_name);
            }
            catch (Exception ex)
            {
                return false;
            }


        }


        public void Pause()
        { 
            player.Pause();
            timer.Stop();
            OnPropertyChanged("PlayPauseButtonImageBig");

            UpdateEpisodeDataOnStop(); //Episode has been stopped
        }

        public void Play()
        {
            if (IsPlaying)
            {
                //Stop the current episode properly if needed.
                Stop();
            }

            player.Play();
            timer.Start();
            OnPropertyChanged("PlayPauseButtonImageBig");
        }

        public void Seek(double position)
        {
            player.Seek(position);
            OnPropertyChanged("CurrentPosition");
            OnPropertyChanged("RemainingSeconds");
            OnPropertyChanged("CurrentProgressPercentage");
        }

        public void Stop()
        {
            player.Stop();
            timer.Stop();
            OnPropertyChanged("PlayPauseButtonImageBig");

            UpdateEpisodeDataOnStop(); //episode has stopped

        }

我的Android本机播放器类如下

public class DroidDabNativePlayer : BroadcastReceiver, IDabNativePlayer
    {

        DabPlayer player;

        public string ComponentName { get { return this.Class.Name; } }


        public DroidDabNativePlayer(ISimpleAudioPlayer Player, bool IntegrateWithLockScreen)
        {
        }

        public void Init(DabPlayer Player, bool IntegrateWithLockScreen)
        {
            player = Player;


            if (IntegrateWithLockScreen)
            {
                /* SET UP LOCK SCREEN */
                //TODO: Set up lock screen

            }
        }
    }

在将项目移交给我之前,已经设置了iOS锁屏控件,我可以在下面发布该代码,以查看它是否有用。

public class iosDabNativePlayer : IDabNativePlayer
    {
        DabPlayer player;
        MPNowPlayingInfo nowPlayingInfo;


        public void Init(DabPlayer Player, bool IntegrateWithLockScreen)
        {

            player = Player;

            AVAudioSession.SharedInstance().SetActive(true);
            AVAudioSession.SharedInstance().SetCategory(AVAudioSessionCategory.Playback);


            /* SET UP LOCK SCREEN COMPONENTS (if needed) */

            if (IntegrateWithLockScreen)
            {
                //Remote Control (Lock Screen)
                UIApplication.SharedApplication.BeginReceivingRemoteControlEvents();

                nowPlayingInfo = new MPNowPlayingInfo();
                nowPlayingInfo.Artist = "Daily Audio Bible";

                player.EpisodeDataChanged += (sender, e) => 
                {
                    //Update the lock screen with new playing info
                    DabPlayerEventArgs args = (DabPlayerEventArgs)e;
                    nowPlayingInfo.Title = args.EpisodeTitle;
                    nowPlayingInfo.AlbumTitle = args.ChannelTitle;
                    nowPlayingInfo.Artist = "Daily Audio Bible";
                    nowPlayingInfo.PlaybackDuration = args.Duration;
                    nowPlayingInfo.ElapsedPlaybackTime = args.CurrentPosition;
                    MPNowPlayingInfoCenter.DefaultCenter.NowPlaying = nowPlayingInfo;
                };

                player.EpisodeProgressChanged += (object sender, EventArgs e) =>
                {
                    //Update lock screen with nee position info
                    DabPlayerEventArgs args = (DabPlayerEventArgs)e;
                    nowPlayingInfo.Title = args.EpisodeTitle;
                    nowPlayingInfo.AlbumTitle = args.ChannelTitle;
                    nowPlayingInfo.Artist = "Daily Audio Bible";
                    nowPlayingInfo.PlaybackDuration = args.Duration;
                    nowPlayingInfo.ElapsedPlaybackTime = args.CurrentPosition;
                    MPNowPlayingInfoCenter.DefaultCenter.NowPlaying = nowPlayingInfo;
                };

                /* Lock Screen Events */

                //Handle play event from lock screen
                MPRemoteCommandCenter.Shared.PlayCommand.AddTarget((arg) =>
                {
                    try
                    {
                        GlobalResources.playerPodcast.Play();
                        return MPRemoteCommandHandlerStatus.Success;
                    }
                    catch (Exception ex)
                    {
                        return MPRemoteCommandHandlerStatus.CommandFailed;
                    }
                });

                //Handle pause event from lock scren
                MPRemoteCommandCenter.Shared.PauseCommand.AddTarget((arg) =>
                {
                    try
                    {
                        GlobalResources.playerPodcast.Pause();
                        return MPRemoteCommandHandlerStatus.Success;
                    }
                    catch (Exception ex)
                    {
                        return MPRemoteCommandHandlerStatus.CommandFailed;
                    }

                });


                //Handle skip forward command from lock screen
                MPRemoteCommandCenter.Shared.SkipForwardCommand.AddTarget((arg) =>
                {
                    try
                    {
                        GlobalResources.playerPodcast.Skip(15); //icon says 15 seconds
                        return MPRemoteCommandHandlerStatus.Success;
                    }
                    catch (Exception ex)
                    {
                        return MPRemoteCommandHandlerStatus.CommandFailed;
                    }

                });

                //Handle skip backward command from lock screen
                MPRemoteCommandCenter.Shared.SkipBackwardCommand.AddTarget((arg) =>
                {
                    try
                    {
                        GlobalResources.playerPodcast.Skip(-15); //icon says 15 seconds
                        return MPRemoteCommandHandlerStatus.Success;
                    }
                    catch (Exception ex)
                    {
                        return MPRemoteCommandHandlerStatus.CommandFailed;
                    }

                });

            }
        }

0 个答案:

没有答案