Skip to content

Commit

Permalink
fixed rendering exception.
Browse files Browse the repository at this point in the history
  • Loading branch information
cloudwebrtc committed Dec 8, 2023
1 parent 453508e commit 2cd9aa7
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 58 deletions.
132 changes: 82 additions & 50 deletions example/lib/pages/room.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import '../exts.dart';
import '../utils.dart';
import '../widgets/controls.dart';
import '../widgets/participant.dart';
import '../widgets/participant_info.dart';
import '../widgets/participant_grid_tile.dart';

class RoomPage extends StatefulWidget {
Expand All @@ -33,6 +32,7 @@ class _RoomPageState extends State<RoomPage> with WidgetsBindingObserver {
List<Participant> participantTracks = [];
EventsListener<RoomEvent> get _listener => widget.listener;
bool get fastConnection => widget.room.engine.fastConnectOptions != null;
bool get autoSubscribe => widget.room.connectOptions.autoSubscribe;
bool gridView = false;
@override
void initState() {
Expand Down Expand Up @@ -83,6 +83,7 @@ class _RoomPageState extends State<RoomPage> with WidgetsBindingObserver {
setState(() {
_notification = state;
});
if (autoSubscribe) return;
if (state == AppLifecycleState.resumed) {
for (var p in participantTracks) {
if (p.hasVideo && participantSubscriptions.containsKey(p.identity)) {
Expand Down Expand Up @@ -247,6 +248,44 @@ class _RoomPageState extends State<RoomPage> with WidgetsBindingObserver {
Map<String, bool> visibleParticipants = {};
Map<String, bool> participantSubscriptions = {};

Widget _widgetForParticipant(int index) {
final participant = participantTracks[index];
return VisibilityDetector(
key: Key(participant.identity),
onVisibilityChanged: (info) {
if (autoSubscribe) return;
final bool isVisible = info.visibleFraction > 0;
final bool isCompletelyGone = info.visibleFraction == 0;
final bool isSubscribed =
participantSubscriptions[participant.identity] ?? false;
final bool shouldSubscribe =
!isSubscribed && isVisible && participant is! LocalParticipant;

if (shouldSubscribe) {
subscribeToVideoTracks(
participant as RemoteParticipant,
);
visibleParticipants[participant.identity] = true;
} else if (participant is! LocalParticipant && isCompletelyGone) {
unSubscribeToVideoTracks(
participant as RemoteParticipant,
);
visibleParticipants.remove(
participant.identity,
);
}
},
child: SizedBox(
width: 240,
height: 180,
child: ParticipantGridTile(
participantTracks[index],
participantSubscriptions,
),
),
);
}

@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
Expand Down Expand Up @@ -296,47 +335,8 @@ class _RoomPageState extends State<RoomPage> with WidgetsBindingObserver {
childAspectRatio: 1.5,
),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
final participant = participantTracks[index];

return VisibilityDetector(
key: Key(participant.identity),
onVisibilityChanged: (info) {
final bool isVisible = info.visibleFraction > 0;
final bool isCompletelyGone =
info.visibleFraction == 0;
final bool isSubscribed = participantSubscriptions[
participant.identity] ??
false;
final bool shouldSubscribe = !isSubscribed &&
isVisible &&
participant is! LocalParticipant;

if (shouldSubscribe) {
subscribeToVideoTracks(
participant as RemoteParticipant,
);
visibleParticipants[participant.identity] = true;
} else if (participant is! LocalParticipant &&
isCompletelyGone) {
unSubscribeToVideoTracks(
participant as RemoteParticipant,
);
visibleParticipants.remove(
participant.identity,
);
}
},
child: SizedBox(
width: 240,
height: 180,
child: ParticipantGridTile(
participantTracks[index],
participantSubscriptions,
),
),
);
},
(BuildContext context, int index) =>
_widgetForParticipant(index),
childCount: participantTracks.length,
),
),
Expand All @@ -358,8 +358,45 @@ class _RoomPageState extends State<RoomPage> with WidgetsBindingObserver {
children: [
Expanded(
child: participantTracks.isNotEmpty
? ParticipantWidget.widgetFor(participantTracks.first,
showStatsLayer: true)
? VisibilityDetector(
key: Key(participantTracks.first.identity),
onVisibilityChanged: (info) {
if (autoSubscribe) return;
final bool isVisible = info.visibleFraction > 0;
final bool isCompletelyGone =
info.visibleFraction == 0;
final bool isSubscribed =
participantSubscriptions[
participantTracks.first.identity] ??
false;
final bool shouldSubscribe = !isSubscribed &&
isVisible &&
participantTracks.first
is! LocalParticipant;

if (shouldSubscribe) {
subscribeToVideoTracks(
participantTracks.first
as RemoteParticipant,
);
visibleParticipants[
participantTracks.first.identity] = true;
} else if (participantTracks.first
is! LocalParticipant &&
isCompletelyGone) {
unSubscribeToVideoTracks(
participantTracks.first
as RemoteParticipant,
);
visibleParticipants.remove(
participantTracks.first.identity,
);
}
},
child: ParticipantWidget.widgetFor(
participantTracks.first,
showStatsLayer: true),
)
: Container()),
if (widget.room.localParticipant != null)
SafeArea(
Expand All @@ -380,12 +417,7 @@ class _RoomPageState extends State<RoomPage> with WidgetsBindingObserver {
scrollDirection: Axis.horizontal,
itemCount: math.max(0, participantTracks.length - 1),
itemBuilder: (BuildContext context, int index) =>
SizedBox(
width: 180,
height: 120,
child: ParticipantWidget.widgetFor(
participantTracks[index + 1]),
),
_widgetForParticipant(index + 1),
),
)),
],
Expand Down
3 changes: 3 additions & 0 deletions example/lib/widgets/controls.dart
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ class _ControlsWidgetState extends State<ControlsWidget> {
_audioInputs = devices.where((d) => d.kind == 'audioinput').toList();
_audioOutputs = devices.where((d) => d.kind == 'audiooutput').toList();
_videoInputs = devices.where((d) => d.kind == 'videoinput').toList();
for (var element in _videoInputs ?? []) {
print('video input: ${element.deviceId}');
}
setState(() {});
}

Expand Down
11 changes: 3 additions & 8 deletions example/lib/widgets/participant_grid_tile.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import 'package:flutter/material.dart';
import 'package:livekit_client/livekit_client.dart';
import 'package:livekit_example/widgets/no_video.dart';
import 'package:fluttertoast/fluttertoast.dart';

import 'participant.dart';

extension ParticipantExtension on Participant {
bool get isLocalParticipant => this is LocalParticipant;
bool get isRemoteParticipant => this is RemoteParticipant;
Expand Down Expand Up @@ -60,14 +61,8 @@ class _ParticipantGridTile extends State<ParticipantGridTile> {
width: 2,
)),
position: DecorationPosition.foreground,
child: hasVideo
? VideoTrackRenderer(
widget.participant.videoTracks[0].track as VideoTrack,
)
: const NoVideoWidget(),
child: ParticipantWidget.widgetFor(widget.participant),
),
Text(
'cam: ${widget.participant.isCameraEnabled()}\n ${widget.participant.identity} ($name)'),
Material(
type: MaterialType.transparency,
child: InkWell(
Expand Down

0 comments on commit 2cd9aa7

Please sign in to comment.