Skip to content

Commit

Permalink
Added recrod video/audio.
Browse files Browse the repository at this point in the history
Changed Android Handler
  • Loading branch information
Hector Alonso committed Apr 9, 2023
1 parent d1745df commit 8239450
Show file tree
Hide file tree
Showing 22 changed files with 2,205 additions and 380 deletions.
5 changes: 5 additions & 0 deletions Camera.MAUI.Test/Camera.MAUI.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="CommunityToolkit.Maui" Version="5.0.0" />
<PackageReference Include="CommunityToolkit.Maui.MediaElement" Version="1.0.2" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="7.0.0" />
</ItemGroup>

Expand All @@ -67,6 +69,9 @@
<MauiXaml Update="FullScreenPage.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
<MauiXaml Update="MVVM\MVVMPage.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
<MauiXaml Update="SizedPage.xaml">
<Generator>MSBuild:Compile</Generator>
</MauiXaml>
Expand Down
2 changes: 2 additions & 0 deletions Camera.MAUI.Test/FullScreenPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ private void CameraView_CamerasLoaded(object sender, EventArgs e)
if (cameraView.Cameras.Count > 0)
{
cameraView.Camera = cameraView.Cameras.First();
/*
MainThread.BeginInvokeOnMainThread(async () =>
{
if (await cameraView.StartCameraAsync() == CameraResult.Success)
Expand All @@ -21,6 +22,7 @@ private void CameraView_CamerasLoaded(object sender, EventArgs e)
playing = true;
}
});
*/
}
}
private async void Button_Clicked(object sender, EventArgs e)
Expand Down
183 changes: 183 additions & 0 deletions Camera.MAUI.Test/MVVM/CameraViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZXing;
using System.Windows.Markup;
using System.Collections.Specialized;
using Camera.MAUI.ZXingHelper;
using CommunityToolkit.Maui.Views;

namespace Camera.MAUI.Test;

public class CameraViewModel : INotifyPropertyChanged
{
private CameraInfo camera = null;
public CameraInfo Camera
{
get => camera;
set
{
camera = value;
OnPropertyChanged(nameof(Camera));
AutoStartPreview = false;
OnPropertyChanged(nameof(AutoStartPreview));
AutoStartPreview = true;
OnPropertyChanged(nameof(AutoStartPreview));
}
}
private ObservableCollection<CameraInfo> cameras = new();
public ObservableCollection<CameraInfo> Cameras
{
get => cameras;
set
{
cameras = value;
OnPropertyChanged(nameof(Cameras));
}
}
public int NumCameras
{
set
{
if (value > 0)
Camera = Cameras.First();
}
}
private MicrophoneInfo micro = null;
public MicrophoneInfo Microphone
{
get => micro;
set
{
micro = value;
OnPropertyChanged(nameof(Microphone));
}
}
private ObservableCollection<MicrophoneInfo> micros = new();
public ObservableCollection<MicrophoneInfo> Microphones
{
get => micros;
set
{
micros = value;
OnPropertyChanged(nameof(Microphones));
}
}
public int NumMicrophones
{
set
{
if (value > 0)
Microphone = Microphones.First();
}
}
public MediaSource VideoSource { get; set; }
public BarcodeDecodeOptions BarCodeOptions { get; set; }
public string BarcodeText { get; set; } = "No barcode detected";
public bool AutoStartPreview { get; set; } = false;
public bool AutoStartRecording { get; set; } = false;
private Result[] barCodeResults;
public Result[] BarCodeResults
{
get => barCodeResults;
set
{
barCodeResults = value;
if (barCodeResults != null && barCodeResults.Length > 0)
BarcodeText = barCodeResults[0].Text;
else
BarcodeText = "No barcode detected";
OnPropertyChanged(nameof(BarcodeText));
}
}
private bool takeSnapshot = false;
public bool TakeSnapshot
{
get => takeSnapshot;
set
{
takeSnapshot = value;
OnPropertyChanged(nameof(TakeSnapshot));
}
}
public float SnapshotSeconds { get; set; } = 0f;
public string Seconds
{
get => SnapshotSeconds.ToString();
set
{
if (float.TryParse(value, out float seconds))
{
SnapshotSeconds = seconds;
OnPropertyChanged(nameof(SnapshotSeconds));
}
}
}
public Command StartCamera { get; set; }
public Command StopCamera { get; set; }
public Command TakeSnapshotCmd { get; set; }
public string RecordingFile { get; set; }
public Command StartRecording { get; set; }
public Command StopRecording { get; set; }

public event PropertyChangedEventHandler PropertyChanged;

protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public CameraViewModel()
{
BarCodeOptions = new ZXingHelper.BarcodeDecodeOptions
{
AutoRotate = true,
PossibleFormats = { ZXing.BarcodeFormat.QR_CODE },
ReadMultipleCodes = false,
TryHarder = true,
TryInverted = true
};
OnPropertyChanged(nameof(BarCodeOptions));
StartCamera = new Command(() =>
{
AutoStartPreview = true;
OnPropertyChanged(nameof(AutoStartPreview));
});
StopCamera = new Command(() =>
{
AutoStartPreview = false;
OnPropertyChanged(nameof(AutoStartPreview));
});
TakeSnapshotCmd = new Command(() =>
{
TakeSnapshot = false;
TakeSnapshot = true;
});
#if IOS
RecordingFile = Path.Combine(FileSystem.Current.CacheDirectory, "Video.mov");
#else
RecordingFile = Path.Combine(FileSystem.Current.CacheDirectory, "Video.mp4");
#endif
OnPropertyChanged(nameof(RecordingFile));
StartRecording = new Command(() =>
{
AutoStartRecording = true;
OnPropertyChanged(nameof(AutoStartRecording));
});
StopRecording = new Command(() =>
{
AutoStartRecording = false;
OnPropertyChanged(nameof(AutoStartRecording));
VideoSource = MediaSource.FromFile(RecordingFile);
OnPropertyChanged(nameof(VideoSource));
});
OnPropertyChanged(nameof(StartCamera));
OnPropertyChanged(nameof(StopCamera));
OnPropertyChanged(nameof(TakeSnapshotCmd));
OnPropertyChanged(nameof(StartRecording));
OnPropertyChanged(nameof(StopRecording));
}
}
64 changes: 64 additions & 0 deletions Camera.MAUI.Test/MVVM/MVVMPage.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Camera.MAUI.Test.MVVMPage"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
xmlns:local="clr-namespace:Camera.MAUI.Test"
xmlns:cv="clr-namespace:Camera.MAUI;assembly=Camera.MAUI"
Title="MVVMPage" Background="white">
<ContentPage.BindingContext>
<local:CameraViewModel />
</ContentPage.BindingContext>
<ScrollView>
<Grid>
<VerticalStackLayout HorizontalOptions="Center" VerticalOptions="Center">
<cv:CameraView x:Name="cameraView" WidthRequest="300" HeightRequest="200" BarCodeOptions="{Binding BarCodeOptions}" BarCodeResults="{Binding BarCodeResults, Mode=OneWayToSource}"
Cameras="{Binding Cameras, Mode=OneWayToSource}" Camera="{Binding Camera}" AutoStartPreview="{Binding AutoStartPreview}" NumCamerasDetected="{Binding NumCameras, Mode=OneWayToSource}"
AutoSnapShotAsImageSource="True" AutoSnapShotFormat="PNG" TakeAutoSnapShot="{Binding TakeSnapshot}" AutoSnapShotSeconds="{Binding SnapshotSeconds}"
Microphones="{Binding Microphones, Mode=OneWayToSource}" Microphone="{Binding Microphone}" NumMicrophonesDetected="{Binding NumMicrophones, Mode=OneWayToSource}"
AutoRecordingFile="{Binding RecordingFile}" AutoStartRecording="{Binding AutoStartRecording}"/>
<HorizontalStackLayout HorizontalOptions="Center" Margin="5">
<Label Text="Select a camera:" VerticalOptions="Center" BackgroundColor="White" TextColor="Black"/>
<Picker VerticalOptions="Center" TextColor="Black" ItemsSource="{Binding Cameras}" SelectedItem="{Binding Camera,Mode=TwoWay}"/>
</HorizontalStackLayout>
<HorizontalStackLayout HorizontalOptions="Center" Margin="5">
<Label Text="Select a microphone:" VerticalOptions="Center" BackgroundColor="White" TextColor="Black"/>
<Picker VerticalOptions="Center" TextColor="Black" ItemsSource="{Binding Microphones}" SelectedItem="{Binding Microphone,Mode=TwoWay}"/>
</HorizontalStackLayout>
<HorizontalStackLayout HorizontalOptions="Center">
<Label Text="Mirrored" VerticalOptions="Center" TextColor="Black"/>
<CheckBox BindingContext="{x:Reference cameraView}" VerticalOptions="Center" Color="Black" IsChecked="{Binding MirroredImage}"/>
<Label Text="Torch" VerticalOptions="Center" TextColor="Black"/>
<CheckBox BindingContext="{x:Reference cameraView}" VerticalOptions="Center" Color="Black" IsChecked="{Binding TorchEnabled}"/>
<Label Text="QR Detec." VerticalOptions="Center" TextColor="Black"/>
<CheckBox BindingContext="{x:Reference cameraView}" VerticalOptions="Center" Color="Black" IsChecked="{Binding BarCodeDetectionEnabled}"/>
</HorizontalStackLayout>
<HorizontalStackLayout HorizontalOptions="Center">
<Label Text="AutoSnap freq: " VerticalOptions="Center" TextColor="Black"/>
<Entry WidthRequest="20" Keyboard="Numeric" TextColor="Black" Text="{Binding Seconds, Mode=TwoWay}" />
<Label Text="Take Autosnap" VerticalOptions="Center" TextColor="Black"/>
<CheckBox VerticalOptions="Center" Color="Black" IsChecked="{Binding TakeSnapshot, Mode=OneWayToSource}"/>
<Label Text="As ISource" VerticalOptions="Center" TextColor="Black"/>
<CheckBox BindingContext="{x:Reference cameraView}" IsChecked="{Binding AutoSnapShotAsImageSource}" VerticalOptions="Center" Color="Black"/>
</HorizontalStackLayout>
<HorizontalStackLayout HorizontalOptions="Center" Margin="2" Spacing="2">
<Label Text="Zoom" VerticalOptions="Center" TextColor="Black"/>
<Stepper BindingContext="{x:Reference cameraView}" Minimum="{Binding MinZoomFactor}" Maximum="7" Increment="0.5" Value="{Binding ZoomFactor,Mode=TwoWay}" />
</HorizontalStackLayout>
<HorizontalStackLayout HorizontalOptions="Center" Margin="5">
<Button Text="Start Camera" Command="{Binding StartCamera}" />
<Button Text="Stop Camera" Command="{Binding StopCamera}" />
<Button Text="Take Photo" Command="{Binding TakeSnapshotCmd}" />
</HorizontalStackLayout>
<HorizontalStackLayout HorizontalOptions="Center" Margin="5">
<Button Text="Start Record" Command="{Binding StartRecording}" />
<Button Text="Stop Record" Command="{Binding StopRecording}" />
</HorizontalStackLayout>
<Label Text="{Binding BarcodeText}" TextColor="Black" FontAttributes="Bold" HorizontalOptions="Center" />
<Image BindingContext="{x:Reference cameraView}" Source="{Binding SnapShot}" Aspect="AspectFit" WidthRequest="250" HeightRequest="100" HorizontalOptions="Center" />
<toolkit:MediaElement Source="{Binding VideoSource}" ShouldAutoPlay="False" ShouldShowPlaybackControls="True" HeightRequest="300" WidthRequest="200" />
</VerticalStackLayout>
</Grid>
</ScrollView>

</ContentPage>
9 changes: 9 additions & 0 deletions Camera.MAUI.Test/MVVM/MVVMPage.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Camera.MAUI.Test;

public partial class MVVMPage : ContentPage
{
public MVVMPage()
{
InitializeComponent();
}
}
1 change: 1 addition & 0 deletions Camera.MAUI.Test/MainPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<ScrollView>
<Grid>
<VerticalStackLayout HorizontalOptions="Center" VerticalOptions="Center">
<Button HorizontalOptions="Center" Text="Go to MVVM Cam" Clicked="Button_Clicked_2" Margin="5"/>
<Button HorizontalOptions="Center" Text="Go to Parameters Cam" Clicked="Button_Clicked" Margin="5"/>
<Button HorizontalOptions="Center" Text="Go to Fullscreen Cam" Clicked="Button2_Clicked" Margin="5"/>
<Button HorizontalOptions="Center" Text="Go to Code generation" Clicked="Button_Clicked_1" Margin="5"/>
Expand Down
5 changes: 5 additions & 0 deletions Camera.MAUI.Test/MainPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,9 @@ private async void Button_Clicked_1(object sender, EventArgs e)
{
await Navigation.PushAsync(new BarcodeGenerationPage());
}

private async void Button_Clicked_2(object sender, EventArgs e)
{
await Navigation.PushAsync(new MVVMPage());
}
}
7 changes: 6 additions & 1 deletion Camera.MAUI.Test/MauiProgram.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using Microsoft.Extensions.Logging;
using Camera.MAUI;
using Microsoft.Maui.Hosting;
using CommunityToolkit.Maui;

namespace Camera.MAUI.Test
{
public static class MauiProgram
Expand All @@ -9,6 +12,8 @@ public static MauiApp CreateMauiApp()
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.UseMauiCommunityToolkit()
.UseMauiCommunityToolkitMediaElement()
.UseMauiCameraView()
.ConfigureFonts(fonts =>
{
Expand All @@ -19,7 +24,7 @@ public static MauiApp CreateMauiApp()
#if DEBUG
builder.Logging.AddDebug();
#endif

builder.Services.AddSingleton<CameraViewModel>();
return builder.Build();
}
}
Expand Down
2 changes: 2 additions & 0 deletions Camera.MAUI.Test/Platforms/Android/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.RECORD_VIDEO" />
</manifest>
2 changes: 2 additions & 0 deletions Camera.MAUI.Test/Platforms/iOS/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
<string>Assets.xcassets/appicon.appiconset</string>
<key>NSCameraUsageDescription</key>
<string>This app needs access to the camera to take photos and scan QR codes</string>
<key>NSMicrophoneUsageDescription</key>
<string>This app needs access to the microphone for record videos</string>
<key>CFBundleIdentifier</key>
<string></string>
</dict>
Expand Down
Loading

0 comments on commit 8239450

Please sign in to comment.