AudioCard - Displays a participant in audio-only mode with waveform and controls

AudioCard is a specialized React Native component for displaying participants in audio-only scenarios. It renders an avatar/image with an animated audio waveform, participant info overlay, and optional media control buttons. The component is ideal for audio-focused events, participants with video off, or compact grid layouts.

Key Features:

  • Animated audio waveform visualization based on real-time decibel levels
  • Avatar/image display with optional rounded corners
  • Optional control buttons for muting/video toggling
  • Participant info overlay with customizable positioning
  • Fallback to MiniCard for compact display
  • Responsive layout with custom styling support

UI Customization - Two-Tier Override System:

  1. Custom Render Function (via customAudioCard prop): Pass a function that receives all AudioCardOptions and returns custom JSX. Provides complete control over rendering logic and appearance.

  2. Component Override (via uiOverrides.audioCardComponent): Replace the entire AudioCard 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 audio card with default styling
import React from 'react';
import { AudioCard } from 'mediasfu-reactnative-expo';
import { Socket } from 'socket.io-client';

const socket = Socket('https://example.com');

function AudioParticipantGrid() {
return (
<AudioCard
name="Alice Johnson"
participant={{
name: 'Alice Johnson',
id: '456',
videoOn: false,
muted: false,
audioID: 'audio_123',
}}
audioDecibels={{ name: 'Alice Johnson', averageLoudness: 50 }}
parameters={{
audioDecibels: [{ name: 'Alice Johnson', averageLoudness: 50 }],
participants: [{ name: 'Alice Johnson', id: '456', videoOn: false, muted: false }],
socket,
coHostResponsibility: [],
roomName: 'room1',
coHost: 'coHostId',
islevel: '1',
member: '456',
eventType: 'conference',
getUpdatedAllParams: () => ({ ...params }),
}}
backgroundColor="#2c678f"
barColor="red"
textColor="white"
showControls={true}
showInfo={true}
/>
);
}
// Custom styled audio card with avatar and custom colors
<AudioCard
name="Bob Wilson"
participant={currentParticipant}
audioDecibels={{ name: 'Bob Wilson', averageLoudness: 65 }}
parameters={sessionParams}
backgroundColor="#1a1a2e"
barColor="#0f3460"
textColor="#e94560"
imageSource="https://example.com/avatar/bob.jpg"
roundedImage={true}
showControls={true}
showInfo={true}
controlsPosition="bottomRight"
infoPosition="topLeft"
customStyle={{ borderRadius: 12, margin: 8, borderWidth: 2, borderColor: '#e94560' }}
/>
// Custom audio card with custom render function
import { View, Text, Animated } from 'react-native';

const customAudioCard = (options: AudioCardOptions) => {
const { name, participant, audioDecibels } = options;
const volume = audioDecibels?.averageLoudness || 0;

return (
<View style={{ backgroundColor: '#000', padding: 15, borderRadius: 10 }}>
<Text style={{ color: '#fff', fontSize: 16, fontWeight: 'bold' }}>{name}</Text>
<View style={{ marginTop: 10, flexDirection: 'row', alignItems: 'center' }}>
<Text style={{ color: '#888' }}>Volume: </Text>
<View style={{ width: volume * 2, height: 5, backgroundColor: volume > 50 ? 'green' : 'yellow' }} />
</View>
{participant.muted && (
<Text style={{ color: 'red', marginTop: 5 }}>🔇 Muted</Text>
)}
</View>
);
};

<AudioCard
name="Custom Audio Participant"
participant={participant}
audioDecibels={audioData}
parameters={params}
customAudioCard={customAudioCard}
/>
// Using uiOverrides for component-level customization
import { MyCustomAudioCard } from './MyCustomAudioCard';

const sessionConfig = {
credentials: { apiKey: 'your-api-key' },
uiOverrides: {
audioCardComponent: {
component: MyCustomAudioCard,
injectedProps: {
theme: 'neon',
showWaveform: true,
animationSpeed: 'fast',
},
},
},
};

// MyCustomAudioCard.tsx
export const MyCustomAudioCard = (props: AudioCardOptions & { theme: string; showWaveform: boolean; animationSpeed: string }) => {
const waveformColor = props.theme === 'neon' ? '#00ff00' : '#ff0000';

return (
<View style={{ padding: 10 }}>
<Text style={{ color: waveformColor }}>{props.name}</Text>
{props.showWaveform && (
<Text>Audio Level: {props.audioDecibels?.averageLoudness || 0}</Text>
)}
</View>
);
};
import React from 'react';
import { AudioCard } from 'mediasfu-reactnative-expo';
import { io } from 'socket.io-client';

function App() {
const socket = io('http://localhost:3000');

return (
<AudioCard
name="John Doe"
barColor="blue"
textColor="white"
imageSource="https://example.com/image.jpg"
showControls={true}
showInfo={true}
participant={{ name: "John Doe", muted: false, videoOn: true }}
parameters={{
audioDecibels: [{ name: "John Doe", averageLoudness: 128 }],
participants: [{ name: "John Doe" }],
socket,
coHostResponsibility: [],
roomName: "Room 1",
coHost: "Admin",
islevel: "1",
member: "12345",
eventType: "meeting",
showAlert: ({ message, type }) => console.log(message, type),
getUpdatedAllParams: () => ({}),
}}
/>
);
}

export default App;

Properties

propTypes?: WeakValidationMap<AudioCardOptions>

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<AudioCardOptions>

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'