UNPKG

mediasfu-reactnative-expo

Version:

mediasfu-reactnative-expo – Expo-managed React Native WebRTC SDK for video conferencing, webinars, live streaming, broadcast, screen sharing, whiteboard, chat, recording, live subtitles, translation, and AI agent rooms on iOS, Android, and web. Prebuilt r

306 lines (305 loc) 11.9 kB
import React from "react"; import { StyleProp, ViewStyle, ImageStyle } from "react-native"; import { Socket } from "socket.io-client"; import { EventType, ShowAlert, CoHostResponsibility, Participant, AudioDecibels, MediaStream, CustomVideoCardType } from "../../@types/types"; /** * Interface defining the parameters required by the VideoCard component. * * These parameters provide the context and state needed for video display, * participant management, and media controls. * * @interface VideoCardParameters * @property {Socket} socket - Socket.io client instance for real-time communication * @property {string} roomName - Name/ID of the current room session * @property {CoHostResponsibility[]} coHostResponsibility - Array of responsibilities assigned to co-hosts * @property {ShowAlert} [showAlert] - Optional function to display alerts/notifications * @property {string} coHost - User ID of the co-host * @property {Participant[]} participants - Array of all participants in the session * @property {string} member - Current user's member ID * @property {string} islevel - Current user's level/role (e.g., '0', '1', '2') * @property {AudioDecibels[]} audioDecibels - Array of audio level data for waveform visualization * @property {() => VideoCardParameters} getUpdatedAllParams - Function to retrieve latest parameter state */ export interface VideoCardParameters { socket: Socket; roomName: string; coHostResponsibility: CoHostResponsibility[]; showAlert?: ShowAlert; coHost: string; participants: Participant[]; member: string; islevel: string; audioDecibels: AudioDecibels[]; getUpdatedAllParams: () => VideoCardParameters; [key: string]: any; } /** * Interface defining the options for the VideoCard component. * * VideoCard displays a participant's video stream with optional controls, * info overlay, and audio visualization waveform. * * @interface VideoCardOptions * * **Core Display Properties:** * @property {string} name - Participant's display name * @property {string} remoteProducerId - Producer ID for the video stream * @property {MediaStream | null} videoStream - Video MediaStream object (null for screenshare or when video is off) * @property {Participant} participant - Complete participant object with metadata * @property {EventType} eventType - Type of event ('conference', 'webinar', 'broadcast', etc.) * @property {boolean} forceFullDisplay - Whether to force fullscreen display mode * * **Styling Properties:** * @property {StyleProp<ViewStyle>} [customStyle] - Custom styles for the card container * @property {object} [style] - Additional style object for the container * @property {string} [backgroundColor] - Background color (default: '#2c678f') * @property {string} [barColor] - Color of the audio waveform bars (default: 'white') * @property {string} [textColor] - Color of text overlays (default: 'white') * @property {boolean} [doMirror] - Whether to mirror the video horizontally * * **Image/Avatar Properties:** * @property {string} [imageSource] - URI for participant's avatar image * @property {boolean} [roundedImage] - Whether to display avatar with rounded corners * @property {StyleProp<ImageStyle>} [imageStyle] - Custom styles for the avatar image * * **Controls & Info Properties:** * @property {boolean} [showControls] - Whether to show media control buttons * @property {boolean} [showInfo] - Whether to show participant info overlay * @property {React.ReactNode} [videoInfoComponent] - Custom component for info overlay * @property {React.ReactNode} [videoControlsComponent] - Custom component for controls * @property {"topLeft" | "topRight" | "bottomLeft" | "bottomRight"} [controlsPosition] - Position of controls overlay * @property {"topLeft" | "topRight" | "bottomLeft" | "bottomRight"} [infoPosition] - Position of info overlay * * **Audio Visualization:** * @property {AudioDecibels[]} [audioDecibels] - Audio level data for waveform animation * * **State Parameters:** * @property {VideoCardParameters} parameters - State and context parameters for the card * * **Custom UI Override:** * @property {CustomVideoCardType} [customVideoCard] - Custom render function for complete card replacement. * When provided, this function receives all VideoCardOptions and returns a custom JSX.Element. * This allows full control over the video card's appearance and behavior. * * **Advanced Render Overrides:** * @property {(options: { defaultContent: React.ReactNode; dimensions: { width: number; height: number }}) => React.ReactNode} [renderContent] * Function to wrap or replace the default card content while preserving container * @property {(options: { defaultContainer: React.ReactNode; dimensions: { width: number; height: number }}) => React.ReactNode} [renderContainer] * Function to wrap or replace the entire card container */ export interface VideoCardOptions { customStyle?: StyleProp<ViewStyle>; name: string; barColor?: string; textColor?: string; imageSource?: string; roundedImage?: boolean; imageStyle?: StyleProp<ImageStyle>; remoteProducerId: string; eventType: EventType; forceFullDisplay: boolean; videoStream: MediaStream | null; showControls?: boolean; showInfo?: boolean; videoInfoComponent?: React.ReactNode; videoControlsComponent?: React.ReactNode; controlsPosition?: "topLeft" | "topRight" | "bottomLeft" | "bottomRight"; infoPosition?: "topLeft" | "topRight" | "bottomLeft" | "bottomRight"; participant: Participant; backgroundColor?: string; audioDecibels?: AudioDecibels[]; doMirror?: boolean; liveSubtitleText?: string; showSubtitles?: boolean; parameters: VideoCardParameters; customVideoCard?: CustomVideoCardType; /** * Optional custom style to apply to the container. */ style?: object; /** * Optional function to render custom content, receiving the default content and dimensions. */ renderContent?: (options: { defaultContent: React.ReactNode; dimensions: { width: number; height: number; }; }) => React.ReactNode; /** * Optional function to render a custom container, receiving the default container and dimensions. */ renderContainer?: (options: { defaultContainer: React.ReactNode; dimensions: { width: number; height: number; }; }) => React.ReactNode; } export type VideoCardType = (options: VideoCardOptions) => JSX.Element; /** * VideoCard - Displays a participant's video stream with controls, info overlay, and audio waveform * * VideoCard is a comprehensive React Native component that renders a participant's video feed * with real-time audio visualization (animated waveform), optional media controls, and participant * information overlay. It supports multiple display modes, custom styling, and flexible positioning. * * **Key Features:** * - Real-time video stream rendering with MediaStream support * - Animated audio waveform visualization based on decibel levels * - Optional control buttons for muting/video toggling * - Participant info overlay with customizable positioning * - Avatar fallback when video is off * - Horizontal mirroring support * - Responsive layout with force fullscreen mode * * **UI Customization - Two-Tier Override System:** * * 1. **Custom Render Function** (via `customVideoCard` prop): * Pass a function that receives all VideoCardOptions and returns custom JSX. * Provides complete control over rendering logic and appearance. * * 2. **Component Override** (via `uiOverrides.videoCardComponent`): * Replace the entire VideoCard component while preserving MediaSFU's orchestration. * Useful when you want a different component implementation. * * **Advanced Render Overrides:** * - `renderContent`: Wrap/modify the card's inner content while keeping container * - `renderContainer`: Wrap/modify the entire card container * * @component * @param {VideoCardOptions} props - Configuration options for the VideoCard component * * @returns {JSX.Element} Rendered video card with stream, controls, and waveform * * @example * // Basic usage - Display participant video with default styling * import React from 'react'; * import { VideoCard } from 'mediasfu-reactnative-expo'; * import { Socket } from 'socket.io-client'; * * const socket = Socket('https://example.com'); * * function ParticipantGrid() { * return ( * <VideoCard * name="John Doe" * remoteProducerId="producer_123" * eventType="conference" * forceFullDisplay={false} * videoStream={participantStream} * participant={{ * name: 'John Doe', * id: '123', * videoOn: true, * muted: false, * }} * parameters={{ * socket, * roomName: 'room1', * coHostResponsibility: [], * audioDecibels: [], * participants: [{ name: 'John Doe', id: '123', videoOn: true, muted: false }], * member: '123', * islevel: '1', * coHost: 'coHostId', * getUpdatedAllParams: () => ({ ...params }), * }} * backgroundColor="#2c678f" * showControls={true} * showInfo={true} * barColor="white" * textColor="white" * /> * ); * } * * @example * // Custom styled video card with mirroring and custom colors * <VideoCard * name="Jane Smith" * remoteProducerId="producer_456" * eventType="webinar" * forceFullDisplay={true} * videoStream={selfStream} * participant={currentParticipant} * parameters={sessionParams} * backgroundColor="#1a1a2e" * barColor="#16213e" * textColor="#eaeaea" * doMirror={true} * showControls={true} * showInfo={true} * controlsPosition="bottomRight" * infoPosition="topLeft" * customStyle={{ borderRadius: 12, margin: 8 }} * /> * * @example * // Custom video card with custom render function * import { View, Text } from 'react-native'; * * const customVideoCard = (options: VideoCardOptions) => { * const { name, participant, videoStream } = options; * * return ( * <View style={{ backgroundColor: '#000', padding: 10 }}> * <Text style={{ color: '#fff', fontSize: 18 }}>{name}</Text> * {videoStream ? ( * <Text>Video Active</Text> * ) : ( * <Text>Video Off</Text> * )} * {participant.muted && <Text style={{ color: 'red' }}>Muted</Text>} * </View> * ); * }; * * <VideoCard * name="Custom Participant" * remoteProducerId="producer_789" * eventType="broadcast" * forceFullDisplay={false} * videoStream={stream} * participant={participant} * parameters={params} * customVideoCard={customVideoCard} * /> * * @example * // Using uiOverrides for component-level customization * import { MyCustomVideoCard } from './MyCustomVideoCard'; * * const sessionConfig = { * credentials: { apiKey: 'your-api-key' }, * uiOverrides: { * videoCardComponent: { * component: MyCustomVideoCard, * injectedProps: { * theme: 'dark', * showBorder: true, * }, * }, * }, * }; * * // MyCustomVideoCard.tsx * export const MyCustomVideoCard = (props: VideoCardOptions & { theme: string; showBorder: boolean }) => { * return ( * <View style={{ * borderWidth: props.showBorder ? 2 : 0, * borderColor: props.theme === 'dark' ? '#fff' : '#000', * }}> * <Text>{props.name}</Text> * {props.videoStream && <Text>Streaming...</Text>} * </View> * ); * }; * * export default App; * ``` */ declare const VideoCard: React.FC<VideoCardOptions>; export default VideoCard;