Mobiele apps programmeren met Xamarin – Multimedia integreren

print

Inhoud


Wat vooraf ging

Ik herneem hier even een vorige post over het installeren van NuGet Packages (plug-ins).

NuGet is een package manager voor Microsoft development platforms zoals .NET. U kunt deze pakketten installeren om zo de mogelijkheden van uw project uit te breiden.

  • Om een NuGet package te installeren klikt u rechts op het project waar u het NuGet package wilt voor installeren of u klikt rechts op de Solution om het NuGet package meteen te installeren voor alle projecten.
  • Vervolgens klikt u op Manage NuGet packages for Solution….

  • Selecteer het NuGet package dat u wil installeren.
  • Vink alle projecten aan waarvoor u het wilt installeren.
  • Klik op Install.

Onderstaande video toont een volledige installatie (zij het in Visual Studio 2015 en voor een ASP.NET project maar in weze verschilt dit niet).


Inleiding

Onder integratie van multimedia versta ik hier:

  • Foto’s nemen en weergeven.
  • Video’s opnemen en weergeven.
  • En als extraatje, geluid afspelen.

Hiervoor hebben we 3 plug-ins nodig:

Een overzicht van heel wat interessante plug-ins, waarvan sommigen in andere post aan bod komen, vindt u hier.

  • Start een nieuw Xamarin-project en geef het een passende naam (bv. TestMediaPlugin).

MediaPlugin – installeren

  • Klik rechts op de Solution om het NuGet package meteen te installeren voor alle projecten.
  • Vervolgens klikt u op Manage NuGet packages for Solution….
  • Klik op Browse.
  • Zoek naar xam.plugin.media, selecteer alle projecten en de laatste stabiele versie en klik op Install.
  • Doe hetzelfde voor Rox.Xamarin.Video.

Update

Wanneer u met NuGet Packages werkt is het vaak aan te raden om ook de rest van het project up te daten.

  • Klik op Updates.
  • Selecteer Xamarin.Form en Microsoft.NETCore.UniversalWindowsPlatform en klik op Update, of selecteer ze elk afzonderlijk en installeer zelf de laatste stabiele versie.


MediaPlugin – Permissies instellen

Om van de foto en video toepassingen van uw toestel gebruik te kunnen maken is er “toelating” nodig van de gebruiker. U moet deze “permissies” dan ook instellen om de app aan het werk te krijgen.

UWP

In UWP is dit vrij eenvoudig, u moet de applicatie enkel toegang geven tot de Webcam.

  • Open Properties onder het UWP-project.
  • Ga naar Application en klik op Package Manifest….
  • Selecteer het tabblad Capabilities en vink Webcam (helemaal onderaan) aan.

Android

Voor Android moeten de WRITE_EXTERNAL_STORAGE en READ_EXTERNAL_STORAGE permissies worden ingesteld. Dit gebeurt echter automatisch door de plug-in. Om Android-permissies zelf in te stellen:

  • Open Properties onder het Android-project.
  • Ga naar Android Manifest.
  • Vink WRITE_EXTERNAL_STORAGE en READ_EXTERNAL_STORAGE aan.

Deze plug-in bouwt verder op de Permission Plugin, die eveneens, automatisch, toegevoegd is. Deze Permission Plugin vraagt onderstaande aanpassing.

  • Voeg onderstaande code toe aan MainActivity.cs dat u eveneens vindt onder het Android-project.
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults)
{
    Plugin.Permissions.PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}

De volledige code voor MainActivity.cs is:

using Android.App;
using Android.Content.PM;
using Android.OS;

namespace TestMediaPlugin.Droid
{
    [Activity(Label = "TestMediaPlugin", Icon = "@drawable/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        protected override void OnCreate(Bundle bundle)
        {
            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;

            base.OnCreate(bundle);

            global::Xamarin.Forms.Forms.Init(this, bundle);
            LoadApplication(new App());
        }

        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults)
        {
            Plugin.Permissions.PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }
}

We zijn er nog niet.

  • Voeg onderstaande code toe aan AndroidManifest.xml, binnen de Application-tag dat u eveneens vindt onder het Android-project.
<provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true">
	<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"></meta-data>
</provider>

De volledige code voor AndroidManifest.xml is:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
	<uses-sdk android:minSdkVersion="15" />
	<application android:label="TestMediaPlugin.Android">
            <provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true">
	        <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"></meta-data>
            </provider>
	</application>
</manifest>
  • Tenslotte moet nog een mapje met de naam xml worden aan gemaakt onder de reeds bestaande map Resources.
  • Binnen deze map wordt een Xml-bestand toegevoegd (via rechtsklik Add – New item… – Data – XML File) met de naam file_paths.xml.

  • Voeg onderstaande code toe aan file_paths.xml.
<?xml version="1.0" encoding="utf-8" ?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
  <external-files-path name="my_images" path="Pictures" />
  <external-files-path name="my_movies" path="Movies" />
</paths>

Voila, meer moet er niet gebeuren voor Android.

iOS

Voor iOS dient u een aantal keys, en bijhorende meldingen die verschijnen wanneer u er gebruik van wilt maken, toevoegen aan het bestandje Info.plist.

  • Klik rechts Info.plist dat u vindt onder het iOS-project en kies voor Open with… en selecteer XML (Text) Editor.
  • Voeg onderstaande code toe.
<key>NSCameraUsageDescription</key>
<string>This app needs access to the camera to take photos.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app needs access to photos.</string>
<key>NSMicrophoneUsageDescription</key>
<string>This app needs access to microphone.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>This app needs access to the photo gallery.</string>

De volledige code is:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>UIDeviceFamily</key>
    <array>
      <integer>1</integer>
      <integer>2</integer>
    </array>
    <key>UISupportedInterfaceOrientations</key>
    <array>
      <string>UIInterfaceOrientationPortrait</string>
      <string>UIInterfaceOrientationLandscapeLeft</string>
      <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
    <key>UISupportedInterfaceOrientations~ipad</key>
    <array>
      <string>UIInterfaceOrientationPortrait</string>
      <string>UIInterfaceOrientationPortraitUpsideDown</string>
      <string>UIInterfaceOrientationLandscapeLeft</string>
      <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
    <key>MinimumOSVersion</key>
    <string>8.0</string>
    <key>CFBundleDisplayName</key>
    <string>TestMediaPlugin</string>
    <key>CFBundleIdentifier</key>
    <string>com.yourcompany.TestMediaPlugin</string>
    <key>CFBundleVersion</key>
    <string>1.0</string>
    <key>CFBundleIconFiles</key>
    <array>
      <string>Icon-60@2x</string>
      <string>Icon-60@3x</string>
      <string>Icon-76</string>
      <string>Icon-76@2x</string>
      <string>Default</string>
      <string>Default@2x</string>
      <string>Default-568h@2x</string>
      <string>Default-Portrait</string>
      <string>Default-Portrait@2x</string>
      <string>Icon-Small-40</string>
      <string>Icon-Small-40@2x</string>
      <string>Icon-Small-40@3x</string>
      <string>Icon-Small</string>
      <string>Icon-Small@2x</string>
      <string>Icon-Small@3x</string>
    </array>
    <key>UILaunchStoryboardName</key>
    <string>LaunchScreen</string>
    <key>NSCameraUsageDescription</key>
    <string>This app needs access to the camera to take photos.</string>
    <key>NSPhotoLibraryUsageDescription</key>
    <string>This app needs access to photos.</string>
    <key>NSMicrophoneUsageDescription</key>
    <string>This app needs access to microphone.</string>
    <key>NSPhotoLibraryAddUsageDescription</key>
    <string>This app needs access to the photo gallery.</string>
  </dict>
</plist>

Lees hier meer over iOS 10 Privacy Permission Settings.

Een overzicht van alle permissies vindt u hieronder (ik heb de Engelse uitleg behouden).

  • Privacy – Apple Music usage Description (NSAppleMusicUsageDescription) – Allows the developer to describe why the app wants to access the user’s media library.
  • Privacy – Bluetooth Peripheral Usage Description (NSBluetoothPeripheralUsageDescription) – Allows the developer to describe why the app wants to access Bluetooth on the user’s device.
  • Privacy – Calendars Usage Description (NSCalendarsUsageDescription) – Allows the developer to describe why the app wants to access the user’s calendar.
  • Privacy – Camera Usage Description (NSCameraUsageDescription) – Allows the developer to describe why the app wants to access the device’s camera.
  • Privacy – Contacts Usage Description (NSContactsUsageDescription) – Allows the developer to describe why the app wants to access the user’s contacts.
  • Privacy – Health Share Usage Description (NSHealthShareUsageDescription) – Allows the developer to describe why the app wants to access the user’s health data.
  • Privacy – Health Update Usage Description (NSHealthUpdateUsageDescription) – Allows the developer to describe why the app wants to edit the user’s health data.
  • Privacy – HomeKit Usage Description (NSHomeKitUsageDescription) – Allows the developer to describe why the app wants to access the user’s HomeKit Configuration Data.
  • Privacy – Location Always Usage Description (NSLocationAlwaysUsageDescription) – Allows the developer to describe why the app wants to always have access to the user’s location.
  • [Deprecated] Privacy – Location Usage Description (NSLocationUsageDescription) – Allows the developer to describe why the app wants to access the user location. NOTE: This key has been deprecated in iOS 8 (and greater). Use NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription instead.
  • Privacy – Location When In Use Usage Description (NSLocationWhenInUseUsageDescription) – Allows the developer to describe why the app wants to access the user’s location while it is running.
  • [Deprecated] Privacy – Media Library Usage Description – Allows the developer to describe why the app wants to access to the user’s media library. NOTE: This key has been deprecated in iOS 8 (and greater). Use NSAppleMusicUsageDescription instead.
  • Privacy – Microphone Usage Description (NSMicrophoneUsageDescription) – Allows the developer to describe why the app wants to access the devices microphone.
  • Privacy – Motion Usage Description (NSMotionUsageDescription) – Allows the developer to describe why the app wants to access the device’s accelerometer.
  • Privacy – Photo Library Usage Description (NSPhotoLibraryUsageDescription) – Allows the developer to describe why the app wants to access the user’s photo library.
  • Privacy – Reminders Usage Description (NSRemindersUsageDescription) – Allows the developer to describe why the app wants to access the user’s reminders.
  • Privacy – Siri Usage Description (NSSiriUsageDescription) – Allows the developer to describe why the app wants to send user data to Siri.
  • Privacy – Speech Recognition Usage Description (NSSpeechRecognitionUsageDescription) – Allows the developer to describe why the app wants to send user data to Apple’s speech recognition servers.
  • Privacy – TV Provider Usage Description (NSVideoSubscriberAccountUsageDescription) – Allows the developer to describe why the app wants to access the user’s TV provider account.

MediaPlugin – Uitgelegd

Hieronder plaats ik een aantal code snippets, komende van de officiële website, die het gebruik van de MediaPlugin uitlegt.

eigenschappen en methoden

Voordat u foto’s of video’s maakt, moet u controleren of een camera bestaat en of foto’s en video’s worden ondersteund op het apparaat. Er zijn vijf eigenschappen die u kunt controleren:

Eigenschappen voor het controleren van mogelijkheden

/// <summary>
/// Initialize all camera components, must be called before checking properties below
/// </summary>
/// <returns>If success</returns>
Task<bool> Initialize();

/// <summary>
/// Gets if a camera is available on the device
/// </summary>
bool IsCameraAvailable { get; }

/// <summary>
/// Gets if ability to take photos supported on the device
/// </summary>
bool IsTakePhotoSupported { get; }

/// <summary>
/// Gets if the ability to pick photo is supported on the device
/// </summary>
bool IsPickPhotoSupported { get; }

/// <summary>
/// Gets if ability to take video is supported on the device
/// </summary>
bool IsTakeVideoSupported { get; }

/// <summary>
/// Gets if the ability to pick a video is supported on the device
/// </summary>
bool IsPickVideoSupported { get; }

Methoden voor foto’s

/// <summary>
/// Picks a photo from the default gallery
/// </summary>
/// <param name="options">Pick Photo Media Options</param>
/// <returns>Media file or null if canceled</returns>
Task<MediaFile> PickPhotoAsync(PickMediaOptions options = null);

/// <summary>
/// Take a photo async with specified options
/// </summary>
/// <param name="options">Camera Media Options</param>
/// <returns>Media file of photo or null if canceled</returns>
Task<MediaFile> TakePhotoAsync(StoreCameraMediaOptions options);

Methoden voor videos

/// <summary>
/// Picks a video from the default gallery
/// </summary>
/// <returns>Media file of video or null if canceled</returns>
Task<MediaFile> PickVideoAsync();

/// <summary>
/// Take a video with specified options
/// </summary>
/// <param name="options">Video Media Options</param>
/// <returns>Media file of new video or null if canceled</returns>
Task<MediaFile> TakeVideoAsync(StoreVideoOptions options);

Een foto nemen

Alle functionaliteiten zijn toegankelijk via de eigenschap CrossMedia.Current.

Voordat u een foto maakt, kunt u ervoor zorgen dat de camera beschikbaar is en dat het maken van foto’s met het apparaat wordt ondersteund met de eigenschappen IsCameraAvailable en IsTakePhotoSupported.

if (CrossMedia.Current.IsCameraAvailable && CrossMedia.Current.IsTakePhotoSupported)
{
}

Nadat we ervoor hebben gezorgd dat het maken van een foto met het apparaat mogelijk is kunnen we onze opslagopties configureren nadat de foto is gemaakt met de klasse StoreCameraMediaOptions.

// Supply media options for saving our photo after it's taken.
var mediaOptions = new Plugin.Media.Abstractions.StoreCameraMediaOptions
{
   Directory = "Receipts",
   Name = $"{DateTime.UtcNow}.jpg"
};

Een foto maken is net zo eenvoudig als het aanroepen van TakePhotoAsync en het meegeven van de opslagopties:

// Take a photo of the business receipt.
var file = await CrossMedia.Current.TakePhotoAsync(mediaOptions);

De volledige code:

if (CrossMedia.Current.IsCameraAvailable && CrossMedia.Current.IsTakePhotoSupported)
{
    // Supply media options for saving our photo after it's taken.
    var mediaOptions = new Plugin.Media.Abstractions.StoreCameraMediaOptions
    {
        Directory = "Receipts",
        Name = $"{DateTime.UtcNow}.jpg"
    };

// Take a photo of the business receipt.
var file = await CrossMedia.Current.TakePhotoAsync(mediaOptions);
}

Een video opnemen

Het opnemen van een video is gelijkaardig aan het nemen van een foto. Het verschil zit hem eigenlijk enkel in het gebruik van typische video-eigenschappen en methoden zoals IsTakeVideoSupported en TakeVideoAsync.

if (CrossMedia.Current.IsCameraAvailable && CrossMedia.Current.IsTakeVideoSupported)
{
    // Supply media options for saving our video after it's taken.
    var mediaOptions = new Plugin.Media.Abstractions.StoreCameraMediaOptions
    {
        Directory = "Videos",
        Name = $"{DateTime.UtcNow}.mp4"
    };

// Record a video
var file = await CrossMedia.Current.TakeVideoAsync(mediaOptions);
}

Foto en video instellingen

De standaardcamera instellen

Bepaal welke camera, vooraan of achteraan, er standaard gebruikt wordt.

var file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
{
    DefaultCamera = Plugin.Media.Abstractions.CameraDevice.Front
});

Bijsnijden/cropping instellen

Zowel iOS als UWP hebben bij het maken van een foto “bijsnijden/cropping” ingebouwd in de camerabediening. Op iOS is de standaardwaarde false en op UWP is de standaardwaarde is true. U kunt de eigenschap AllowCropping aanpassen wanneer u een foto maakt, zodat degebruiker deze kan bijsnijden.

var file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
{
    AllowCropping = true
});

Formaat aanpassen

Standaard is de foto die wordt gemaakt de maximale grootte en kwaliteit die beschikbaar is. Voor de meeste toepassingen is dit niet nodig en kan het worden aangepast. Dit kan worden bereikt door de eigenschap PhotoSize aan te passen. Het eenvoudigst is om het in te stellen op Small, Medium of Large, wat 25%, 50% of 75% of het origineel is.

var file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
{
    PhotoSize = PhotoSize.Medium,
});

Wilt u specifieke percentages instellen, dan kan dit als volgt:

var file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
{
    PhotoSize = PhotoSize.Custom,
    CustomPhotoSize = 90 //Resize to 90% of original
});

Kwaliteit instellen

Stel de CompressionQuality in, een waarde van 0, de meest gecomprimeerde tot 100, geen compressie. Een goede instelling van testen is ongeveer 92. Dit wordt alleen ondersteund in Android en iOS.

var file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
{
    CompressionQuality = 92
});

Foto’s en video’s bewaren in de filmrol/galerij

U kunt een foto of video opslaan in de filmrol/galerij. Bij het maken van de StoreCameraMediaOptions of StoreVideoMediaOptions stelt u SaveToAlbum eenvoudig in op true. Wanneer de gebruiker een foto maakt, slaat hij nog steeds tijdelijke gegevens op, maar maakt hij indien nodig een kopie naar de openbare galerij (op basis van platform). In de MediaFile ziet u nu een AlbumPath dat u kunt opvragen.

var file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
{
    SaveToAlbum = true
});

//Get the public album path
var aPpath = file.AlbumPath;

//Get private path
var path = file.Path;

Dit resulteert in 2 foto’s die worden opgeslagen. Eén in je privémap en één in een openbare map die wordt weergegeven. De waarde wordt geretourneerd in AlbumPath.

Android: wanneer u SaveToAlbum instelt zorgt dit ervoor dat uw foto’s openbaar zijn in de map Pictures/YourDirectory of Movies/YourDirectory. Dit is de enige manier waarop Android de foto’s kan detecteren.

Foto’s en video’s selecteren

Foto’s en video’s nemen is leuk maar u moet ook reeds opgeslagen foto’s en video’s kunnen selecteren (picken).

// Select a photo. 
if (CrossMedia.Current.IsPickPhotoSupported)
    var photo = await CrossMedia.Current.PickPhotoAsync();
 
// Select a video. 
if (CrossMedia.Current.IsPickVideoSupported)
    var video = await CrossMedia.Current.PickVideoAsync();

Neem een foto overlay (enkel iOS)

Op iOS kun je een overlay bovenop de camera opgeven. Het wordt weergegeven op de live camera en op het laatste voorbeeld, maar het wordt niet opgeslagen als onderdeel van de foto, het is dus geen filter!

//Load an image as an overlay (this is in the iOS Project)
Func<object> func = () =>
{
    var imageView = new UIImageView(UIImage.FromBundle("face-template.png"));
    imageView.ContentMode = UIViewContentMode.ScaleAspectFit;

    var screen = UIScreen.MainScreen.Bounds;
    imageView.Frame = screen;

    return imageView;
};

//Take Photo, could be in iOS Project, or in shared code where there function is passed up via Dependency Services.
var file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
{
    OverlayViewProvider = func
});

MediaPlugin – Een praktische toepassing

U hebt reeds de bovenstaande plugins geïnstalleerd en de nodige permissies ingesteld.

  • Pas de XAML aan voor MainPage.xaml.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:TestMediaPlugin" xmlns:roxv="clr-namespace:Rox;assembly=Rox.Xamarin.Video.Portable" x:Class="TestMediaPlugin.MainPage">

    <ScrollView>
        <StackLayout Spacing="10" Padding="10">
            <Button x:Name="takePhoto" Text="Take Photo" Clicked="takePhoto_Clicked"/>
            <Button x:Name="pickPhoto" Text="Pick Photo" Clicked="pickPhoto_Clicked"/>
            <Button x:Name="takeVideo" Text="Take Video" Clicked="takeVideo_Clicked"/>
            <Button x:Name="pickVideo" Text="Pick Video" Clicked="pickVideo_Clicked"/>
            <roxv:VideoView x:Name="MyVideo" AutoPlay="True" LoopPlay="True" ShowController="True" WidthRequest="640" HeightRequest="480" />
            <Image x:Name="image"/>
        </StackLayout>
    </ScrollView>

</ContentPage>

Om de video te kunnen weergeven moet de namespace worden toegevoegd xmlns:roxv="clr-namespace:Rox;assembly=Rox.Xamarin.Video.Portable".

Hieronder vindt u de Code-behind. Op basis van de bovenstaande uitleg zou deze code moeten duidelijk zijn.

using System;
using Xamarin.Forms;
using Plugin.Media;
using Plugin.Media.Abstractions;


namespace TestMediaPlugin
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            
        }

        async private void takePhoto_Clicked(object sender, EventArgs e)
        {
            await CrossMedia.Current.Initialize();

            if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
            {
                await DisplayAlert("No Camera", ":( No camera avaialble.", "OK");
                return;
            }

            var file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
            {
                Directory = "Test",
                Name = $"{DateTime.UtcNow}.jpg",
                SaveToAlbum = true,
                CompressionQuality = 75,
                CustomPhotoSize = 50,
                PhotoSize = PhotoSize.MaxWidthHeight,
                MaxWidthHeight = 2000,
                DefaultCamera = CameraDevice.Front
            });

            if (file == null)
                return;

            await DisplayAlert("File Location", file.Path, "OK");

            image.Source = ImageSource.FromStream(() =>
            {
                var stream = file.GetStream();
                file.Dispose();
                return stream;
            });
        }

        async private void pickPhoto_Clicked(object sender, EventArgs e)
        {
            await CrossMedia.Current.Initialize();

            if (!CrossMedia.Current.IsPickPhotoSupported)
            {
                await DisplayAlert("Photos Not Supported", ":( Permission not granted to photos.", "OK");
                return;
            }

            var file = await CrossMedia.Current.PickPhotoAsync(new PickMediaOptions
            {
                PhotoSize = PhotoSize.Medium,

            });


            if (file == null)
                return;

            image.Source = ImageSource.FromStream(() =>
            {
                var stream = file.GetStream();
                file.Dispose();
                return stream;
            });
        }

        async private void takeVideo_Clicked(object sender, EventArgs e)
        {
            await CrossMedia.Current.Initialize();

            if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakeVideoSupported)
            {
                await DisplayAlert("No Camera", ":( No camera avaialble.", "OK");
                return;
            }

            var file = await CrossMedia.Current.TakeVideoAsync(new StoreVideoOptions
            {
                Name = $"{DateTime.UtcNow}.mp4",
                Directory = "Test",
            });

            if (file == null)
                return;

            MyVideo.Source = file.Path;

            await DisplayAlert("Video Recorded", "Location: " + file.Path, "OK");

            file.Dispose();
        }

        async private void pickVideo_Clicked(object sender, EventArgs e)
        {
            await CrossMedia.Current.Initialize();

            if (!CrossMedia.Current.IsPickVideoSupported)
            {
                await DisplayAlert("Videos Not Supported", ":( Permission not granted to videos.", "OK");
                return;
            }
            var file = await CrossMedia.Current.PickVideoAsync();

            if (file == null)
                return;

            MyVideo.Source = file.Path;
            
            await DisplayAlert("Video Selected", "Location: " + file.Path, "OK");
            file.Dispose();
        }
    }
}

Geluid afspelen

Plug-in toevoegen

Om geluid af te spelen moet u de plug-in Xam.Plugin.SimpleAudioPlayer toevoegen.

  • Klik rechts op de Solution om het NuGet package meteen te installeren voor alle projecten.
  • Vervolgens klikt u op Manage NuGet packages for Solution….
  • Klik op Browse.
  • Zoek naar Xam.Plugin.SimpleAudioPlayer, selecteer alle projecten en de laatste stabiele versie en klik op Install.

Geluidsbestanden toevoegen en afspelen

Het geluid kan worden toegevoegd in de daartoe voorzien map van het specifieke project:

  • Windows UWP en Android – plaats de audiobestanden in de Assets-map en zet de Build Action voor UWP op Content en voor Android op AndroidAsset.
  • Voor iOS – plaats de audiobestanden in de Resources-map folder aen zet de Build Action op BundleResource.
  • Gebruik onderstaande code om het geluid af te spelen.
var player = Plugin.SimpleAudioPlayer.CrossSimpleAudioPlayer.Current; 
player.Load("uwgeluidbestand.mp3");
player.Play();

Of plaats de audiobestanden in de Shared project en plaats de Build Action op Embedded Resource.

De code wordt nu:

var assembly = typeof(MainPage).GetTypeInfo().Assembly; 
Stream audioStream = assembly.GetManifestResourceStream("TestMediaPlugin.uwgeluidbestand.mp3"); 
 
var player = Plugin.SimpleAudioPlayer.CrossSimpleAudioPlayer.Current; 
player.Load(audioStream);
player.Play();

In var assembly = typeof(MainPage).GetTypeInfo().Assembly; verwijst MainPage naar de naam van het formulier.

In Stream audioStream = assembly.GetManifestResourceStream("TestMediaPlugin.uwgeluidbestand.mp3") verwijst TestMediaPlugin naar de naam van uw project.


Behandelde Basiscompetenties uit de module ICT Programmeren – Integratie externe functionaliteiten

  • IC BC024 – * kan zijn eigen deskundigheid inzake ICT opbouwen
  • IC BC232 – kan digitale tools gebruiken om modellen, simulaties en visualisaties van de realiteit te maken
  • IC BC254 – kan externe content integreren en structureren
  • IC BC258 – houdt rekening met regelgeving m.b.t. licenties voor het gebruik en de publicatie van broncode
  • IC BC288 – kan ICT-problemen oplossen

Geef een reactie

  • Abonneer je op deze website d.m.v. e-mail

    Voer je e-mailadres in om je in te schrijven op deze website en e-mailmeldingen te ontvangen van nieuwe berichten.