From d0e482dd6aabc55b9fa77b161e28302de7b601ac Mon Sep 17 00:00:00 2001 From: "Geunsun, Lee" Date: Wed, 7 Jun 2017 19:26:16 +0900 Subject: [PATCH] Implement the music player for the music tab Change-Id: I89095aac77e014ae8ba0ad5a73c237468b7f18d3 --- .../TVMediaHub.Tizen/Models/ContentProvider.cs | 2 + TVMediaHub/TVMediaHub.Tizen/Models/MediaHubImpl.cs | 4 + .../TVMediaHub.Tizen/Models/MusicPlayerModel.cs | 260 +++++++++++++++++++++ .../TVMediaHub.Tizen/Models/MusicProvider.cs | 1 - .../TVMediaHub.Tizen/TVMediaHub.Tizen.csproj | 12 + .../TVMediaHub.Tizen/Utils/EasingFunction.cs | 21 ++ .../ViewModels/ImageTabViewModel.cs | 5 +- .../ViewModels/MusicPlayerViewModel.cs | 105 +++++++++ .../ViewModels/MusicPlayerViewModelLocator.cs | 40 ++++ .../ViewModels/MusicTabViewModel.cs | 26 ++- .../ViewModels/MusicTabViewModelLocator.cs | 1 + .../ViewModels/VideoTabViewModelLocator.cs | 1 + .../TVMediaHub.Tizen/Views/ImageItem.xaml.cs | 1 + .../TVMediaHub.Tizen/Views/ImageViewer.xaml.cs | 3 +- .../TVMediaHub.Tizen/Views/MusicGroup.xaml.cs | 4 +- TVMediaHub/TVMediaHub.Tizen/Views/MusicItem.xaml | 20 +- .../TVMediaHub.Tizen/Views/MusicItem.xaml.cs | 8 +- TVMediaHub/TVMediaHub.Tizen/Views/MusicPlayer.xaml | 18 ++ .../TVMediaHub.Tizen/Views/MusicPlayer.xaml.cs | 37 +++ TVMediaHub/TVMediaHub.Tizen/Views/MusicTab.xaml | 8 +- TVMediaHub/TVMediaHub.Tizen/Views/MusicTab.xaml.cs | 1 + 21 files changed, 558 insertions(+), 20 deletions(-) create mode 100644 TVMediaHub/TVMediaHub.Tizen/Models/MusicPlayerModel.cs create mode 100644 TVMediaHub/TVMediaHub.Tizen/ViewModels/MusicPlayerViewModel.cs create mode 100644 TVMediaHub/TVMediaHub.Tizen/ViewModels/MusicPlayerViewModelLocator.cs create mode 100644 TVMediaHub/TVMediaHub.Tizen/Views/MusicPlayer.xaml create mode 100644 TVMediaHub/TVMediaHub.Tizen/Views/MusicPlayer.xaml.cs diff --git a/TVMediaHub/TVMediaHub.Tizen/Models/ContentProvider.cs b/TVMediaHub/TVMediaHub.Tizen/Models/ContentProvider.cs index 3d21b0b..3ffb646 100755 --- a/TVMediaHub/TVMediaHub.Tizen/Models/ContentProvider.cs +++ b/TVMediaHub/TVMediaHub.Tizen/Models/ContentProvider.cs @@ -162,6 +162,7 @@ namespace TVMediaHub.Tizen.Models newGroupFlag = true; newTitle = mediaInformationEx.MediaContentInformation.MediaType.ToString(); } + break; case SortOption.Album: if (lastGroupItem == null || lastGroupItem.Title != (mediaInformationEx.MediaContentInformation as AudioInformation).Album) @@ -169,6 +170,7 @@ namespace TVMediaHub.Tizen.Models newGroupFlag = true; newTitle = (mediaInformationEx.MediaContentInformation as AudioInformation).Album.ToString(); } + break; case SortOption.Artist: if (lastGroupItem == null || lastGroupItem.Title != (mediaInformationEx.MediaContentInformation as AudioInformation).Artist) diff --git a/TVMediaHub/TVMediaHub.Tizen/Models/MediaHubImpl.cs b/TVMediaHub/TVMediaHub.Tizen/Models/MediaHubImpl.cs index 4e89dcc..4d4a51d 100755 --- a/TVMediaHub/TVMediaHub.Tizen/Models/MediaHubImpl.cs +++ b/TVMediaHub/TVMediaHub.Tizen/Models/MediaHubImpl.cs @@ -26,6 +26,7 @@ namespace TVMediaHub.Tizen.Models /// An instance of the MediaHubImpl /// private static readonly MediaHubImpl instance = new MediaHubImpl(); + /// /// Gets an instance of the MediaHubImpl /// @@ -56,6 +57,7 @@ namespace TVMediaHub.Tizen.Models /// An instance of the MusicProvider /// private static readonly MusicProvider musicProviderInstance = new MusicProvider(); + /// /// Gets an instance of the MusicProvider /// @@ -71,6 +73,7 @@ namespace TVMediaHub.Tizen.Models /// An instance of the MusicProvider /// private static readonly VideoProvider videoProviderInstance = new VideoProvider(); + /// /// Gets an instance of the MusicProvider /// @@ -86,6 +89,7 @@ namespace TVMediaHub.Tizen.Models /// An instance of the StorageProvider /// private static readonly StorageProvider storageProviderInstance = new StorageProvider(); + /// /// Gets an instance of the StorageProvider /// diff --git a/TVMediaHub/TVMediaHub.Tizen/Models/MusicPlayerModel.cs b/TVMediaHub/TVMediaHub.Tizen/Models/MusicPlayerModel.cs new file mode 100644 index 0000000..74c1294 --- /dev/null +++ b/TVMediaHub/TVMediaHub.Tizen/Models/MusicPlayerModel.cs @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.1 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Threading; +using System.Threading.Tasks; +using Tizen.Content.MediaContent; +using Tizen.Multimedia; +using TVMediaHub.Tizen.DataModels; +using TVMediaHub.Tizen.Utils; + +namespace TVMediaHub.Tizen.Models +{ + /// + /// A custom EventArgs with string fields + /// + public class MusicPlayerInfoEventArgs : EventArgs + { + public string Title; + public string Artist; + public string AlbumCover; + } + + /// + /// A custom EventArgs with double field + /// + public class MusicPlayerProgressEventArgs : EventArgs + { + public double Progress; + } + + /// + /// An instance of the MusicPlayerModel + /// + public class MusicPlayerModel + { + /// + /// A main instance class of the music player model instance + /// + private static readonly MusicPlayerModel instance = new MusicPlayerModel(); + + /// + /// An instance of the player + /// + private Player playerInstance; + + /// + /// An timer for the progressbar + /// + private Timer progressbarTimer; + + /// + /// The period of the timer + /// + private int timerPeriod = 1000; + + /// + /// An event handler for handling the current music information + /// + private EventHandler MusicPlayerInfoListener; + + /// + /// An event handler for handling the percentage of the progressbar + /// + private EventHandler MusicPlayerProgressListener; + + /// + /// The information of the current music + /// + public MediaInformationEx currentMusic; + + /// + /// Gets or sets the current music + /// + public MediaInformationEx CurrentMusic + { + get + { + return currentMusic; + } + + set + { + if (currentMusic != value) + { + currentMusic = value; + + /// 1. Stop the player + if (playerInstance.State == PlayerState.Playing) + { + StopPlayer(); + } + + /// 2. Play the current music + StartPlayerAsync((currentMusic.MediaContentInformation as AudioInformation).FilePath); + + /// 3. Update the information of the current music + MusicPlayerInfoListener?.Invoke(this, new MusicPlayerInfoEventArgs() + { + Title = (currentMusic.MediaContentInformation as AudioInformation).Title, + Artist = (currentMusic.MediaContentInformation as AudioInformation).Artist, + AlbumCover = ((currentMusic.MediaContentInformation as AudioInformation).ThumbnailPath.Length != 0) ? (currentMusic.MediaContentInformation as AudioInformation).ThumbnailPath : "img_media_no_contents.png", + }); + + /// 4. Update the progressbar of the current music + MusicPlayerProgressListener?.Invoke(this, new MusicPlayerProgressEventArgs() + { + Progress = (playerInstance.State == PlayerState.Idle || playerInstance.State == PlayerState.Preparing) ? 0 : Convert.ToDouble(playerInstance.GetPlayPosition()) / (currentMusic.MediaContentInformation as AudioInformation).Duration, + }); + } + } + } + + /// + /// Gets an instance of the music player model + /// + public static MusicPlayerModel Instance + { + get + { + return instance; + } + } + + /// + /// A constructor + /// + public MusicPlayerModel() + { + InitializePlayer(); + InitializeProgressbarTimer(); + } + + /// + /// Initialize the player instance + /// Register event handler for the player + /// + private void InitializePlayer() + { + playerInstance = new Player(); + + playerInstance.PlaybackCompleted += ((s, e) => + { + StopPlayer(); + }); + + playerInstance.PlaybackInterrupted += ((s, e) => + { + DbgPort.E("Error : " + Enum.GetName(typeof(PlayerError), e.Reason)); + + StopPlayer(); + }); + + playerInstance.ErrorOccurred += ((s, e) => + { + DbgPort.E("Error : " + Enum.GetName(typeof(PlayerError), e.Error)); + + StopPlayer(); + }); + } + + /// + /// Initialize the timer for the progressbar + /// + private void InitializeProgressbarTimer() + { + progressbarTimer = new Timer((object o) => + { + MusicPlayerProgressListener?.Invoke(this, new MusicPlayerProgressEventArgs() + { + Progress = (playerInstance.State == PlayerState.Idle || playerInstance.State == PlayerState.Preparing) ? 0 : Convert.ToDouble(playerInstance.GetPlayPosition()) / (currentMusic.MediaContentInformation as AudioInformation).Duration, + }); + }, null, Timeout.Infinite, Timeout.Infinite); + } + + /// + /// Starts the timer for the progressbar + /// + private void StartProgressbarTimer() + { + progressbarTimer.Change(0, timerPeriod); + } + + /// + /// Stops the timer for the porgressbar + /// + private void StopProgressbarTimer() + { + progressbarTimer.Change(Timeout.Infinite, Timeout.Infinite); + } + + /// + /// Plays the current music + /// + /// The file path of the media source + public void StartPlayerAsync(string filePath) + { + MediaSource source = new MediaUriSource(filePath); + playerInstance.SetSource(source); + + Task.Run(async () => + { + await playerInstance.PrepareAsync(); + + playerInstance.Start(); + + StartProgressbarTimer(); + }); + } + + /// + /// Stops the current music + /// + public void StopPlayer() + { + StopProgressbarTimer(); + + try + { + playerInstance.Stop(); + playerInstance.Unprepare(); + } + catch (Exception e) + { + DbgPort.E("Error : " + e.Message); + } + } + + /// + /// A method adds EventHandler to SetCurrentMusicInfoListener + /// + /// The EventHandler for adding + public void SetCurrentMusicInfoListener(EventHandler listener) + { + MusicPlayerInfoListener += listener; + } + + /// + /// A method adds EventHandler to SetCurrentMusicProgressListener + /// + /// The EventHandler for adding + public void SetCurrentMusicProgressListener(EventHandler listener) + { + MusicPlayerProgressListener += listener; + } + } +} diff --git a/TVMediaHub/TVMediaHub.Tizen/Models/MusicProvider.cs b/TVMediaHub/TVMediaHub.Tizen/Models/MusicProvider.cs index 381a321..95a5540 100755 --- a/TVMediaHub/TVMediaHub.Tizen/Models/MusicProvider.cs +++ b/TVMediaHub/TVMediaHub.Tizen/Models/MusicProvider.cs @@ -15,7 +15,6 @@ */ using System; -using Tizen.Content.MediaContent; using TVMediaHub.Tizen.DataModels; namespace TVMediaHub.Tizen.Models diff --git a/TVMediaHub/TVMediaHub.Tizen/TVMediaHub.Tizen.csproj b/TVMediaHub/TVMediaHub.Tizen/TVMediaHub.Tizen.csproj index 6b66f2b..0666f86 100755 --- a/TVMediaHub/TVMediaHub.Tizen/TVMediaHub.Tizen.csproj +++ b/TVMediaHub/TVMediaHub.Tizen/TVMediaHub.Tizen.csproj @@ -65,6 +65,7 @@ + @@ -85,7 +86,9 @@ + + @@ -136,6 +139,9 @@ VideoItem.xaml + + MusicPlayer.xaml + VideoPlayer.xaml @@ -323,6 +329,12 @@ Designer + + + MSBuild:UpdateDesignTimeXaml + Designer + +