I am coding a cross platform app and currently working on where users can choose images or videos up to 10 using Xamarin.MediaGallery NuGet Package. This line, var results = await MediaGallery.PickAsync(10, MediaFileType.Image, MediaFileType.Video);, let's me choose both Images and Videos up to 10 and the code below takes the images, convert each into a byte array, and add them to an empty byte list and send it to another page. What I can confirm is that when a user selects, let's say, 5 pictures from their gallery, each picture is successfully converted into a byte and sent it to another page where that page displays the selected pictures.
private async void PickFromLibrary(object sender, EventArgs e)
{
var results = await MediaGallery.PickAsync(10, MediaFileType.Image, MediaFileType.Video);
try
{
if (results.Files == null)
return;
List<byte[]> byteList = new List<byte[]>();
foreach (var media in results.Files)
{
photoPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "rotated_photo.jpg");
var selectedMedia = media.OpenReadAsync().Result;
using (var memoryStream = new MemoryStream())
{
await selectedMedia.CopyToAsync(memoryStream);
// skipped code. Rotate the image by 90 degrees to the right
byte[] rotatedImageBytes = File.ReadAllBytes(photoPath);
byteList.Add(rotatedImageBytes);
}
File.Delete(photoPath);
}
await Navigation.PushAsync(new EditPostPage(userId, textId, byteList));
}
catch (OperationCanceledException)
{
await Navigation.PopAsync();
}
catch (Exception ex)
{
await DisplayAlert("Error", $"Failed selecting medias: {ex.Message}", "OK");
}
}
With the code above, this is the XAML code in EditPostPage that shows the images in CarouselView. I didn't implement any other code like MediaElement to display a video yet.
<CarouselView x:Name="imageCarousel" IndicatorView="IndicatorView">
<CarouselView.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}" Aspect="AspectFill" RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width}"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height}" />
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
And below is the back end code where it takes the byte list and convert it back to images.
public EditPostPage(int userId, int textId, List<byte[]> byteList)
{
InitializeComponent();
this.userId = userId;
this.textId = textId;
this.byteImage = byteList;
Appearing += (sender, e) =>
{
imageCarousel.ItemsSource = byteImage.Select(bytes => ImageSource.FromStream(() => new MemoryStream(bytes)));
if (byteImage.Count <= 1)
{
imageCarousel.IsSwipeEnabled = false;
}
};
}
What I am struggling is that now that the users can successfully select images and the EditPostPage shows the images, I want the users to be able to select videos and the videos show up on EditPostPage. I did use var results = await MediaGallery.PickAsync(10, MediaFileType.Image, MediaFileType.Video); so users can select videos. But there are two things that I can't figure out.
I don't know if the
PickFromLibrarymethod will also turn the selected videos into a byte array and send it toEditPostPage.How will I modify
EditPostPageso if the user selected a video, it shows the video, if the user selected images, it shows the images. I want to implement a code where the code determines if the selected media is an image or a video and act accordingly. That is, if user selects an image, it displays the image, if user selects a video, it displays the video. Even though I read MediaGallery doc in GitHub I can't figure out how to distinguish whether the user selected an image or a video. https://github.com/dimonovdd/Xamarin.MediaGallery
I was considering put something like the following code where I implement IsVisible function and make it true or false depending on the media type. But How would I figure out if the media type the user selected is an image or a video?
<CarouselView x:Name="imageCarousel" IndicatorView="IndicatorView" IsVisible="{Binding IsImageCarouselVisible}">
<CarouselView.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}" Aspect="AspectFill" RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width}"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height}" />
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
<xyt:MediaElement x:Name="videoPlayer" IsVisible="{Binding IsVideoPlayerVisible}" RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width}"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height}" />
IMediaFilecontains anExtension,ContentType, andTypefields that should all allow you to distinguish a video from an image.byte[]instead of just passing theIMediaFile?byte[]since it offers a more straightforward and generic approach. There isn't really a specific reason why I chosebyte[]. I've never usedIMediaFilebefore and have no knowledge. Is there a website or a doc I can view? Thank you.