Skip to content

Commit a90edcd

Browse files
authored
feat: add customization for LivestreamPlayer controls (#962)
* customization of LivestreamPlayer controls * tweaks
1 parent c126542 commit a90edcd

File tree

3 files changed

+46
-32
lines changed

3 files changed

+46
-32
lines changed

dogfooding/lib/widgets/settings_menu/background_filters_menu_item.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ sealed class _FilterOption {
141141
}
142142

143143
class _BlurFilterOption extends _FilterOption {
144+
// ignore: unused_element_parameter
144145
const _BlurFilterOption([this.intensity = BlurIntensity.medium]);
145146
final BlurIntensity intensity;
146147

packages/stream_video/lib/src/webrtc/rtc_track/rtc_local_track.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import 'package:collection/collection.dart';
2-
import 'package:flutter/foundation.dart';
32
import 'package:stream_webrtc_flutter/stream_webrtc_flutter.dart' as rtc;
43

54
import '../../exceptions/video_exception.dart';

packages/stream_video_flutter/lib/src/livestream/livestream_player.dart

Lines changed: 45 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ typedef LivestreamBackstageBuilder = Widget Function(
1616
CallState callState,
1717
);
1818

19+
typedef LivestreamControlsBuilder = Widget Function(
20+
BuildContext context,
21+
Call call,
22+
CallState callState,
23+
);
24+
1925
/// Creates a widget that allows a user to view a livestream.
2026
///
2127
/// By default, the widget has call controls and other elements including:
@@ -26,8 +32,6 @@ class LivestreamPlayer extends StatefulWidget {
2632
///
2733
/// * [call] is the livestream call intended to be viewed.
2834
///
29-
/// * [muted] defines if the call is muted by default.
30-
///
3135
/// * [showParticipantCount] defines if the call should show participant count.
3236
///
3337
/// * [backButtonBuilder] allows you to build a back/close button for closing the livestream.
@@ -36,28 +40,32 @@ class LivestreamPlayer extends StatefulWidget {
3640
const LivestreamPlayer({
3741
super.key,
3842
required this.call,
39-
this.muted = false,
4043
this.showParticipantCount = true,
4144
this.backButtonBuilder,
4245
this.livestreamEndedBuilder,
4346
this.livestreamBackstageBuilder,
47+
this.livestreamControlsBuilder,
4448
this.allowDiagnostics = false,
4549
this.onCallDisconnected,
4650
this.onRecordingTapped,
4751
this.onFullscreenTapped,
52+
this.startInFullscreenMode = false,
4853
});
4954

5055
/// The livestream call to display.
5156
final Call call;
5257

53-
/// Stores if the call should be muted by default
54-
final bool muted;
55-
5658
/// Boolean to display participant count.
5759
///
5860
/// Defaults to true.
5961
final bool showParticipantCount;
6062

63+
/// Determines whether the livestream should start in fullscreen mode.
64+
/// When true, the video will expand to cover the entire available space.
65+
/// When false, the video will be contained within its boundaries.
66+
/// Defaults to false.
67+
final bool startInFullscreenMode;
68+
6169
/// [WidgetBuilder] used to build an action button on the top left side of
6270
/// the screen.
6371
final WidgetBuilder? backButtonBuilder;
@@ -68,6 +76,10 @@ class LivestreamPlayer extends StatefulWidget {
6876
/// The builder used to create a custom widget when the livestream is in backstage mode.
6977
final LivestreamBackstageBuilder? livestreamBackstageBuilder;
7078

79+
/// The builder used to create custom controls for the livestream player.
80+
/// This allows customization of the control UI elements displayed during the livestream.
81+
final LivestreamControlsBuilder? livestreamControlsBuilder;
82+
7183
/// The action to perform when the call is disconnected. By default, it pops the current route.
7284
final void Function(CallDisconnectedProperties)? onCallDisconnected;
7385

@@ -108,6 +120,7 @@ class _LivestreamPlayerState extends State<LivestreamPlayer>
108120
super.initState();
109121
_callStateSubscription = call.state.listen(_setState);
110122
_callState = call.state.value;
123+
_fullscreen = widget.startInFullscreenMode;
111124

112125
_connect();
113126
}
@@ -189,32 +202,33 @@ class _LivestreamPlayerState extends State<LivestreamPlayer>
189202
displayDiagnostics: _isStatsVisible,
190203
videoFit: _fullscreen ? VideoFit.cover : VideoFit.contain,
191204
),
192-
Align(
193-
alignment: Alignment.bottomCenter,
194-
child: StreamBuilder<Duration>(
195-
stream: call.callDurationStream,
196-
builder: (context, snapshot) {
197-
final duration = snapshot.data ?? Duration.zero;
198-
199-
return LivestreamInfo(
200-
call: call,
201-
callState: widget.call.state.value,
202-
fullscreen: _fullscreen,
203-
onFullscreenTapped: () {
204-
if (widget.onFullscreenTapped != null) {
205-
widget.onFullscreenTapped?.call();
206-
} else {
207-
setState(() {
208-
_fullscreen = !_fullscreen;
209-
});
210-
}
205+
widget.livestreamControlsBuilder?.call(context, call, _callState) ??
206+
Align(
207+
alignment: Alignment.bottomCenter,
208+
child: StreamBuilder<Duration>(
209+
stream: call.callDurationStream,
210+
builder: (context, snapshot) {
211+
final duration = snapshot.data ?? Duration.zero;
212+
213+
return LivestreamInfo(
214+
call: call,
215+
callState: widget.call.state.value,
216+
fullscreen: _fullscreen,
217+
onFullscreenTapped: () {
218+
if (widget.onFullscreenTapped != null) {
219+
widget.onFullscreenTapped?.call();
220+
} else {
221+
setState(() {
222+
_fullscreen = !_fullscreen;
223+
});
224+
}
225+
},
226+
duration: duration,
227+
showParticipantCount: widget.showParticipantCount,
228+
);
211229
},
212-
duration: duration,
213-
showParticipantCount: widget.showParticipantCount,
214-
);
215-
},
216-
),
217-
),
230+
),
231+
),
218232
],
219233
),
220234
),

0 commit comments

Comments
 (0)