Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FLUT-265: HLS Player View #1756

Merged
merged 59 commits into from
Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
a4f89a3
Added HLS Player UI with chat
Decoder07 Apr 4, 2024
eb62cc8
Added HLS Player desktop UI
Decoder07 Apr 5, 2024
81ecf78
🤖 Automated Format and Fix
Decoder07 Apr 5, 2024
a9d7b9b
released sample app version 1.5.164 (464) 🍀
ygit Apr 5, 2024
9179ce1
Merge branch 'develop' into FLUT-262
ygit Apr 9, 2024
00075a1
Merge branch 'develop' into FLUT-262
ygit Apr 9, 2024
8e27393
Merge branch 'FLUT-262' of https://github.com/100mslive/100ms-flutter…
ygit Apr 9, 2024
9bbf8f3
updated pods
ygit Apr 9, 2024
51ffabf
released sample app version 1.5.165 (465) 🍀
ygit Apr 9, 2024
9d8440d
released sample app version 1.5.166 (466) 🍀
ygit Apr 9, 2024
86601b4
resolved lint warnings
ygit Apr 9, 2024
9211b8d
added iOS Privacy info file
ygit Apr 9, 2024
f63811e
updated build version
ygit Apr 10, 2024
e895923
Fixed foreground services on android 14
Decoder07 Apr 10, 2024
a5f220e
released sample app version 1.5.167 (467) 🍀
ygit Apr 10, 2024
046935a
Added resolution changes and removed broadcast receiver
Decoder07 Apr 12, 2024
bd4d3e1
Fixed chat bottom sheet
Decoder07 Apr 12, 2024
30cdee7
released sample app version 1.5.168 (468) 🍀
ygit Apr 12, 2024
ecfdbbf
resolved lint warnings
ygit Apr 13, 2024
de494a9
Added caption supported api in iOS
Decoder07 Apr 15, 2024
7a445eb
Added buffering state
Decoder07 Apr 15, 2024
d324703
released sample app version 1.5.169 (469) 🍀
ygit Apr 15, 2024
576ec6d
Fixed player flickr
Decoder07 Apr 17, 2024
89f2521
released sample app version 1.5.170 (470) 🍀
ygit Apr 17, 2024
f2b5e22
Fixed SIP Peer UI issue (#1751)
Decoder07 Apr 17, 2024
bf5a237
released sample app version 1.5.171 (471) 🍀
ygit Apr 17, 2024
5962d74
updated docs
ygit Apr 18, 2024
e172154
Merge branch 'develop' into FLUT-262
ygit Apr 18, 2024
ca3eb7d
Merge branch 'develop' into FLUT-262
ygit Apr 18, 2024
bca4b1d
Added captions
Decoder07 Apr 18, 2024
218e977
Fixed reconnection handling in android and iOS (#1753)
Decoder07 Apr 19, 2024
e982224
released sample app version 1.5.172 (472) 🍀
ygit Apr 19, 2024
1454865
Fixed iOS network error
Decoder07 Apr 19, 2024
5f8324e
Added play pause functionality
Decoder07 Apr 19, 2024
be4692e
Merged FLUT-262
Decoder07 Apr 19, 2024
fc55744
Added landscape support
Decoder07 Apr 22, 2024
ddd3c65
Added pinch and zoom
Decoder07 Apr 22, 2024
5dffffb
Merged develop
Decoder07 Apr 22, 2024
c2add72
released sample app version 1.5.175 (475) 🍀
ygit Apr 22, 2024
4ce77c6
Added landscape support and SIP fix
Decoder07 Apr 22, 2024
828d243
released sample app version 1.5.177 (477) 🍀
ygit Apr 23, 2024
36fa757
updated Example app changelog
ygit Apr 23, 2024
29c4259
added seekbar
Decoder07 Apr 23, 2024
0bb623c
released sample app version 1.5.178 (478) 🍀
ygit Apr 23, 2024
da66af5
Fixed seek bar
Decoder07 Apr 23, 2024
4e18524
Fixed android bug
Decoder07 Apr 24, 2024
2f4f1d2
released sample app version 1.5.179 (479) 🍀
ygit Apr 24, 2024
5e12388
updated Room Kit ReadMe
ygit Apr 24, 2024
4c8f01e
Added android captions
Decoder07 Apr 24, 2024
2fe4691
released sample app version 1.5.180 (480) 🍀
ygit Apr 24, 2024
c77dd68
Fixed empty name issuer
Decoder07 Apr 24, 2024
500d2b1
Fixed time to live value for iOS
Decoder07 Apr 24, 2024
5acc644
released sample app version 1.5.181 (481) 🍀
ygit Apr 24, 2024
273a369
🤖 Automated Format and Fix
Decoder07 Apr 25, 2024
56c281a
Fixed transcription bug
Decoder07 Apr 25, 2024
758733a
🤖 Automated Format and Fix
Decoder07 Apr 25, 2024
9cca509
released sample app version 1.5.182 (482) 🍀
Decoder07 Apr 25, 2024
33b9dac
🤖 Automated Format and Fix
Decoder07 Apr 25, 2024
59e3c9f
Fixed linter
Decoder07 Apr 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.
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.
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
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
Loading