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
// 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"
/>
);
}
// 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 }}
/>
// 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}
/>
// 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;

Properties

propTypes?: WeakValidationMap<VideoCardOptions>

Used to declare the types of the props accepted by the component. These types will be checked during rendering and in development only.

We recommend using TypeScript instead of checking prop types at runtime.

contextTypes?: ValidationMap<any>

Lets you specify which legacy context is consumed by this component.

defaultProps?: Partial<VideoCardOptions>

Used to define default values for the props accepted by the component.

type Props = { name?: string }

const MyComponent: FC<Props> = (props) => {
return <div>{props.name}</div>
}

MyComponent.defaultProps = {
name: 'John Doe'
}
displayName?: string

Used in debugging messages. You might want to set it explicitly if you want to display a different name for debugging purposes.


const MyComponent: FC = () => {
return <div>Hello!</div>
}

MyComponent.displayName = 'MyAwesomeComponent'