Skip to content
This repository has been archived by the owner on Jan 26, 2020. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
TizianoNoto committed Oct 10, 2018
2 parents 692fd22 + a6e8340 commit 33b030b
Show file tree
Hide file tree
Showing 8 changed files with 181 additions and 29 deletions.
8 changes: 4 additions & 4 deletions OnlyM.Core/Utils/GraphicsUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ public static bool AutoRotateIfRequired(string itemFilePath)
public static BitmapSource Downsize(string imageFilePath, int maxImageWidth, int maxImageHeight)
{
var image = GetBitmapImageWithCacheOnLoad(imageFilePath);
var factorWidth = maxImageWidth / image.Width;
var factorHeight = maxImageHeight / image.Height;

var factorWidth = (double)maxImageWidth / image.PixelWidth;
var factorHeight = (double)maxImageHeight / image.PixelHeight;

if (factorHeight >= 1 && factorWidth >= 1)
{
Expand Down Expand Up @@ -116,7 +116,7 @@ public static ImageSource ByteArrayToImage(byte[] imageData)
public static BitmapImage GetBitmapImageWithCacheOnLoad(string imageFile)
{
var bmp = new BitmapImage();

// BitmapCacheOption.OnLoad prevents the source image file remaining
// in use when the bitmap is used as an ImageSource.
bmp.BeginInit();
Expand Down
5 changes: 4 additions & 1 deletion OnlyM/MediaElementAdaption/IMediaElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System;
using System.Threading.Tasks;
using System.Windows;
using OnlyM.Core.Models;

internal interface IMediaElement
{
Expand All @@ -24,7 +25,7 @@ internal interface IMediaElement

Duration NaturalDuration { get; }

Task Play(Uri mediaPath);
Task Play(Uri mediaPath, MediaClassification mediaClassification);

Task Pause();

Expand All @@ -35,5 +36,7 @@ internal interface IMediaElement
FrameworkElement FrameworkElement { get; }

Guid MediaItemId { get; set; }

void UnsubscribeEvents();
}
}
146 changes: 134 additions & 12 deletions OnlyM/MediaElementAdaption/MediaElementMediaFoundation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,33 @@
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Threading;
using Core.Services.Options;
using OnlyM.Core.Models;

internal sealed class MediaElementMediaFoundation : IMediaElement
{
// note that _audioPlayer is used for audio-only playback (e.g. MP3 files);
// videos are rendered using _mediaElement. It should be possible to use MediaElement
// exclusively, but it must be part of the visual tree in order to work correctly
// and we want to be able to play audio without the need to create the MediaWindow.
private readonly Lazy<MediaPlayer> _audioPlayer;
private readonly MediaElement _mediaElement;
private readonly DispatcherTimer _timer;

private readonly IOptionsService _optionsService;
private MediaClassification _currentMediaClassification;

public MediaElementMediaFoundation(
MediaElement mediaElement,
IOptionsService optionsService)
{
_currentMediaClassification = MediaClassification.Unknown;

_optionsService = optionsService;

_audioPlayer = new Lazy<MediaPlayer>(MediaPlayerFactory);

_mediaElement = mediaElement;
_mediaElement.Volume = 1.0;

Expand Down Expand Up @@ -56,38 +70,100 @@ public event EventHandler<LogMessageEventArgs> MessageLogged

public TimeSpan Position
{
get => _mediaElement.Position;
set => _mediaElement.Position = value;
get
{
if (_currentMediaClassification == MediaClassification.Audio)
{
return _audioPlayer.Value.Position;
}

return _mediaElement.Position;
}
set
{
if (_currentMediaClassification == MediaClassification.Audio)
{
_audioPlayer.Value.Position = value;
}
else
{
_mediaElement.Position = value;
}
}
}

public Duration NaturalDuration => _mediaElement.NaturalDuration;
public Duration NaturalDuration
{
get
{
if (_currentMediaClassification == MediaClassification.Audio)
{
return _audioPlayer.Value.NaturalDuration;
}

return _mediaElement.NaturalDuration;
}
}

public Task Play(Uri mediaPath)
public Task Play(Uri mediaPath, MediaClassification mediaClassification)
{
IsPaused = false;
_currentMediaClassification = mediaClassification;

if (_currentMediaClassification == MediaClassification.Audio)
{
if (!IsPaused)
{
_audioPlayer.Value.Open(mediaPath);
}

if (_mediaElement.Source != mediaPath)
IsPaused = false;
_audioPlayer.Value.Play();
}
else
{
_mediaElement.Source = mediaPath;
IsPaused = false;

if (_mediaElement.Source != mediaPath)
{
_mediaElement.Source = mediaPath;
}

_mediaElement.Play();
}

_mediaElement.Play();

_timer.Start();

return Task.CompletedTask;
}

public Task Pause()
{
IsPaused = true;
_mediaElement.Pause();

if (_currentMediaClassification == MediaClassification.Audio)
{
_audioPlayer.Value.Pause();
}
else
{
_mediaElement.Pause();
}

return Task.CompletedTask;
}

public Task Close()
{
_timer.Stop();
_mediaElement.Close();

if (_currentMediaClassification == MediaClassification.Audio)
{
_audioPlayer.Value.Close();
}
else
{
_mediaElement.Close();
}

MediaClosed?.Invoke(this, null);
return Task.CompletedTask;
Expand All @@ -99,6 +175,22 @@ public Task Close()

public Guid MediaItemId { get; set; }

public void UnsubscribeEvents()
{
_mediaElement.MediaOpened -= HandleMediaOpened;
_mediaElement.MediaEnded -= HandleMediaEnded;
_mediaElement.MediaFailed -= HandleMediaFailed;

if (_audioPlayer.IsValueCreated)
{
_audioPlayer.Value.MediaOpened -= HandleMediaOpened2;
_audioPlayer.Value.MediaEnded -= HandleMediaEnded2;
_audioPlayer.Value.MediaFailed -= HandleMediaFailed2;
}

_timer.Tick -= TimerFire;
}

private void HandleMediaOpened(object sender, RoutedEventArgs e)
{
MediaOpened?.Invoke(sender, e);
Expand All @@ -118,5 +210,35 @@ private void TimerFire(object sender, EventArgs e)
{
PositionChanged?.Invoke(this, new PositionChangedEventArgs(MediaItemId, Position));
}

private MediaPlayer MediaPlayerFactory()
{
var result = new MediaPlayer
{
Volume = 1.0,
ScrubbingEnabled = _optionsService.Options.AllowVideoScrubbing
};

result.MediaOpened += HandleMediaOpened2;
result.MediaEnded += HandleMediaEnded2;
result.MediaFailed += HandleMediaFailed2;

return result;
}

private void HandleMediaFailed2(object sender, ExceptionEventArgs e)
{
HandleMediaFailed(sender, null);
}

private void HandleMediaEnded2(object sender, EventArgs e)
{
HandleMediaEnded(sender, null);
}

private void HandleMediaOpened2(object sender, EventArgs e)
{
HandleMediaOpened(sender, null);
}
}
}
25 changes: 19 additions & 6 deletions OnlyM/MediaElementAdaption/MediaElementUnoSquare.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace OnlyM.MediaElementAdaption
using OnlyM.Core.Models;

namespace OnlyM.MediaElementAdaption
{
using System;
using System.Threading.Tasks;
Expand All @@ -9,13 +11,13 @@
internal sealed class MediaElementUnoSquare : IMediaElement
{
private readonly Unosquare.FFME.MediaElement _mediaElement;

public MediaElementUnoSquare(Unosquare.FFME.MediaElement mediaElement)
{
_mediaElement = mediaElement;
_mediaElement.Volume = 1.0;

_mediaElement.MediaOpened += async (s, e) => await HandleMediaOpened(s, e);
_mediaElement.MediaOpened += HandleMediaOpened;
_mediaElement.MediaClosed += HandleMediaClosed;
_mediaElement.MediaEnded += HandleMediaEnded;
_mediaElement.MediaFailed += HandleMediaFailed;
Expand Down Expand Up @@ -50,7 +52,7 @@ public TimeSpan Position

public Guid MediaItemId { get; set; }

public async Task Play(Uri mediaPath)
public async Task Play(Uri mediaPath, MediaClassification mediaClassification)
{
IsPaused = false;

Expand Down Expand Up @@ -78,7 +80,18 @@ public Task Close()

public bool IsPaused { get; private set; }

private async Task HandleMediaOpened(object sender, RoutedEventArgs e)
public void UnsubscribeEvents()
{
_mediaElement.MediaOpened -= HandleMediaOpened;
_mediaElement.MediaClosed -= HandleMediaClosed;
_mediaElement.MediaEnded -= HandleMediaEnded;
_mediaElement.MediaFailed -= HandleMediaFailed;
_mediaElement.RenderingSubtitles -= HandleRenderingSubtitles;
_mediaElement.PositionChanged -= HandlePositionChanged;
_mediaElement.MessageLogged -= HandleMessageLogged;
}

private async void HandleMediaOpened(object sender, RoutedEventArgs e)
{
await _mediaElement.Play();
MediaOpened?.Invoke(sender, e);
Expand Down
12 changes: 9 additions & 3 deletions OnlyM/Services/VideoDisplayManager.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace OnlyM.Services
using System.Windows.Media;

namespace OnlyM.Services
{
using System;
using System.Threading.Tasks;
Expand Down Expand Up @@ -50,6 +52,9 @@ public async Task ShowVideoOrPlayAudio(
bool startFromPaused)
{
_mediaItemId = mediaItemId;

Log.Debug($"ShowVideoOrPlayAudio - Media Id = {_mediaItemId}");

_mediaClassification = mediaClassification;
_startPosition = startOffset;
_lastPosition = TimeSpan.Zero;
Expand All @@ -61,12 +66,13 @@ public async Task ShowVideoOrPlayAudio(
if (startFromPaused)
{
_mediaElement.Position = _startPosition;
await _mediaElement.Play(new Uri(mediaItemFilePath));
await _mediaElement.Play(new Uri(mediaItemFilePath), _mediaClassification);
OnMediaChangeEvent(CreateMediaEventArgs(_mediaItemId, MediaChange.Started));
}
else
{
await _mediaElement.Play(new Uri(mediaItemFilePath));
Log.Debug($"Firing Started - Media Id = {_mediaItemId}");
await _mediaElement.Play(new Uri(mediaItemFilePath), _mediaClassification).ConfigureAwait(true);
OnMediaChangeEvent(CreateMediaEventArgs(_mediaItemId, MediaChange.Starting));
}
}
Expand Down
6 changes: 6 additions & 0 deletions OnlyM/ViewModel/OperatorViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -330,12 +330,16 @@ private void ChangePlayButtonEnabledStatus()

private void HandleMediaChangeEvent(object sender, MediaEventArgs e)
{
Log.Debug($"HandleMediaChangeEvent (id = {e.MediaItemId}, change = {e.Change})");

var mediaItem = GetMediaItem(e.MediaItemId);
if (mediaItem == null)
{
return;
}

Log.Debug(mediaItem.Name);

switch (e.Change)
{
case MediaChange.Starting:
Expand Down Expand Up @@ -504,6 +508,8 @@ private async Task MediaControl1(Guid mediaItemId)
// only allow start/stop media when nothing is changing.
if (!_mediaStatusChangingService.IsMediaStatusChanging())
{
Log.Debug($"MediaControl1 (id = {mediaItemId})");

var mediaItem = GetMediaItem(mediaItemId);
if (mediaItem == null)
{
Expand Down
6 changes: 4 additions & 2 deletions OnlyM/Windows/MediaWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ private void ShowImage(MediaItem mediaItem)
mediaItem.IsBlankScreen);
}

private async Task ShowVideoOrPlayAudio(
private Task ShowVideoOrPlayAudio(
MediaItem mediaItemToStart,
IReadOnlyCollection<MediaItem> currentMediaItems,
bool startFromPaused)
Expand All @@ -196,7 +196,7 @@ private async Task ShowVideoOrPlayAudio(

_videoDisplayManager.ShowSubtitles = _optionsService.Options.ShowVideoSubtitles;

await _videoDisplayManager.ShowVideoOrPlayAudio(
return _videoDisplayManager.ShowVideoOrPlayAudio(
mediaItemToStart.FilePath,
_optionsService.Options.VideoScreenPosition,
mediaItemToStart.Id,
Expand Down Expand Up @@ -318,6 +318,8 @@ private void HandleImageScreenPositionChangedEvent(object sender, EventArgs e)

private void InitRenderingMethod()
{
_videoElement?.UnsubscribeEvents();

switch (_optionsService.Options.RenderingMethod)
{
case RenderingMethod.Ffmpeg:
Expand Down
Loading

0 comments on commit 33b030b

Please sign in to comment.