using MediaBrowser.UI.Controller;
using MediaBrowser.UI.Playback;
using MediaBrowser.UI.Playback.InternalPlayer;
using System;
using System.Threading;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
namespace MediaBrowser.UI.Controls
{
///
/// Interaction logic for NavigationBar.xaml
///
public partial class NavigationBar : BaseUserControl
{
///
/// Gets or sets the current player.
///
/// The current player.
private BaseMediaPlayer CurrentPlayer { get; set; }
///
/// Gets or sets the current position timer.
///
/// The current position timer.
private Timer CurrentPositionTimer { get; set; }
///
/// Initializes a new instance of the class.
///
public NavigationBar()
{
InitializeComponent();
Loaded += NavigationBar_Loaded;
}
///
/// Handles the Loaded event of the NavigationBar control.
///
/// The source of the event.
/// The instance containing the event data.
void NavigationBar_Loaded(object sender, RoutedEventArgs e)
{
BackButton.Click += BtnApplicationBackClick;
MuteButton.Click += MuteButton_Click;
VolumeDownButton.PreviewMouseDown += VolumeDownButton_Click;
VolumeUpButton.PreviewMouseDown += VolumeUpButton_Click;
StopButton.Click += StopButton_Click;
PlayButton.Click += PlayButton_Click;
PauseButton.Click += PauseButton_Click;
NextChapterButton.Click += NextChapterButton_Click;
PreviousChapterButton.Click += PreviousChapterButton_Click;
UIKernel.Instance.PlaybackManager.PlaybackStarted += PlaybackManager_PlaybackStarted;
UIKernel.Instance.PlaybackManager.PlaybackCompleted += PlaybackManager_PlaybackCompleted;
CurrentPositionSlider.PreviewMouseUp += CurrentPositionSlider_PreviewMouseUp;
}
///
/// Handles the Click event of the PreviousChapterButton control.
///
/// The source of the event.
/// The instance containing the event data.
async void PreviousChapterButton_Click(object sender, RoutedEventArgs e)
{
await CurrentPlayer.GoToPreviousChapter();
}
///
/// Handles the Click event of the NextChapterButton control.
///
/// The source of the event.
/// The instance containing the event data.
async void NextChapterButton_Click(object sender, RoutedEventArgs e)
{
await CurrentPlayer.GoToNextChapter();
}
///
/// Handles the Click event of the PauseButton control.
///
/// The source of the event.
/// The instance containing the event data.
async void PauseButton_Click(object sender, RoutedEventArgs e)
{
await CurrentPlayer.Pause();
}
///
/// Handles the Click event of the PlayButton control.
///
/// The source of the event.
/// The instance containing the event data.
async void PlayButton_Click(object sender, RoutedEventArgs e)
{
await CurrentPlayer.UnPause();
}
///
/// Handles the Click event of the StopButton control.
///
/// The source of the event.
/// The instance containing the event data.
async void StopButton_Click(object sender, RoutedEventArgs e)
{
await CurrentPlayer.Stop();
}
///
/// Handles the PlaybackCompleted event of the PlaybackManager control.
///
/// The source of the event.
/// The instance containing the event data.
void PlaybackManager_PlaybackCompleted(object sender, PlaybackStopEventArgs e)
{
if (e.Player == CurrentPlayer)
{
if (CurrentPositionTimer != null)
{
CurrentPositionTimer.Dispose();
}
CurrentPlayer.PlayStateChanged -= CurrentPlayer_PlayStateChanged;
CurrentPlayer = null;
ResetButtonVisibilities(null);
Dispatcher.InvokeAsync(() => TxtCurrentPosition.Text = string.Empty);
}
}
///
/// Handles the Click event of the VolumeUpButton control.
///
/// The source of the event.
/// The instance containing the event data.
void VolumeUpButton_Click(object sender, RoutedEventArgs e)
{
CurrentPlayer.Volume += 3;
}
///
/// Handles the Click event of the VolumeDownButton control.
///
/// The source of the event.
/// The instance containing the event data.
void VolumeDownButton_Click(object sender, RoutedEventArgs e)
{
CurrentPlayer.Volume -= 3;
}
///
/// Handles the Click event of the MuteButton control.
///
/// The source of the event.
/// The instance containing the event data.
void MuteButton_Click(object sender, RoutedEventArgs e)
{
if (CurrentPlayer.CanMute)
{
CurrentPlayer.Mute = !CurrentPlayer.Mute;
}
}
///
/// Handles the PlaybackStarted event of the PlaybackManager control.
///
/// The source of the event.
/// The instance containing the event data.
void PlaybackManager_PlaybackStarted(object sender, PlaybackEventArgs e)
{
if (e.Player is BaseInternalMediaPlayer)
{
CurrentPlayer = e.Player;
CurrentPlayer.PlayStateChanged += CurrentPlayer_PlayStateChanged;
ResetButtonVisibilities(e.Player);
Dispatcher.InvokeAsync(() =>
{
var runtime = e.Player.CurrentMedia.RunTimeTicks ?? 0;
CurrentPositionSlider.Maximum = runtime;
TxtDuration.Text = GetTimeString(runtime);
});
CurrentPositionTimer = new Timer(CurrentPositionTimerCallback, null, 250, 250);
}
}
///
/// Currents the position timer callback.
///
/// The state.
private void CurrentPositionTimerCallback(object state)
{
var time = string.Empty;
var ticks = CurrentPlayer.CurrentPositionTicks;
if (ticks.HasValue)
{
time = GetTimeString(ticks.Value);
}
Dispatcher.InvokeAsync(() =>
{
TxtCurrentPosition.Text = time;
if (!_isPositionSliderDragging)
{
CurrentPositionSlider.Value = ticks ?? 0;
}
});
}
///
/// Gets the time string.
///
/// The ticks.
/// System.String.
private string GetTimeString(long ticks)
{
var timespan = TimeSpan.FromTicks(ticks);
return timespan.TotalHours >= 1 ? timespan.ToString("hh':'mm':'ss") : timespan.ToString("mm':'ss");
}
///
/// Handles the PlayStateChanged event of the CurrentPlayer control.
///
/// The source of the event.
/// The instance containing the event data.
void CurrentPlayer_PlayStateChanged(object sender, EventArgs e)
{
ResetButtonVisibilities(CurrentPlayer);
}
///
/// Resets the button visibilities.
///
/// The player.
private void ResetButtonVisibilities(BaseMediaPlayer player)
{
Dispatcher.Invoke(() =>
{
PlayButton.Visibility = player != null && player.PlayState == PlayState.Paused ? Visibility.Visible : Visibility.Collapsed;
PauseButton.Visibility = player != null && player.CanPause && player.PlayState == PlayState.Playing ? Visibility.Visible : Visibility.Collapsed;
StopButton.Visibility = player != null ? Visibility.Visible : Visibility.Collapsed;
MuteButton.Visibility = player != null && player.CanMute ? Visibility.Visible : Visibility.Collapsed;
VolumeUpButton.Visibility = player != null && player.CanControlVolume ? Visibility.Visible : Visibility.Collapsed;
VolumeDownButton.Visibility = player != null && player.CanControlVolume ? Visibility.Visible : Visibility.Collapsed;
var isSeekabke = player != null && player.CanSeek && player.CurrentMedia != null;
SeekGrid.Visibility = isSeekabke ? Visibility.Visible : Visibility.Collapsed;
var canSeekChapters = isSeekabke && player.CurrentMedia.Chapters != null && player.CurrentMedia.Chapters.Count > 1;
NextChapterButton.Visibility = canSeekChapters ? Visibility.Visible : Visibility.Collapsed;
PreviousChapterButton.Visibility = canSeekChapters ? Visibility.Visible : Visibility.Collapsed;
});
}
///
/// BTNs the application back click.
///
/// The sender.
/// The instance containing the event data.
void BtnApplicationBackClick(object sender, RoutedEventArgs e)
{
App.Instance.ApplicationWindow.NavigateBack();
}
///
/// The is position slider dragging
///
private bool _isPositionSliderDragging;
///
/// Handles the DragStarted event of the CurrentPositionSlider control.
///
/// The source of the event.
/// The instance containing the event data.
private void CurrentPositionSlider_DragStarted(object sender, DragStartedEventArgs e)
{
_isPositionSliderDragging = true;
}
///
/// Handles the DragCompleted event of the CurrentPositionSlider control.
///
/// The source of the event.
/// The instance containing the event data.
private void CurrentPositionSlider_DragCompleted(object sender, DragCompletedEventArgs e)
{
_isPositionSliderDragging = false;
//await CurrentPlayer.Seek(Convert.ToInt64(CurrentPositionSlider.Value));
}
///
/// Handles the PreviewMouseUp event of the CurrentPositionSlider control.
///
/// The source of the event.
/// The instance containing the event data.
async void CurrentPositionSlider_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
await CurrentPlayer.Seek(Convert.ToInt64(CurrentPositionSlider.Value));
}
}
}