TASK 3 milestone 1: webcam capture (MediaCapture CPU-first, CameraManager refcount, picker, clip/mirror, schema v2, tests)

This commit is contained in:
2026-08-06 14:35:34 -07:00
parent d97b5d375c
commit 98cdc4b3f4
23 changed files with 1099 additions and 40 deletions
+56
View File
@@ -1,6 +1,7 @@
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using ytLive.Helpers;
namespace ytLive.Models;
@@ -15,6 +16,12 @@ public enum SourceType
TextOverlay
}
public enum ClipShape
{
Traditional,
Round
}
public class Source : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
@@ -52,6 +59,54 @@ public class Source : INotifyPropertyChanged
private string? _deviceId;
public string? DeviceId { get => _deviceId; set => Set(ref _deviceId, value); }
// Webcam live preview: the shared WriteableBitmap owned by CameraManager.
private WriteableBitmap? _videoImageSource;
public WriteableBitmap? VideoImageSource
{
get => _videoImageSource;
set
{
if (Set(ref _videoImageSource, value))
Raise(nameof(DisplaySource));
}
}
private ClipShape _clipShape = ClipShape.Traditional;
public ClipShape ClipShape
{
get => _clipShape;
set
{
if (Set(ref _clipShape, value))
Raise(nameof(ShapeButtonText));
}
}
private bool _isMirrored;
public bool IsMirrored
{
get => _isMirrored;
set
{
if (Set(ref _isMirrored, value))
{
Raise(nameof(MirrorScale));
Raise(nameof(MirrorButtonText));
}
}
}
public double MirrorScale => IsMirrored ? -1 : 1;
/// <summary>Mirror toggle label (mirrored → "Unmirror").</summary>
public string MirrorButtonText => IsMirrored ? "Unmirror" : "Mirror";
/// <summary>Clip-shape toggle label (round → "Rect").</summary>
public string ShapeButtonText => ClipShape == ClipShape.Round ? "Rect" : "Round";
/// <summary>What the preview shows: static image for image/background, live frames for webcam.</summary>
public ImageSource? DisplaySource => Type == SourceType.Webcam ? _videoImageSource : _imageSource;
// Image (asset stored in the layout database)
private string? _assetId;
private ImageSource? _imageSource;
@@ -65,6 +120,7 @@ public class Source : INotifyPropertyChanged
{
_imageSource = ImageCache.Get(value ?? string.Empty);
Raise(nameof(ImageSource));
Raise(nameof(DisplaySource));
}
}
}