Skip to content
Media client

Rendering and events

Render video tracks and react to room changes.

Render video

Render each video track with VideoTrackRenderer:

import 'package:flutter/material.dart';
import 'package:voxera_media_client/voxera_media_client.dart';
 
class ParticipantView extends StatelessWidget {
  const ParticipantView({super.key, this.track});
 
  final VideoTrack? track;
 
  @override
  Widget build(BuildContext context) {
    final track = this.track;
    if (track == null) return Container(color: Colors.grey);
    return VideoTrackRenderer(track);
  }
}

Audio

Audio tracks play automatically while you're subscribed to them.

React to changes

The client notifies you in two ways:

  • ChangeNotifier is a general signal that something changed. Use it for UI that only needs to rebuild.
  • EventsListener delivers specific events.
import 'package:flutter/material.dart';
import 'package:voxera_media_client/voxera_media_client.dart';
 
class RoomWidget extends StatefulWidget {
  const RoomWidget({super.key, required this.room});
 
  final Room room;
 
  @override
  State<RoomWidget> createState() => _RoomState();
}
 
class _RoomState extends State<RoomWidget> {
  late final EventsListener<RoomEvent> _listener = widget.room.createListener();
 
  @override
  void initState() {
    super.initState();
    widget.room.addListener(_onChange);
 
    _listener
      ..on<RoomDisconnectedEvent>((_) {
        // handle the disconnect
      })
      ..on<ParticipantConnectedEvent>((e) {
        debugPrint('participant joined: ${e.participant.identity}');
      });
  }
 
  @override
  void dispose() {
    _listener.dispose();
    widget.room.removeListener(_onChange);
    super.dispose();
  }
 
  void _onChange() => setState(() {});
 
  @override
  Widget build(BuildContext context) => const SizedBox();
}