30 VideoSource source, Func<IVideoPlayer>? playerFactory =
null,
string? nickname =
null)
35 ArgumentNullException.ThrowIfNull(view);
36 ArgumentNullException.ThrowIfNull(source);
38 Video =
new DirectVideo(() => player = (playerFactory ?? DefaultPlayerFactory)(),
39 source, renderSurfaceHost, view, bounds, $
"{Nickname}.video");
58 VideoSource source, Func<IVideoPlayer>? playerFactory =
null,
string? nickname =
null)
63 ArgumentNullException.ThrowIfNull(sceneLayer);
64 ArgumentNullException.ThrowIfNull(source);
66 Video =
new DirectVideo(() => player = (playerFactory ?? DefaultPlayerFactory)(),
67 source, renderSurfaceHost, sceneLayer, bounds, $
"{Nickname}.video");
87 : this(renderSurfaceHost, view, bounds, source, OwnedPlayerFactory(player), nickname) { }
98 : this(renderSurfaceHost, sceneLayer, bounds, source, OwnedPlayerFactory(player), nickname) { }
111 ValidateBounds(bounds);
115 else Video.WorldBounds = bounds;
127 public void Seek(TimeSpan position) =>
Video.Seek(position);
137 public bool Loop {
get =>
Video.Loop;
set => Video.Loop = value; }
156 public event EventHandler
Started { add => _player.Started += value;
remove => _player.Started -= value; }
158 public event EventHandler
Paused { add => _player.Paused += value;
remove => _player.Paused -= value; }
160 public event EventHandler
Stopped { add => _player.Stopped += value;
remove => _player.Stopped -= value; }
162 public event EventHandler
Ended { add => _player.Ended += value;
remove => _player.Ended -= value; }
166 add => _player.StateChanged += value;
167 remove => _player.StateChanged -= value;
170 private void InitializeVideo()
172 try {
Add(
Video, keepCurrentOffset:
false, explicitLocalOffsetPx: Vector2.Zero); }
173 catch {
Video.Dispose();
throw; }
179 private static IVideoPlayer DefaultPlayerFactory() =>
new VlcVideoPlayer();
181 private static Func<IVideoPlayer> OwnedPlayerFactory(IVideoPlayer player)
183 ArgumentNullException.ThrowIfNull(player);
187 private static Rectangle ValidateBounds(Rectangle bounds)
189 if (bounds.Width <= 0 || bounds.Height <= 0)
190 throw new ArgumentOutOfRangeException(nameof(bounds), bounds,
"Video widget size must be positive.");
SceneLayer? SceneLayer
Gets the scene layer shared by all children in scene-layer mode.
DirectComposite SetLocalOffset(IDirectCompositeChild child, Vector2 newLocalOffsetPx)
Changes one child's local offset and reapplies its position.
View? View
Gets the view shared by all children in view mode.
virtual DirectComposite Add(IDirectCompositeChild child, bool keepCurrentOffset=true, Vector2? explicitLocalOffsetPx=null)
Adds a composite-compatible direct drawable as a child.
void SetPosition(Vector2 position)
Sets the composite anchor and repositions all children from their stored offsets.
DirectDrawingMode Mode
Gets the coordinate mode shared by the composite and its children.
Draws video frames provided by IVideoPlayer onto the backbuffer. Audio is handled by the IVideoPlayer...
Represents a base class for hosting a render surface, providing functionality for managing rendering ...
A URI, borrowed/owned stream, or GAF asset to open with a video backend.
Defines the contract for a video player that can play, pause, stop, and seek video content.
@ Rectangle
Particles are spawned uniformly within a rectangular area. This is the default distribution.
DirectDrawingMode
Specifies where direct drawing operations are applied within the rendering pipeline.
@ View
Performs direct drawing at the view level using screen-space coordinates.
StretchMode
Defines how video content should be stretched or scaled to fit within its display bounds.
record VideoMetadata(VideoMetadataStatus Status, bool HasAudio, TimeSpan Duration)
An immutable metadata snapshot. Values are authoritative only when status is Ready.