Updating player view model and common 59/260459/3
authoraman.jeph <aman.jeph@samsung.com>
Fri, 25 Jun 2021 06:15:25 +0000 (11:45 +0530)
committeraman.jeph <aman.jeph@samsung.com>
Mon, 28 Jun 2021 09:59:04 +0000 (15:29 +0530)
Change-Id: Ic25be459461fdce9fe2c8007ceb6858b0ebb6af0
Signed-off-by: aman.jeph <aman.jeph@samsung.com>
Common/AppConstants.cs
Common/PlayerCommon.cs
Models/PlayerModel.cs
ViewModels/PlayerViewModel.cs
Views/PlayerView.cs

index 98cfef0a8632aafe4496c1a0e2d4e5fd771ef138..3dfb522f0d568e1c6bea8a4c61b2a775a5f1b2e5 100755 (executable)
@@ -7,5 +7,8 @@
         // KeyCodes
         public const string BackKeyCode = "XF86Back";
         public const string EscapeKeyCode = "Escape";
+
+        // string literals
+        public const string TimeFormat = @"mm\:ss";
     }
 }
index a2703c7b51e0b8d09ca40fb5c0919ac23b253e6b..2d51a5666a49a9a92d27542e07c5616f97981bb4 100755 (executable)
@@ -24,4 +24,31 @@ namespace MusicPlayer.Common
         On,
         Off,
     }
+
+    public enum EventType
+    {
+        Error,
+        PlaybackCompleted,
+    }
+
+    public class PlayerEventArgs : EventArgs
+    {
+        private readonly EventType type;
+        private readonly string description;
+
+        internal PlayerEventArgs(EventType eventType, string desc)
+        {
+            type = eventType;
+            description = desc;
+        }
+
+        public EventType Type
+        {
+            get => type;
+        }
+        public string Description
+        {
+            get => description;
+        }
+    }
 }
index 1d37e937349ad4b78d44dfdc1cd1615c52b3c9e3..383f42e1a62bae1063d50f9bf8be24593353326c 100755 (executable)
@@ -1,70 +1,85 @@
 using MusicPlayer.Common;
+using System;
 
 namespace MusicPlayer.Models
 {
     class PlayerModel : PropertyNotifier
     {
-        private Track currentTrack;
-        private string trackName;
-        private string trackArtist;
-        private int trackLength;
-        private int trackPlayingTime; //TODO need to use with mmplayer
-        private string thumbnailPath;
-        private PlayingStatus playingStatus;
-
         public PlayerModel()
         {
         }
-        public PlayerModel(Track track)
-        {
-            CurrentTrack = track;
-        }
+
+        private Track currentTrack;
 
         public Track CurrentTrack
         {
+            get => currentTrack;
             set
             {
                 currentTrack = value;
                 TrackName = currentTrack.TrackTitle;
                 TrackArtist = currentTrack.ArtistName;
-                TrackLength = currentTrack.Duration;
+                TrackLength = TimeSpan.FromMilliseconds(currentTrack.Duration).ToString(AppConstants.TimeFormat);
+                PlayingTime = TimeSpan.FromMilliseconds(0).ToString(AppConstants.TimeFormat);
                 ThumbnailPath = currentTrack.ThumbnailPath;
                 PlayingStatus = PlayingStatus.None;
             }
-            get
-            {
-                return currentTrack;
-            }
         }
 
+        private string trackName;
+
         public string TrackName
         {
             get => trackName;
             set => SetProperty(ref trackName, value);
         }
 
+        private string trackArtist;
+
         public string TrackArtist
         {
             get => trackArtist;
             set => SetProperty(ref trackArtist, value);
         }
 
-        public int TrackLength
+        private string trackLength;
+
+        public string TrackLength
         {
             get => trackLength;
             set => SetProperty(ref trackLength, value);
         }
 
+        private string thumbnailPath;
+
         public string ThumbnailPath
         {
             get => thumbnailPath;
             set => SetProperty(ref thumbnailPath, value);
         }
 
+        private PlayingStatus playingStatus;
+
         public PlayingStatus PlayingStatus
         {
             get => playingStatus;
             set { playingStatus = value; }
         }
+
+        private string playingTime;
+
+        public string PlayingTime
+        {
+            get => playingTime;
+            set => SetProperty(ref playingTime, value);
+        }
+
+        private float elapsedTime;
+
+        public float ElapsedTime
+        {
+            get => elapsedTime;
+            set => SetProperty(ref elapsedTime, value);
+        }
     }
 }
index 5c2b290296b35c3d95ef748569f6857581d3ae29..170258485d445998d416dc4dc4a45f8b5a34e975 100755 (executable)
@@ -3,38 +3,124 @@ using System.Collections.Generic;
 using System.Text;
 using MusicPlayer.Models;
 using MusicPlayer.Common;
+using MusicPlayer.Core;
+using Tizen.NUI;
+using Tizen.Multimedia;
 
 namespace MusicPlayer.ViewModels
 {
     class PlayerViewModel : PropertyNotifier
     {
+        private const int PlaybackTimerDuration = 1000;
+
         internal PlayerModel playerModel;
-        internal PlayingListViewModel playingListViewModel;
         internal LyricsViewModel lyricsViewModel;
-        private string playPauseUrl;
+        private Timer playbackTimer;
+        private bool isVolumeChanging;
 
         public PlayerViewModel()
         {
             lyricsViewModel = new LyricsViewModel();
             playingListViewModel = new PlayingListViewModel();
             playerModel = new PlayerModel();
+            playerModel.ElapsedTime = 0.0f;
             PlayPauseUrl = Resources.GetImagePath() + "play.png";
+            PlayerController.Instance.PlayerEventOccurred += OnPlayerEventOccurred;
+            playbackTimer = new Timer(PlaybackTimerDuration);
+            playbackTimer.Tick += OnPlaybackTimerTick;
+            isVolumeChanging = false;
+            VolumeLevel = AudioManager.VolumeController.Level[AudioVolumeType.Media];
+            AudioManager.VolumeController.Changed += OnVolumeLevelChanged;
+            HasPreviousTrack = playingListViewModel.HasPrev();
+            HasNextTrack = playingListViewModel.HasNext();
         }
 
+        internal PlayingListViewModel playingListViewModel;
         public PlayingListViewModel CurrentPlayingListViewModel
         {
             get => playingListViewModel;
         }
 
+        private string playPauseUrl;
+        public string PlayPauseUrl
+        {
+            get => playPauseUrl;
+            set => SetProperty(ref playPauseUrl, value);
+        }
+
+        private float volumeLevel;
+
+        public float VolumeLevel
+        {
+            get => volumeLevel;
+            set => SetProperty(ref volumeLevel, value);
+        }
+
+        private bool hasPreviousTrack;
+
+        public bool HasPreviousTrack
+        {
+            get => hasPreviousTrack;
+            set => SetProperty(ref hasPreviousTrack, value);
+        }
+
+        private bool hasNextTrack;
+
+        public bool HasNextTrack
+        {
+            get => hasNextTrack;
+            set => SetProperty(ref hasNextTrack, value);
+        }
+
+        public void SetPlayingList(TrackListViewModel trackListVM)
+        {
+            playingListViewModel.SetTrackListViewModel(trackListVM);
+        }
+
         public void SetCurrentTrack(Track track)
         {
+            Tizen.Log.Info(AppConstants.LogTag, "Setting Current track");
             playerModel.CurrentTrack = track;
             lyricsViewModel.CurrentTrack = track;
+            //TO DO need to set index properly
+            Track current = playingListViewModel.Current();
+            if (current == null)
+            {
+                Tizen.Log.Error(AppConstants.LogTag, "Current track is null so setting new track");
+                playingListViewModel.SetPlayingTrack(track);
+            }
+            // updating prev/next button state
+            HasPreviousTrack = playingListViewModel.HasPrev();
+            HasNextTrack = playingListViewModel.HasNext();
+
+            PlayerController.Instance.Uri = track.FilePath;
+            StartPlayback();
         }
 
-        public void SetPlayingList(TrackListViewModel trackListVM)
+        public void NextButtonClicked()
         {
-            playingListViewModel.SetTrackListViewModel(trackListVM);
+            Track nextTrack = playingListViewModel.Next();
+            if (nextTrack == null)
+            {
+                Tizen.Log.Error(AppConstants.LogTag, "nextTrack is null");
+                StopPlayback();
+                return;
+            }
+            Tizen.Log.Debug(AppConstants.LogTag, "Next track is: " + nextTrack.TrackTitle);
+            SetCurrentTrack(nextTrack);
+        }
+
+        public void PrevButtonClicked()
+        {
+            Track previousTrack = playingListViewModel.Prev();
+            if (previousTrack == null)
+            {
+                Tizen.Log.Error(AppConstants.LogTag, "previousTrack is null");
+                StopPlayback();
+                return;
+            }
+            Tizen.Log.Debug(AppConstants.LogTag, "Prev track is: " + previousTrack.TrackTitle);
+            SetCurrentTrack(previousTrack);
         }
 
         public void ShuffleChanged()
@@ -53,9 +139,10 @@ namespace MusicPlayer.ViewModels
                     break;
                 i++;
             }
-            RepeatMode new_mode = RepeatMode.Off;
-            RepeatMode [] repeatArr = (RepeatMode [])values;
-            if(i+1 >= values.Length)
+
+            RepeatMode[] repeatArr = (RepeatMode[])values;
+            RepeatMode new_mode;
+            if (i + 1 >= values.Length)
             {
                 new_mode = repeatArr[0];
             }
@@ -66,23 +153,132 @@ namespace MusicPlayer.ViewModels
             playingListViewModel.RepeatMode = new_mode;
         }
 
-        public string PlayPauseUrl
-        {
-            get => playPauseUrl;
-            set => SetProperty(ref playPauseUrl, value);
-        }
-
         public void PlayingStatusChanged()
         {
-            if(playerModel.PlayingStatus == PlayingStatus.Playing)
+            if (playerModel.PlayingStatus == PlayingStatus.Playing)
             {
                 playerModel.PlayingStatus = PlayingStatus.Paused;
                 PlayPauseUrl = Resources.GetImagePath() + "play.png";
+                Pause();
+                playbackTimer.Stop();
             }
             else
             {
                 playerModel.PlayingStatus = PlayingStatus.Playing;
                 PlayPauseUrl = Resources.GetImagePath() + "pause.png";
+                Resume();
+                playbackTimer.Start();
+            }
+        }
+
+        public void UpdatePlayerPosition(float value)
+        {
+            int currentPosition = (int)(playerModel.CurrentTrack.Duration * value);
+            PlayerController.Instance.SetPosition(currentPosition);
+            playerModel.PlayingTime = TimeSpan.FromMilliseconds(currentPosition).ToString(AppConstants.TimeFormat);
+            playbackTimer.Start();
+        }
+
+        public void StopPlaybackTimer()
+        {
+            playbackTimer.Stop();
+        }
+
+        public void SetElapsedTime(float value)
+        {
+            int currentPosition = (int)(playerModel.CurrentTrack.Duration * value);
+            playerModel.PlayingTime = TimeSpan.FromMilliseconds(currentPosition).ToString(AppConstants.TimeFormat);
+        }
+
+        public void VolumeChangeStarted()
+        {
+            isVolumeChanging = true;
+        }
+
+        public void VolumeChangeFinished(int value)
+        {
+            VolumeLevelChanged(value);
+            isVolumeChanging = false;
+        }
+        public void VolumeLevelChanged(int value)
+        {
+            AudioManager.VolumeController.Level[AudioVolumeType.Media] = value;
+        }
+
+        private bool OnPlaybackTimerTick(object source, Timer.TickEventArgs e)
+        {
+            UpdatePlayingTime();
+            return true;
+        }
+
+        private void OnPlayerEventOccurred(object sender, PlayerEventArgs e)
+        {
+            Tizen.Log.Error(AppConstants.LogTag, "Player Event Occurred:");
+            Tizen.Log.Error(AppConstants.LogTag, "\t"+e.Type.ToString());
+            Tizen.Log.Error(AppConstants.LogTag, "\t:"+e.Description);
+            if(e.Type == EventType.PlaybackCompleted)
+            {
+                PlayNext();
+            }
+        }
+
+        private void PlayNext()
+        {
+            if(playingListViewModel.RepeatMode == RepeatMode.Off)
+            {
+                Tizen.Log.Debug(AppConstants.LogTag, "Repeat is off, can't play next");
+                StopPlayback();
+                UpdatePlayingTime();
+                return;
+            }
+            NextButtonClicked();
+        }
+
+        private void UpdatePlayingTime()
+        {
+            int position = PlayerController.Instance.GetPosition();
+            playerModel.ElapsedTime = position / (float)playerModel.CurrentTrack.Duration;
+            playerModel.PlayingTime = TimeSpan.FromMilliseconds(position).ToString(AppConstants.TimeFormat);
+        }
+
+        private void StartPlayback()
+        {
+            playerModel.PlayingStatus = PlayingStatus.Playing;
+            PlayPauseUrl = Resources.GetImagePath() + "pause.png";
+            Play();
+            playbackTimer.Start();
+        }
+
+        private void StopPlayback()
+        {
+            playerModel.PlayingStatus = PlayingStatus.Stopped;
+            PlayPauseUrl = Resources.GetImagePath() + "play.png";
+            Stop();
+            playbackTimer.Stop();
+        }
+
+        private void  Play()
+        {
+            PlayerController.Instance.Play();
+        }
+        private void Pause()
+        {
+            PlayerController.Instance.Pause();
+        }
+        private void Resume()
+        {
+            PlayerController.Instance.Resume();
+        }
+        private void Stop()
+        {
+            PlayerController.Instance.Stop();
+        }
+
+        private void OnVolumeLevelChanged(object sender, VolumeChangedEventArgs e)
+        {
+            if(e.Type == AudioVolumeType.Media && isVolumeChanging == false)
+            {
+                VolumeLevel = e.Level;
             }
         }
     }
index d975dd627c6168fbf8d618804490b0caaae3a487..1aeb833e9432163fea0e1103cfe3a4e9b1401abb 100755 (executable)
@@ -7,6 +7,7 @@ using Tizen.NUI.Components;
 using MusicPlayer.Common;
 using Tizen.NUI.Binding;
 using MusicPlayer.ViewModels;
+using Tizen.Multimedia;
 
 namespace MusicPlayer.Views
 {
@@ -20,6 +21,7 @@ namespace MusicPlayer.Views
         private const int ControlViewMargin = 315;
         private const int TitleLabelHeight = 48;
         private const int ArtistLabelHeight = 36;
+        private const int TopBarButtonsY = (TopBarSize / 2 - IconSize / 2);
 
         private View leftView;
         private View rightView;
@@ -71,7 +73,23 @@ namespace MusicPlayer.Views
             AddLyricsView();
         }
 
-        private Button CreatButton(string url, int x, int y)
+        private Button CreateButton(ImageViewStyle style, int x, int y)
+        {
+            ButtonStyle buttonStyle = new ButtonStyle()
+            {
+                Icon = style,
+                IsSelectable = false,
+                IsEnabled = true,
+            };
+            Button button = new Button(buttonStyle)
+            {
+                Size2D = new Size2D(IconSize, IconSize),
+                Position2D = new Position2D(x, y),
+            };
+            return button;
+        }
+
+        private Button CreateButton(string url, int x, int y)
         {
             ButtonStyle buttonStyle = new ButtonStyle()
             {
@@ -119,10 +137,10 @@ namespace MusicPlayer.Views
 
         private void AddTopButtons()
         {
-            backButton = CreatButton(Resources.GetImagePath() + "back_button.png", LayoutPadding, (TopBarSize / 2 - IconSize / 2));
+            backButton = CreateButton(Resources.GetImagePath() + "back_button.png", LayoutPadding, TopBarButtonsY);
             leftView.Add(backButton);
 
-            moreButton = CreatButton(Resources.GetImagePath() + "more_button.png", Window.Instance.WindowSize.Width / 2 - LayoutPadding - IconSize, (TopBarSize / 2 - IconSize / 2));
+            moreButton = CreateButton(Resources.GetImagePath() + "more_button.png", Window.Instance.WindowSize.Width / 2 - LayoutPadding - IconSize, TopBarButtonsY);
             rightView.Add(moreButton);
         }
 
@@ -137,7 +155,7 @@ namespace MusicPlayer.Views
             rightView.Add(controlsView);
         }
 
-        private void AddTextControlElements()
+        private void AddTitleLabel()
         {
             titleLabel = new TextLabel()
             {
@@ -152,7 +170,10 @@ namespace MusicPlayer.Views
             };
             titleLabel.SetBinding(TextLabel.TextProperty, "TrackName");
             controlsView.Add(titleLabel);
+        }
 
+        private void AddArtistLabel()
+        {
             artistLabel = new TextLabel()
             {
                 Size2D = new Size2D(ControlViewWidth, ArtistLabelHeight),
@@ -168,43 +189,104 @@ namespace MusicPlayer.Views
             controlsView.Add(artistLabel);
         }
 
-        private void AddButtonControlElements()
+        private void AddTextControlElements()
         {
-            shuffleButton = CreatButton(Resources.GetImagePath() + "shuffle.png", 0, 196);
+            AddTitleLabel();
+            AddArtistLabel();
+        }
+
+        private void AddShuffleButton()
+        {
+            shuffleButton = CreateButton(Resources.GetImagePath() + "shuffle.png", 0, 196);
             shuffleButton.Icon.BindingContext = viewModel.playingListViewModel;
             shuffleButton.Icon.SetBinding(ImageView.ResourceUrlProperty, "ShuffleUrl");
+            // TODO need to implement command instead
             shuffleButton.Clicked += (object sender, ClickedEventArgs e) =>
             {
                 viewModel.ShuffleChanged();
             };
             controlsView.Add(shuffleButton);
+        }
 
-            prevButton = CreatButton(Resources.GetImagePath() + "prev.png", 168, 196);
+        private void AddPreviousButton()
+        {
+            ImageViewStyle prevIconStyle = new ImageViewStyle()
+            {
+                ResourceUrl = new Selector<string>
+                {
+                    Normal = Resources.GetImagePath() + "prev.png",
+                    Disabled = Resources.GetImagePath() + "prev_disabled.png"
+                },
+            };
+            prevButton = CreateButton(prevIconStyle, 168, 196);
+            // TODO need to implement command instead
+            prevButton.Clicked += (object sender, ClickedEventArgs e) =>
+            {
+                viewModel.PrevButtonClicked();
+            };
+            prevButton.BindingContext = viewModel;
+            prevButton.SetBinding(Button.IsEnabledProperty, "HasPreviousTrack");
             controlsView.Add(prevButton);
+        }
 
-            playButton = CreatButton(Resources.GetImagePath() + "play.png", 296, 196);
+        private void AddPlayButton()
+        {
+            playButton = CreateButton(Resources.GetImagePath() + "play.png", 296, 196);
             playButton.Icon.BindingContext = viewModel;
             playButton.Icon.SetBinding(ImageView.ResourceUrlProperty, "PlayPauseUrl");
             controlsView.Add(playButton);
+            // TODO need to implement command instead
             playButton.Clicked += (object sender, ClickedEventArgs e) =>
             {
                 viewModel.PlayingStatusChanged();
             };
+        }
+
+        private void AddNextButton()
+        {
+            ImageViewStyle nextIconStyle = new ImageViewStyle()
+            {
+                ResourceUrl = new Selector<string>
+                {
+                    Normal = Resources.GetImagePath() + "next.png",
+                    Disabled = Resources.GetImagePath() + "next_disabled.png",
+                },
+            };
 
-            nextButton = CreatButton(Resources.GetImagePath() + "next.png", 424, 196);
+            nextButton = CreateButton(nextIconStyle, 424, 196);
+            // TODO need to implement command instead
+            nextButton.Clicked += (object sender, ClickedEventArgs e) =>
+            {
+                viewModel.NextButtonClicked();
+            };
+            nextButton.BindingContext = viewModel;
+            nextButton.SetBinding(Button.IsEnabledProperty, "HasNextTrack");
             controlsView.Add(nextButton);
+        }
 
-            repeatButton = CreatButton(Resources.GetImagePath() + "repeat.png", 592, 196);
+        private void AddRepeatButton()
+        {
+            repeatButton = CreateButton(Resources.GetImagePath() + "repeat.png", 592, 196);
             repeatButton.Icon.BindingContext = viewModel.playingListViewModel;
             repeatButton.Icon.SetBinding(ImageView.ResourceUrlProperty, "RepeatUrl");
             controlsView.Add(repeatButton);
+            // TODO need to implement command instead
             repeatButton.Clicked += (object sender, ClickedEventArgs e) =>
             {
                 viewModel.RepeatChanged();
             };
         }
 
-        private void AddVolumeSliderElements()
+        private void AddButtonControlElements()
+        {
+            AddShuffleButton();
+            AddPreviousButton();
+            AddPlayButton();
+            AddNextButton();
+            AddRepeatButton();
+        }
+
+        private void AddLeftVolumeIcon()
         {
             leftVolumeIcon = new ImageView(Resources.GetImagePath() + "left_sound_icon.png")
             {
@@ -212,14 +294,20 @@ namespace MusicPlayer.Views
                 Position2D = new Position2D(0, 336),
             };
             controlsView.Add(leftVolumeIcon);
+        }
 
+        private void AddRightVolumeIcon()
+        {
             rightVolumeIcon = new ImageView(Resources.GetImagePath() + "right_sound_icon.png")
             {
                 Size2D = new Size2D(IconSize, IconSize),
                 Position2D = new Position2D(592, 336),
             };
             controlsView.Add(rightVolumeIcon);
+        }
 
+        private SliderStyle CreateVolumeSliderStyle()
+        {
             SliderStyle volumeSliderStyle = new SliderStyle()
             {
                 IndicatorType = Slider.IndicatorType.Image,
@@ -239,8 +327,28 @@ namespace MusicPlayer.Views
                     },
                 },
             };
+            return volumeSliderStyle;
+        }
 
-            volumeSlider = new Slider(volumeSliderStyle);
+        private void AddVolumeSliderEventHandlers()
+        {
+            volumeSlider.SlidingStarted += (object sender, SliderSlidingStartedEventArgs e) =>
+            {
+                viewModel.VolumeChangeStarted();
+            };
+            volumeSlider.ValueChanged += (object sender, SliderValueChangedEventArgs e) =>
+            {
+                viewModel.VolumeLevelChanged((int)e.CurrentValue);
+            };
+            volumeSlider.SlidingFinished += (object sender, SliderSlidingFinishedEventArgs e) =>
+            {
+                viewModel.VolumeChangeFinished((int)e.CurrentValue);
+            };
+        }
+
+        private void AddVolumeSlider()
+        {
+            volumeSlider = new Slider(CreateVolumeSliderStyle());
             volumeSlider.Indicator = Slider.IndicatorType.Text;
             volumeSlider.TrackThickness = 4;
             volumeSlider.ThumbImageURLSelector = new StringSelector
@@ -250,12 +358,22 @@ namespace MusicPlayer.Views
             };
             volumeSlider.Size2D = new Size2D(496, 48);
             volumeSlider.Position2D = new Position2D(72, 336);
-            volumeSlider.ThumbSize = new Size(36, 36);
+            volumeSlider.ThumbSize = new Tizen.NUI.Size(36, 36);
             volumeSlider.Direction = Slider.DirectionType.Horizontal;
             volumeSlider.MinValue = 0;
-            volumeSlider.MaxValue = 100;
-            volumeSlider.CurrentValue = 10;
+            volumeSlider.MaxValue = AudioManager.VolumeController.MaxLevel[AudioVolumeType.Media];
+            volumeSlider.CurrentValue = AudioManager.VolumeController.Level[AudioVolumeType.Media];
             controlsView.Add(volumeSlider);
+            volumeSlider.BindingContext = viewModel;
+            volumeSlider.SetBinding(Slider.CurrentValueProperty, "VolumeLevel");
+            AddVolumeSliderEventHandlers();
+        }
+
+        private void AddVolumeSliderElements()
+        {
+            AddLeftVolumeIcon();
+            AddRightVolumeIcon();
+            AddVolumeSlider();
         }
 
         private void AddControlElements()
@@ -265,14 +383,8 @@ namespace MusicPlayer.Views
             AddVolumeSliderElements();
         }
 
-        private void AddPlaybackSlider()
+        private SliderStyle CreatePlaybackSliderStyle()
         {
-            View sliderView = new View()
-            {
-                Size2D = new Size2D(1792, 80),
-                Position2D = new Position2D(64, 950),
-                BackgroundColor = Color.Transparent,
-            };
             SliderStyle playbackSliderStyle = new SliderStyle()
             {
                 IndicatorType = Slider.IndicatorType.Image,
@@ -292,7 +404,28 @@ namespace MusicPlayer.Views
                     },
                 },
             };
-            playbackSlider = new Slider(playbackSliderStyle)
+            return playbackSliderStyle;
+        }
+
+        private void AddPlaybackSliderEventHandler()
+        {
+            playbackSlider.SlidingStarted += (object sender, SliderSlidingStartedEventArgs e) =>
+            {
+                viewModel.StopPlaybackTimer();
+            };
+            playbackSlider.ValueChanged += (object sender, SliderValueChangedEventArgs e) =>
+            {
+                viewModel.SetElapsedTime(e.CurrentValue);
+            };
+            playbackSlider.SlidingFinished += (object sender, SliderSlidingFinishedEventArgs e) =>
+            {
+                viewModel.UpdatePlayerPosition(e.CurrentValue);
+            };
+        }
+
+        private void AddPlaybackSlider(View sliderView)
+        {
+            playbackSlider = new Slider(CreatePlaybackSliderStyle())
             {
                 ThumbImageURLSelector = new StringSelector
                 {
@@ -303,10 +436,17 @@ namespace MusicPlayer.Views
                 MaxValue = 1.0f,
                 WidthResizePolicy = ResizePolicyType.FillToParent,
                 SizeHeight = 44,
-                ThumbSize = new Size(36, 36),
+                ThumbSize = new Tizen.NUI.Size(36, 36),
                 Direction = Slider.DirectionType.Horizontal,
+                IsCreateByXaml = true,
             };
+            playbackSlider.SetBinding(Slider.CurrentValueProperty, "ElapsedTime");
             sliderView.Add(playbackSlider);
+            AddPlaybackSliderEventHandler();
+        }
+
+        private void AddCurrentTimeLabel(View sliderView)
+        {
             currentTime = new TextLabel()
             {
                 Size2D = new Size2D(400, 32),
@@ -317,19 +457,39 @@ namespace MusicPlayer.Views
                 Text = "00::00:00",
                 HorizontalAlignment = HorizontalAlignment.Begin,
             };
+            currentTime.SetBinding(TextLabel.TextProperty, "PlayingTime");
             sliderView.Add(currentTime);
+        }
+
+        private void AddTotalTimeLabel(View sliderView)
+        {
             totalTime = new TextLabel()
             {
                 Size2D = new Size2D(400, 32),
-                Position2D = new Position2D(1792-400, 48),
+                Position2D = new Position2D(1792 - 400, 48),
                 TextColor = UIColors.HEX001447,
                 PixelSize = 24,
                 FontFamily = "BreezeSans",
                 HorizontalAlignment = HorizontalAlignment.End,
                 Text = "59:59:59",
             };
+            totalTime.SetBinding(TextLabel.TextProperty, "TrackLength");
             sliderView.Add(totalTime);
-            this.Add(sliderView);
+        }
+
+        private void AddPlaybackSlider()
+        {
+            View sliderView = new View()
+            {
+                Size2D = new Size2D(1792, 80),
+                Position2D = new Position2D(64, 950),
+                BackgroundColor = Color.Transparent,
+            };
+            Add(sliderView);
+
+            AddPlaybackSlider(sliderView);
+            AddCurrentTimeLabel(sliderView);
+            AddTotalTimeLabel(sliderView);
         }
 
         private void AddListActionButtons()
@@ -342,13 +502,13 @@ namespace MusicPlayer.Views
             };
             rightView.Add(actionButtonView);
 
-            listButton = CreatButton(Resources.GetImagePath() + "playing_queue.png", 0, 0);
+            listButton = CreateButton(Resources.GetImagePath() + "playing_queue.png", 0, 0);
             actionButtonView.Add(listButton);
 
-            playlistButton = CreatButton(Resources.GetImagePath() + "addtoplaylist.png", 88, 0);
+            playlistButton = CreateButton(Resources.GetImagePath() + "addtoplaylist.png", 88, 0);
             actionButtonView.Add(playlistButton);
 
-            favouriteButton = CreatButton(Resources.GetImagePath() + "favourite_off.png", 176, 0);
+            favouriteButton = CreateButton(Resources.GetImagePath() + "favourite_off.png", 176, 0);
             actionButtonView.Add(favouriteButton);
         }