Skip to content

Commit

Permalink
Merge pull request #627 from JuanuMusic/video-placeholder
Browse files Browse the repository at this point in the history
Video placeholder for Xamarin.Forms
  • Loading branch information
martijn00 authored Oct 14, 2019
2 parents 51ff83c + 3d5b9ae commit 1a08803
Show file tree
Hide file tree
Showing 22 changed files with 826 additions and 74 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ build/
bld/
[Bb]in/
[Oo]bj/
.vscode/

# Visual Studo 2015 cache/options directory
.vs/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,27 @@

namespace MediaManager.Forms
{
public static class ImageSourceHelper
public static partial class ImageSourceExtensions
{
public static ImageSource ToImageSource(this object image)
{
if (image is ImageSource imageSource)
return imageSource;
#if ANDROID
if (image is Android.Graphics.Bitmap bitmap)
return MediaManager.Forms.Platforms.Android.ImageSourceHelper.ToImageSource(bitmap);
return bitmap.ToImageSource();
#elif IOS
if (image is CoreGraphics.CGImage cgImage)
return MediaManager.Forms.Platforms.Ios.ImageSourceHelper.ToImageSource(cgImage);
return cgImage.ToImageSource();
else if (image is UIKit.UIImage uIImage)
return MediaManager.Forms.Platforms.Ios.ImageSourceHelper.ToImageSource(uIImage);
return uIImage.ToImageSource();
#elif MAC
if (image is CoreGraphics.CGImage cgImage)
return cgImage.ToImageSource();
#elif WINDOWS
//TODO: This one should not be async. It might deadlock
if (image is Windows.UI.Xaml.Media.Imaging.BitmapImage bitmapImage)
return MediaManager.Forms.Platforms.Uap.ImageSourceHelper.ToImageSource(bitmapImage).GetAwaiter().GetResult();
return bitmapImage.ToImageSource().GetAwaiter().GetResult();
#endif
return null;
}
Expand Down
55 changes: 55 additions & 0 deletions MediaManager.Forms/Platforms/Android/ImageSourceExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using System.IO;
using System.Threading.Tasks;
using Android.Content;
using Android.Graphics;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

namespace MediaManager.Forms
{
public static partial class ImageSourceExtensions
{
public static ImageSource ToImageSource(this Bitmap bitmap)
{
if (bitmap != null)
{
var stream = new MemoryStream();
bitmap.Compress(Bitmap.CompressFormat.Png, 0, stream);
var bitmapData = stream.ToArray();
return ImageSource.FromStream(() => new MemoryStream(bitmapData));
}
return null;
}

public static async Task<Bitmap> ToNative(this ImageSource source)
{
return await source.ToNative(Android.App.Application.Context);
}

public static async Task<Bitmap> ToNative(this ImageSource source, Context context)
{
var imageHandler = source.GetImageSourceHandler();
if (imageHandler == null)
return null;

return await imageHandler.LoadImageAsync(source, context);
}

public static IImageSourceHandler GetImageSourceHandler(this ImageSource source)
{
//check the specific source type and return the correct image source handler
switch (source)
{
case FileImageSource _:
return new FileImageSourceHandler();
case StreamImageSource _:
return new StreamImagesourceHandler();
case FontImageSource _:
return new FontImageSourceHandler();
case UriImageSource _:
default:
return new ImageLoaderSourceHandler();
}
}
}
}
21 changes: 0 additions & 21 deletions MediaManager.Forms/Platforms/Android/ImageSourceHelper.cs

This file was deleted.

12 changes: 9 additions & 3 deletions MediaManager.Forms/Platforms/Android/VideoViewRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,17 @@ protected override void OnElementChanged(ElementChangedEventArgs<VideoView> args

protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
if (_videoView != null)
if (_videoView != null && widthMeasureSpec > -1 && heightMeasureSpec > -1)
{
var p = _videoView.LayoutParameters;
p.Height = heightMeasureSpec;
p.Width = widthMeasureSpec;

if (p == null)
p = new LayoutParams(widthMeasureSpec, heightMeasureSpec);
else
{
p.Height = heightMeasureSpec;
p.Width = widthMeasureSpec;
}
_videoView.LayoutParameters = p;
}
base.OnMeasure(widthMeasureSpec, heightMeasureSpec);
Expand Down
47 changes: 47 additions & 0 deletions MediaManager.Forms/Platforms/Ios/ImageSourceExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System.Threading.Tasks;
using CoreGraphics;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

namespace MediaManager.Forms
{
public static partial class ImageSourceExtensions
{
public static ImageSource ToImageSource(this CGImage cgImage)
{
return ImageSource.FromStream(() => new UIImage(cgImage).AsPNG().AsStream());
}

public static ImageSource ToImageSource(this UIImage uIImage)
{
return ImageSource.FromStream(() => uIImage.AsPNG().AsStream());
}

public static async Task<UIImage> ToNative(this ImageSource source)
{
var imageHandler = source.GetImageSourceHandler();
if (imageHandler == null)
return null;

return await imageHandler.LoadImageAsync(source);
}

public static IImageSourceHandler GetImageSourceHandler(this ImageSource source)
{
//check the specific source type and return the correct image source handler
switch (source)
{
case FileImageSource _:
return new FileImageSourceHandler();
case StreamImageSource _:
return new StreamImagesourceHandler();
case FontImageSource _:
return new FontImageSourceHandler();
case UriImageSource _:
default:
return new ImageLoaderSourceHandler();
}
}
}
}
19 changes: 0 additions & 19 deletions MediaManager.Forms/Platforms/Ios/ImageSourceHelper.cs

This file was deleted.

31 changes: 31 additions & 0 deletions MediaManager.Forms/Platforms/Mac/ImageSourceExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using AppKit;
using CoreGraphics;
using Xamarin.Forms;
using Xamarin.Forms.Platform.MacOS;

namespace MediaManager.Forms
{
public static partial class ImageSourceExtensions
{
public static ImageSource ToImageSource(this CGImage cgImage)
{
return ImageSource.FromStream(() => new NSImage(cgImage, new CGSize(cgImage.Width, cgImage.Height)).AsTiff().AsStream());
}

public static IImageSourceHandler GetImageSourceHandler(this ImageSource source)
{
//check the specific source type and return the correct image source handler
switch (source)
{
case FileImageSource _:
return new FileImageSourceHandler();
case StreamImageSource _:
return new StreamImagesourceHandler();
case FontImageSource _:
case UriImageSource _:
default:
return new ImageLoaderSourceHandler();
}
}
}
}
24 changes: 24 additions & 0 deletions MediaManager.Forms/Platforms/Tizen/ImageSourceExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Xamarin.Forms;
using Xamarin.Forms.Platform.Tizen;

namespace MediaManager.Forms
{
public static partial class ImageSourceExtensions
{
public static IImageSourceHandler GetImageSourceHandler(this ImageSource source)
{
//check the specific source type and return the correct image source handler
switch (source)
{
case FileImageSource _:
return new FileImageSourceHandler();
case StreamImageSource _:
return new StreamImageSourceHandler();
case FontImageSource _:
case UriImageSource _:
default:
return new UriImageSourceHandler();
}
}
}
}
40 changes: 40 additions & 0 deletions MediaManager.Forms/Platforms/Uap/ImageSourceExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System;
using System.IO;
using System.Threading.Tasks;
using Windows.Storage.Streams;
using Windows.UI.Xaml.Media.Imaging;
using Xamarin.Forms;
using Xamarin.Forms.Platform.UWP;

namespace MediaManager.Forms
{
public static partial class ImageSourceExtensions
{
public static async Task<ImageSource> ToImageSource(this BitmapImage bitmapImage)
{
IRandomAccessStreamReference random = RandomAccessStreamReference.CreateFromUri(bitmapImage.UriSour‌​ce);
var decoder = await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(await random.OpenReadAsync());
var pixelData = await decoder.GetPixelDataAsync();
var bitmapData = pixelData.DetachPixelData();

return ImageSource.FromStream(() => new MemoryStream(bitmapData));
}

public static IImageSourceHandler GetImageSourceHandler(this ImageSource source)
{
//check the specific source type and return the correct image source handler
switch (source)
{
case FileImageSource _:
return new FileImageSourceHandler();
case StreamImageSource _:
return new StreamImageSourceHandler();
case FontImageSource _:
return new FontImageSourceHandler();
case UriImageSource _:
default:
return new UriImageSourceHandler();
}
}
}
}
22 changes: 0 additions & 22 deletions MediaManager.Forms/Platforms/Uap/ImageSourceHelper.cs

This file was deleted.

25 changes: 25 additions & 0 deletions MediaManager.Forms/Platforms/Wpf/ImageSourceExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Xamarin.Forms;
using Xamarin.Forms.Platform.WPF;

namespace MediaManager.Forms
{
public static partial class ImageSourceExtensions
{

public static IImageSourceHandler GetImageSourceHandler(this ImageSource source)
{
//check the specific source type and return the correct image source handler
switch (source)
{
case FileImageSource _:
return new FileImageSourceHandler();
case StreamImageSource _:
return new StreamImageSourceHandler();
case FontImageSource _:
case UriImageSource _:
default:
return new UriImageSourceHandler();
}
}
}
}
17 changes: 17 additions & 0 deletions MediaManager.Forms/VideoView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ private void MediaPlayer_PropertyChanged(object sender, System.ComponentModel.Pr
case nameof(MediaPlayer.VideoWidth):
VideoWidth = MediaPlayer.VideoWidth;
break;
case nameof(MediaPlayer.VideoPlaceholder):
VideoPlaceholder = MediaPlayer.VideoPlaceholder?.ToImageSource();
break;
default:
break;
}
Expand Down Expand Up @@ -145,6 +148,9 @@ private void MediaManager_BufferedChanged(object sender, BufferedChangedEventArg
public static readonly BindableProperty SpeedProperty =
BindableProperty.Create(nameof(Speed), typeof(float), typeof(VideoView), 1.0f, propertyChanged: OnSpeedPropertyChanged, defaultValueCreator: x => MediaManager.Speed);

public static readonly BindableProperty VideoPlaceholderProperty =
BindableProperty.Create(nameof(VideoPlaceholder), typeof(ImageSource), typeof(VideoView), null, propertyChanged: OnVideoPlaceholderPropertyChanged, defaultValueCreator: x => MediaManager.MediaPlayer.VideoPlaceholder?.ToImageSource());

public VideoAspectMode VideoAspect
{
get => (VideoAspectMode)GetValue(VideoAspectProperty);
Expand Down Expand Up @@ -235,6 +241,12 @@ public float Speed
set { SetValue(SpeedProperty, value); }
}

public ImageSource VideoPlaceholder
{
get { return (ImageSource)GetValue(VideoPlaceholderProperty); }
set { SetValue(VideoPlaceholderProperty, value); }
}

private static async void OnSourcePropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
//Prevent loop with MediaQueue_QueueChanged
Expand Down Expand Up @@ -280,6 +292,11 @@ private static void OnAutoPlayPropertyChanged(BindableObject bindable, object ol
MediaManager.AutoPlay = (bool)newValue;
}

private static void OnVideoPlaceholderPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
MediaManager.MediaPlayer.VideoPlaceholder = newValue;
}

public void Dispose()
{
MediaManager.BufferedChanged -= MediaManager_BufferedChanged;
Expand Down
Loading

0 comments on commit 1a08803

Please sign in to comment.