Skip to content

Commit

Permalink
Merge pull request #1756 from 100mslive/FLUT-265
Browse files Browse the repository at this point in the history
FLUT-265: HLS Player View
  • Loading branch information
Decoder07 authored Apr 26, 2024
2 parents c757b87 + 59e3c9f commit 3d909e5
Show file tree
Hide file tree
Showing 52 changed files with 1,254 additions and 465 deletions.
1 change: 1 addition & 0 deletions packages/hms_room_kit/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# 100ms Room Kit 🎉

[![Pub Version](https://img.shields.io/pub/v/hms_room_kit)](https://pub.dev/packages/hms_room_kit)
[![Build](https://github.com/100mslive/100ms-flutter/actions/workflows/build.yml/badge.svg?branch=develop)](https://github.com/100mslive/100ms-flutter/actions/workflows/build.yml)
[![License](https://img.shields.io/github/license/100mslive/100ms-flutter)](https://www.100ms.live/)
[![Documentation](https://img.shields.io/badge/Read-Documentation-blue)](https://docs.100ms.live/flutter/v2/foundation/basics)
[![Discord](https://img.shields.io/discord/843749923060711464?label=Join%20on%20Discord)](https://100ms.live/discord)
Expand Down
Binary file not shown.
4 changes: 4 additions & 0 deletions packages/hms_room_kit/lib/src/assets/icons/pause.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions packages/hms_room_kit/lib/src/assets/icons/play.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions packages/hms_room_kit/lib/src/assets/icons/seek_backward.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions packages/hms_room_kit/lib/src/assets/icons/seek_forward.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 4 additions & 4 deletions packages/hms_room_kit/lib/src/common/utility_components.dart
Original file line number Diff line number Diff line change
Expand Up @@ -992,18 +992,18 @@ class UtilityComponents {
MeetingStore meetingStore = Provider.of<MeetingStore>(context);
return GestureDetector(
onTap: () {
if (meetingStore.isLandscapeLocked) {
meetingStore.setLandscapeLock(false);
if (meetingStore.isScreenRotationAllowed) {
meetingStore.allowScreenRotation(false);
} else {
meetingStore.setLandscapeLock(true);
meetingStore.allowScreenRotation(true);
}
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: SvgPicture.asset(
"packages/hms_room_kit/lib/src/assets/icons/rotate.svg",
colorFilter: ColorFilter.mode(
meetingStore.isLandscapeLocked ? Colors.blue : iconColor,
meetingStore.isScreenRotationAllowed ? Colors.blue : iconColor,
BlendMode.srcIn)),
),
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
library;

///Package imports
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:provider/provider.dart';

///Project imports
import 'package:hms_room_kit/hms_room_kit.dart';
import 'package:hms_room_kit/src/layout_api/hms_room_layout.dart';
import 'package:hms_room_kit/src/meeting/meeting_store.dart';
import 'package:hms_room_kit/src/widgets/bottom_sheets/hls_app_utilities_bottom_sheet.dart';
import 'package:hms_room_kit/src/widgets/common_widgets/hms_embedded_button.dart';
import 'package:provider/provider.dart';

///[HLSHandRaiseMenu] is a widget that is used to render the hand raise menu in case of Viewer near realtime
class HLSHandRaiseMenu extends StatelessWidget {
const HLSHandRaiseMenu({Key? key}) : super(key: key);

Expand Down
90 changes: 44 additions & 46 deletions packages/hms_room_kit/lib/src/hls_viewer/hls_player.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,56 +28,54 @@ class HLSPlayer extends StatelessWidget {
///Renders the HLS Player if the HLS has started
///Otherwise renders the waiting UI
hasHLSStarted
? Align(
alignment: Alignment.center,
child: Selector<HLSPlayerStore, Size>(
selector: (_, hlsPlayerStore) =>
hlsPlayerStore.hlsPlayerSize,
builder: (_, hlsPlayerSize, __) {
return AspectRatio(
aspectRatio:
hlsPlayerSize.width / hlsPlayerSize.height,
child: InkWell(
onTap: () => context
.read<HLSPlayerStore>()
.toggleButtonsVisibility(),
splashFactory: NoSplash.splashFactory,
splashColor: HMSThemeColors.backgroundDim,
child: IgnorePointer(
child: const HMSHLSPlayer(
showPlayerControls: false,
),
),
),
);
}),
)
? Selector<HLSPlayerStore, bool>(
selector: (_, hlsPlayerStore) =>
hlsPlayerStore.isFullScreen,
builder: (_, isFullScreen, __) {
return InteractiveViewer(
minScale: 1,
maxScale: 8,
child: Align(
alignment: Alignment.center,
child: Selector<HLSPlayerStore, Size>(
selector: (_, hlsPlayerStore) =>
hlsPlayerStore.hlsPlayerSize,
builder: (_, hlsPlayerSize, __) {
return InkWell(
onTap: () => context
.read<HLSPlayerStore>()
.toggleButtonsVisibility(),
splashFactory: NoSplash.splashFactory,
splashColor: HMSThemeColors.backgroundDim,
child: AspectRatio(
aspectRatio: hlsPlayerSize.width /
hlsPlayerSize.height,
child: Selector<HLSPlayerStore, bool>(
selector: (_, hlsPlayerStore) =>
hlsPlayerStore.isFullScreen,
builder: (_, isFullScreen, __) {
return IgnorePointer(
child: const HMSHLSPlayer(
showPlayerControls: false,
),
);
}),
),
);
}),
),
);
})
: Center(child: const HLSWaitingUI()),

///This renders the overlay controls for HLS Player
Align(
alignment: Alignment.center,
child: Selector<HLSPlayerStore, bool>(
selector: (_, hlsPlayerStore) =>
hlsPlayerStore.isFullScreen,
builder: (_, isFullScreen, __) {
return isFullScreen
? Selector<HLSPlayerStore, Size>(
selector: (_, hlsPlayerStore) =>
hlsPlayerStore.hlsPlayerSize,
builder: (_, hlsPlayerSize, __) {
return AspectRatio(
aspectRatio: hlsPlayerSize.width /
hlsPlayerSize.height,
child: HLSPlayerOverlayOptions(
hasHLSStarted: hasHLSStarted,
),
);
})
: HLSPlayerOverlayOptions(
hasHLSStarted: hasHLSStarted);
}),
),
alignment: Alignment.center,
child: HLSPlayerOverlayOptions(
hasHLSStarted: hasHLSStarted,
)),

///This renders the circular progress indicator when the player is buffering or failed
Selector<HLSPlayerStore, HMSHLSPlaybackState>(
selector: (_, hlsPlayerStore) =>
hlsPlayerStore.playerPlaybackState,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import 'package:hms_room_kit/src/widgets/bottom_sheets/chat_bottom_sheet.dart';

///[HLSPlayerDesktopControls] is the desktop controls for the HLS Player
class HLSPlayerDesktopControls extends StatefulWidget {
final Orientation orientation;
const HLSPlayerDesktopControls({Key? key, required this.orientation})
: super(key: key);

@override
State<HLSPlayerDesktopControls> createState() =>
_HLSPlayerDesktopControlsState();
Expand All @@ -26,25 +30,25 @@ class _HLSPlayerDesktopControlsState extends State<HLSPlayerDesktopControls> {

@override
Widget build(BuildContext context) {
return Expanded(
child: Column(
children: [
///Renders HLS Stream Description and Chat Bottom Sheet
HLSStreamDescription(
showDescription: showDescription,
toggleDescription: toggleDescription),

///Renders Chat Bottom Sheet only is the description is not visible
if (!showDescription)
Expanded(
child: Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: ChatBottomSheet(
isHLSChat: true,
),
))
],
),
return Column(
children: [
///Renders HLS Stream Description and Chat Bottom Sheet
widget.orientation == Orientation.portrait
? HLSStreamDescription(
showDescription: showDescription,
toggleDescription: toggleDescription)
: const SizedBox(),

///Renders Chat Bottom Sheet only if the description is not visible
if (!showDescription)
Expanded(
child: Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: const ChatBottomSheet(
isHLSChat: true,
),
))
],
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
///Project imports
import 'package:hms_room_kit/src/hls_viewer/hls_viewer_bottom_navigation_bar.dart';
import 'package:hms_room_kit/src/hls_viewer/hls_viewer_header.dart';
import 'package:hms_room_kit/src/hls_viewer/hls_viewer_mid_section.dart';

///[HLSPlayerOverlayOptions] renders the overlay options for the HLS Player
class HLSPlayerOverlayOptions extends StatelessWidget {
Expand All @@ -14,16 +15,30 @@ class HLSPlayerOverlayOptions extends StatelessWidget {
const HLSPlayerOverlayOptions({super.key, required this.hasHLSStarted});
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
///Here top and bottom navigation bar are in Column
///while mid section is above the Column
///This is done to avoid overflowing in case of
///large transcription
return Stack(
children: [
HLSViewerHeader(
hasHLSStarted: hasHLSStarted,
Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
HLSViewerHeader(
hasHLSStarted: hasHLSStarted,
),

///Renders the bottom navigation bar if the HLS has started
///Otherwise does not render the bottom navigation bar
hasHLSStarted ? HLSViewerBottomNavigationBar() : const SizedBox()
],
),

///Renders the bottom navigation bar if the HLS has started
///Otherwise does not render the bottom navigation bar
hasHLSStarted ? HLSViewerBottomNavigationBar() : const SizedBox()
///This renders the pause/play button
Align(
alignment: Alignment.center,
child: hasHLSStarted ? HLSViewerMidSection() : const SizedBox(),
)
],
);
}
Expand Down
92 changes: 92 additions & 0 deletions packages/hms_room_kit/lib/src/hls_viewer/hls_player_seekbar.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
library;

///Package imports
import 'package:flutter/material.dart';
import 'package:hmssdk_flutter/hmssdk_flutter.dart';
import 'package:provider/provider.dart';
import 'package:tuple/tuple.dart';

///Project imports
import 'package:hms_room_kit/src/meeting/meeting_store.dart';
import 'package:hms_room_kit/hms_room_kit.dart';
import 'package:hms_room_kit/src/hls_viewer/hls_player_store.dart';

///[HLSPlayerSeekbar] is the seekbar for the HLS Player
class HLSPlayerSeekbar extends StatefulWidget {
@override
State<HLSPlayerSeekbar> createState() => _HLSPlayerSeekbarState();
}

class _HLSPlayerSeekbarState extends State<HLSPlayerSeekbar> {
int seekBarValue = 0;
int minValue = 0, maxValue = 300;
bool isInteracting = false;

///[_toggleIsInteracting] toggles the [isInteracting] variable
void _toggleIsInteracting(bool value) {
setState(() {
isInteracting = value;
});
}

@override
void initState() {
super.initState();
maxValue = context.read<HLSPlayerStore>().rollingWindow.inSeconds;
}

@override
Widget build(BuildContext context) {
return (context
.read<MeetingStore>()
.hmsRoom
?.hmshlsStreamingState
?.variants[0]
?.playlistType ==
HMSHLSPlaylistType.dvr)
? Selector<HLSPlayerStore, Tuple2<Duration, Duration>>(
selector: (_, hlsPlayerStore) => Tuple2(
hlsPlayerStore.timeFromLive, hlsPlayerStore.rollingWindow),
builder: (_, data, __) {
maxValue = data.item2.inSeconds;
seekBarValue = maxValue > 0 ? maxValue - data.item1.inSeconds : 0;
minValue = 0;
return (maxValue > 0 && seekBarValue > 0)
? SliderTheme(
data: SliderThemeData(
trackHeight: isInteracting ? 6 : 4,
trackShape: RoundedRectSliderTrackShape(),
inactiveTrackColor: HMSThemeColors.baseWhite,
activeTrackColor: HMSThemeColors.primaryDefault,
thumbColor: HMSThemeColors.primaryDefault,
thumbShape: RoundSliderThumbShape(
enabledThumbRadius: isInteracting ? 10 : 6),
overlayShape:
RoundSliderOverlayShape(overlayRadius: 0)),
child: Slider(
value: seekBarValue.toDouble(),
onChanged: (value) {},
onChangeEnd: (value) {
if (value > seekBarValue) {
HMSHLSPlayerController.seekForward(
seconds: (value - seekBarValue).toInt());
} else {
HMSHLSPlayerController.seekBackward(
seconds: (seekBarValue - value).toInt());
}
HMSHLSPlayerController.resume();
_toggleIsInteracting(false);
},
onChangeStart: (_) {
HMSHLSPlayerController.pause();
_toggleIsInteracting(true);
},
min: minValue.toDouble(),
max: maxValue.toDouble(),
),
)
: const SizedBox();
})
: const SizedBox();
}
}
Loading

0 comments on commit 3d909e5

Please sign in to comment.