Add project files.
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0-windows10.0.18362.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="7.0.0-rc.2.22472.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="7.0.0-rc.2.22472.3" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Media\Capture\Capture.csproj" />
|
||||
<ProjectReference Include="..\Core\Core.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,19 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace TheXamlGuy.Framework.Camera;
|
||||
|
||||
public class CameraBuilder : ICameraBuilder
|
||||
{
|
||||
private readonly List<ICameraBuilderConfiguration> configurations = new();
|
||||
|
||||
public IReadOnlyCollection<ICameraBuilderConfiguration> Configurations => new ReadOnlyCollection<ICameraBuilderConfiguration>(configurations);
|
||||
|
||||
public ICameraBuilderConfiguration<TConfiguration> Add<TConfiguration>(IConfiguration configuration) where TConfiguration : IRemoteCameraConfiguration, new()
|
||||
{
|
||||
CameraBuilderConfiguration<TConfiguration>? builderConfiguration = new(configuration);
|
||||
configurations.Add(builderConfiguration);
|
||||
|
||||
return builderConfiguration;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace TheXamlGuy.Framework.Camera;
|
||||
|
||||
public class CameraBuilderConfiguration<TConfiguration> : ICameraBuilderConfiguration<TConfiguration> where TConfiguration : INamedCameraConfiguration, new()
|
||||
{
|
||||
private readonly IConfiguration configuration;
|
||||
|
||||
public CameraBuilderConfiguration(IConfiguration configuration)
|
||||
{
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
public Func<IServiceProvider, ICameraContext> Factory => (IServiceProvider provider) => provider.GetService<ICameraFactory>()!.Create(configuration.Get<TConfiguration>());
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using TheXamlGuy.Framework.Core;
|
||||
using TheXamlGuy.Media.Capture;
|
||||
|
||||
namespace TheXamlGuy.Framework.Camera;
|
||||
|
||||
public class CameraContext : ICameraContext
|
||||
{
|
||||
private readonly IEventAggregator eventAggregator;
|
||||
private ILowLagPhotoCapture? lowLagPhotoCapture;
|
||||
private IMediaCapture? mediaCapture;
|
||||
|
||||
public CameraContext(IEventAggregator eventAggregator)
|
||||
{
|
||||
this.eventAggregator = eventAggregator;
|
||||
}
|
||||
|
||||
public async Task InitializeAsync()
|
||||
{
|
||||
IReadOnlyList<IMediaFrameSource> sourceGroups = await MediaFrameSource.FindAllAsync();
|
||||
if (sourceGroups.FirstOrDefault(x => x.DisplayName.Contains("USB", StringComparison.InvariantCultureIgnoreCase)) is IMediaFrameSource source)
|
||||
{
|
||||
if (source.SupportedFormats.OrderByDescending(x => x.Size.Width & x.Size.Height).FirstOrDefault() is MediaFrameFormat bestSupportedFormat)
|
||||
{
|
||||
source.SetFormat(bestSupportedFormat);
|
||||
}
|
||||
|
||||
MediaCaptureInitializationSettings settings = new()
|
||||
{
|
||||
Source = source
|
||||
};
|
||||
|
||||
mediaCapture = new MediaCapture();
|
||||
mediaCapture.Initialize(settings);
|
||||
|
||||
lowLagPhotoCapture = await mediaCapture.PrepareLowLagPhotoCaptureAsync();
|
||||
eventAggregator.SubscribeUI<Capture>(OnCapture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private async void OnCapture(Capture args)
|
||||
{
|
||||
if (lowLagPhotoCapture is not null)
|
||||
{
|
||||
await lowLagPhotoCapture.CaptureAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using TheXamlGuy.Framework.Core;
|
||||
|
||||
namespace TheXamlGuy.Framework.Camera;
|
||||
|
||||
public class CameraFactory : ICameraFactory
|
||||
{
|
||||
private readonly Dictionary<INamedCameraConfiguration, ICameraContext> cache = new();
|
||||
private readonly IServiceFactory factory;
|
||||
|
||||
public CameraFactory(IServiceFactory factory)
|
||||
{
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
public ICameraContext Create(INamedCameraConfiguration configuration)
|
||||
{
|
||||
if (cache.TryGetValue(configuration, out ICameraContext? context))
|
||||
{
|
||||
return context;
|
||||
}
|
||||
|
||||
if (configuration is IRemoteCameraConfiguration)
|
||||
{
|
||||
context = factory.Create<RemoteCameraContext>();
|
||||
}
|
||||
else
|
||||
{
|
||||
context = factory.Create<CameraContext>();
|
||||
}
|
||||
|
||||
cache.Add(configuration, context);
|
||||
return context;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
namespace TheXamlGuy.Framework.Camera;
|
||||
|
||||
public record Capture;
|
||||
@@ -0,0 +1,12 @@
|
||||
using System.Drawing;
|
||||
|
||||
namespace TheXamlGuy.Framework.Camera;
|
||||
|
||||
public record Captured
|
||||
{
|
||||
public Bitmap? Photo { get; init; }
|
||||
|
||||
public int Width { get; init; }
|
||||
|
||||
public int Height { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace TheXamlGuy.Framework.Camera;
|
||||
|
||||
public interface ICameraBuilder
|
||||
{
|
||||
IReadOnlyCollection<ICameraBuilderConfiguration> Configurations { get; }
|
||||
|
||||
ICameraBuilderConfiguration<TConfiguration> Add<TConfiguration>(IConfiguration configuration) where TConfiguration : IRemoteCameraConfiguration, new();
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace TheXamlGuy.Framework.Camera;
|
||||
|
||||
public interface ICameraBuilderConfiguration
|
||||
{
|
||||
Func<IServiceProvider, ICameraContext> Factory { get; }
|
||||
}
|
||||
|
||||
public interface ICameraBuilderConfiguration<TConfiguration> : ICameraBuilderConfiguration where TConfiguration : INamedCameraConfiguration, new()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
namespace TheXamlGuy.Framework.Camera;
|
||||
|
||||
public interface ICameraConfiguration : INamedCameraConfiguration
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using TheXamlGuy.Framework.Core;
|
||||
|
||||
namespace TheXamlGuy.Framework.Camera;
|
||||
|
||||
public interface ICameraContext : IInitializer
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace TheXamlGuy.Framework.Camera;
|
||||
|
||||
public interface ICameraFactory
|
||||
{
|
||||
ICameraContext Create(INamedCameraConfiguration configuration);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace TheXamlGuy.Framework.Camera;
|
||||
|
||||
public static class IHostBuilderExtensions
|
||||
{
|
||||
public static IHostBuilder ConfigureCamera(this IHostBuilder hostBuilder, Action<HostBuilderContext, ICameraBuilder> builderDelegate)
|
||||
{
|
||||
hostBuilder.ConfigureServices((hostBuilderContext, serviceCollection) =>
|
||||
{
|
||||
CameraBuilder? builder = new();
|
||||
|
||||
builderDelegate.Invoke(hostBuilderContext, builder);
|
||||
serviceCollection.TryAddSingleton<ICameraFactory, CameraFactory>();
|
||||
|
||||
foreach (ICameraBuilderConfiguration configuration in builder.Configurations)
|
||||
{
|
||||
serviceCollection.AddSingleton(provider => configuration.Factory.Invoke(provider));
|
||||
}
|
||||
});
|
||||
|
||||
return hostBuilder;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace TheXamlGuy.Framework.Camera;
|
||||
|
||||
public interface INamedCameraConfiguration
|
||||
{
|
||||
string Name { get; }
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
namespace TheXamlGuy.Framework.Camera;
|
||||
|
||||
public interface IRemoteCameraConfiguration : INamedCameraConfiguration
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace TheXamlGuy.Framework.Camera;
|
||||
|
||||
public class RemoteCameraConfiguration : IRemoteCameraConfiguration
|
||||
{
|
||||
[NotNull]
|
||||
public string? Name { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using TheXamlGuy.Framework.Core;
|
||||
using TheXamlGuy.Media.Capture;
|
||||
|
||||
namespace TheXamlGuy.Framework.Camera;
|
||||
|
||||
public class RemoteCameraContext : ICameraContext
|
||||
{
|
||||
private readonly IEventAggregator eventAggregator;
|
||||
private ILowLagPhotoCapture? lowLagPhotoCapture;
|
||||
private IRemoteMediaCapture? mediaCapture;
|
||||
|
||||
public RemoteCameraContext(IEventAggregator eventAggregator)
|
||||
{
|
||||
this.eventAggregator = eventAggregator;
|
||||
}
|
||||
|
||||
public async Task InitializeAsync()
|
||||
{
|
||||
IReadOnlyList<IRemoteMediaFrameSource> sourceGroups = await RemoteMediaFrameSource.FindAllAsync();
|
||||
if (sourceGroups.FirstOrDefault(x => x.DisplayName.Contains("DSC-HX60", StringComparison.InvariantCultureIgnoreCase)) is IRemoteMediaFrameSource source)
|
||||
{
|
||||
RemoteMediaCaptureInitializationSettings settings = new()
|
||||
{
|
||||
Source = source
|
||||
};
|
||||
|
||||
mediaCapture = new RemoteMediaCapture();
|
||||
mediaCapture.Initialize(settings);
|
||||
|
||||
lowLagPhotoCapture = await mediaCapture.PrepareLowLagPhotoCaptureAsync();
|
||||
eventAggregator.SubscribeUI<Capture>(OnCapture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private async void OnCapture(Capture args)
|
||||
{
|
||||
if (lowLagPhotoCapture is not null)
|
||||
{
|
||||
if (await lowLagPhotoCapture.CaptureAsync() is CapturedPhoto capturedPhoto)
|
||||
{
|
||||
eventAggregator.Publish(new Captured
|
||||
{
|
||||
Photo = capturedPhoto.Photo,
|
||||
Width = capturedPhoto.Width,
|
||||
Height = capturedPhoto.Height
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user