CardVideoDisplayContainerContext class

Configuration options for the CardVideoDisplay widget.

Defines video stream rendering behavior, styling, and builder hooks for a WebRTC video player. This component handles RTCVideoRenderer lifecycle, stream attachment, video track polling, and layered content (placeholder, video, overlay).

Properties:

  • remoteProducerId: Unique identifier for the remote producer (used for tracking/logging)
  • eventType: Type of video event (e.g., EventType.conference, EventType.webinar) for context-specific behavior
  • forceFullDisplay: Video scaling mode (true = cover/crop to fill; false = contain/letterbox)
  • videoStream: MediaStream containing video tracks to render (null = no video)
  • backgroundColor: Background color visible when no video or during loading (defaults to Colors.transparent)
  • doMirror: Horizontal flip for local camera preview (true = mirror effect; false = normal)
  • padding: Inner padding around video content
  • margin: Outer margin around container
  • decoration: BoxDecoration for borders, gradients, shadows (merged with backgroundColor)
  • clipBehavior: Clipping strategy (auto-detected from decoration if null: antiAlias for rounded corners, none otherwise)
  • alignment: Content alignment within container (defaults to Alignment.center)
  • constraints: Size constraints for container (e.g., BoxConstraints.expand(), BoxConstraints.tightFor(width: 320))
  • placeholder: Widget shown when streamReady=false (e.g., loading spinner, avatar, "Video Off" text)
  • overlay: Widget always layered on top of video (e.g., name badge, audio indicator, controls)
  • containerBuilder: Hook to wrap Container with dimensions/styling (receives child content, streamReady state)
  • videoBuilder: Hook to customize RTCVideoView rendering (receives renderer, streamReady state)
  • maintainRendererOnNullStream: Keep last frame when stream becomes null (true = retain; false = clear srcObject)
  • streamPollInterval: Polling interval for checking video track availability when stream has no tracks (defaults to 120ms)

Stream Attachment Logic:

if (videoStream == null) {
  if (!maintainRendererOnNullStream) {
    renderer.srcObject = null; // clear video
  }
  streamReady = false;
} else if (videoStream.getVideoTracks().isNotEmpty) {
  renderer.srcObject = videoStream; // attach stream
  streamReady = true;
} else {
  streamReady = false;
  startPolling(); // wait for tracks to become available
}

Video Scaling Modes:

  • forceFullDisplay = true: RTCVideoViewObjectFit.RTCVideoViewObjectFitCover (crop to fill, no letterbox)
  • forceFullDisplay = false: RTCVideoViewObjectFit.RTCVideoViewObjectFitContain (scale to fit, may letterbox)

Layered Content Structure:

Stack
  ├─ Positioned.fill → RTCVideoView (always present)
  ├─ Positioned.fill → placeholder (if streamReady=false and placeholder!=null)
  └─ Positioned.fill → overlay (if overlay!=null, always visible)

Builder Hook Flow:

1. Build RTCVideoView with mirror/objectFit
2. videoBuilder?(renderer, streamReady) → videoSurface
3. Create Stack with videoSurface + placeholder + overlay
4. Wrap in Container with decoration/padding/alignment
5. containerBuilder?(content, streamReady) → final widget

Common Configurations:

// 1. Basic remote participant video (contain mode)
CardVideoDisplayOptions(
  remoteProducerId: participant.videoId,
  eventType: EventType.conference,
  forceFullDisplay: false, // contain with letterbox
  videoStream: participant.stream,
  backgroundColor: Colors.black,
  placeholder: Center(
    child: CircularProgressIndicator(),
  ),
)

// 2. Local camera preview (mirrored, cover mode)
CardVideoDisplayOptions(
  remoteProducerId: 'local_camera',
  eventType: EventType.conference,
  forceFullDisplay: true, // cover/crop
  videoStream: localStream,
  backgroundColor: Colors.grey[900]!,
  doMirror: true, // horizontal flip
  decoration: BoxDecoration(
    borderRadius: BorderRadius.circular(12),
    border: Border.all(color: Colors.blue, width: 2),
  ),
  overlay: Positioned(
    top: 8,
    right: 8,
    child: Icon(Icons.videocam, color: Colors.white),
  ),
)

// 3. Screenshare display with custom placeholder
CardVideoDisplayOptions(
  remoteProducerId: presenter.screenId,
  eventType: EventType.conference,
  forceFullDisplay: false, // contain for aspect ratio preservation
  videoStream: screenshareStream,
  backgroundColor: Colors.black,
  placeholder: Center(
    child: Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        Icon(Icons.screen_share, size: 64, color: Colors.white54),
        SizedBox(height: 16),
        Text('Waiting for screenshare...', style: TextStyle(color: Colors.white54)),
      ],
    ),
  ),
  maintainRendererOnNullStream: true, // keep last frame
)

// 4. Picture-in-picture mini player
CardVideoDisplayOptions(
  remoteProducerId: participant.videoId,
  eventType: EventType.conference,
  forceFullDisplay: true,
  videoStream: participant.stream,
  backgroundColor: Colors.black,
  doMirror: false,
  constraints: BoxConstraints.tightFor(width: 160, height: 120),
  decoration: BoxDecoration(
    borderRadius: BorderRadius.circular(8),
    boxShadow: [BoxShadow(color: Colors.black38, blurRadius: 4)],
  ),
  overlay: Positioned(
    bottom: 4,
    left: 4,
    child: Container(
      padding: EdgeInsets.symmetric(horizontal: 6, vertical: 2),
      decoration: BoxDecoration(
        color: Colors.black54,
        borderRadius: BorderRadius.circular(4),
      ),
      child: Text(
        participant.name,
        style: TextStyle(color: Colors.white, fontSize: 10),
      ),
    ),
  ),
)

Typical Use Cases:

  • Remote participant video rendering
  • Local camera preview with mirror effect
  • Screenshare display
  • Picture-in-picture mini player
  • Video tiles in gallery grid Provides context data when building a custom container for CardVideoDisplay.

Constructors

CardVideoDisplayContainerContext({required CardVideoDisplayOptions options, required bool streamReady, required Widget child, required Widget defaultContainer})

Properties

child Widget
final
defaultContainer Widget
final
hashCode int
The hash code for this object.
no setterinherited
options CardVideoDisplayOptions
final
runtimeType Type
A representation of the runtime type of the object.
no setterinherited
streamReady bool
final

Methods

noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toString() String
A string representation of this object.
inherited

Operators

operator ==(Object other) bool
The equality operator.
inherited