Skip to content

Commit

Permalink
🎨 used go router for routing
Browse files Browse the repository at this point in the history
  • Loading branch information
sarbagyastha committed Aug 3, 2024
1 parent 87f0d9b commit b33cc7e
Show file tree
Hide file tree
Showing 6 changed files with 280 additions and 251 deletions.
3 changes: 2 additions & 1 deletion packages/youtube_player_iframe/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Changelog
## 5.1.3
## 5.1.4
**Aug 3, 2024**
- Bumps dependency to latest version.
- Fixes issue where only one of player would initialize at a time in web.

## 5.1.3
**Jul 1, 2024**
Expand Down
254 changes: 5 additions & 249 deletions packages/youtube_player_iframe/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:developer';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:youtube_player_iframe/youtube_player_iframe.dart';
import 'package:youtube_player_iframe_example/video_list_page.dart';

import 'widgets/meta_data_section.dart';
import 'widgets/play_pause_button_bar.dart';
import 'widgets/player_state_section.dart';
import 'widgets/source_input_section.dart';

const List<String> _videoIds = [
'tcodrIK2P_I',
'H5v3kku4y6Q',
'nPt8bK2gbaU',
'K18cpp_-gP8',
'iLnmTe5Q2Qw',
'_WoCV4c6XOE',
'KmzdUe0RSJo',
'6jZDSSZZxjQ',
'p2lYr3vM_1w',
'7QUtEmBT_-w',
'34_PXCzGw1M'
];
import 'package:youtube_player_iframe_example/router.dart';
import 'package:flutter_web_plugins/url_strategy.dart';

Future<void> main() async {
usePathUrlStrategy();
runApp(const YoutubeApp());
}

Expand All @@ -43,234 +22,11 @@ class YoutubeApp extends StatelessWidget {
dynamicSchemeVariant: DynamicSchemeVariant.expressive,
);

return MaterialApp(
return MaterialApp.router(
title: 'Youtube Player IFrame Demo',
theme: ThemeData.from(colorScheme: colorScheme),
debugShowCheckedModeBanner: false,
home: const YoutubeAppDemo(),
);
}
}

///
class YoutubeAppDemo extends StatefulWidget {
const YoutubeAppDemo({super.key});

@override
State<YoutubeAppDemo> createState() => _YoutubeAppDemoState();
}

class _YoutubeAppDemoState extends State<YoutubeAppDemo> {
late YoutubePlayerController _controller;

@override
void initState() {
super.initState();
_controller = YoutubePlayerController(
params: const YoutubePlayerParams(
showControls: true,
mute: false,
showFullscreenButton: true,
loop: false,
),
);

_controller.setFullScreenListener(
(isFullScreen) {
log('${isFullScreen ? 'Entered' : 'Exited'} Fullscreen.');
},
);

_controller.loadPlaylist(
list: _videoIds,
listType: ListType.playlist,
startSeconds: 136,
);
}

@override
Widget build(BuildContext context) {
return YoutubePlayerScaffold(
controller: _controller,
builder: (context, player) {
return Scaffold(
appBar: AppBar(
title: const Text('Youtube Player IFrame Demo'),
actions: const [VideoPlaylistIconButton()],
),
body: LayoutBuilder(
builder: (context, constraints) {
if (kIsWeb && constraints.maxWidth > 750) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
flex: 3,
child: Column(
children: [
player,
const VideoPositionIndicator(),
],
),
),
const Expanded(
flex: 2,
child: SingleChildScrollView(
child: Controls(),
),
),
],
);
}

return ListView(
children: [
player,
const VideoPositionIndicator(),
const Controls(),
],
);
},
),
);
},
);
}

@override
void dispose() {
_controller.close();
super.dispose();
}
}

///
class Controls extends StatelessWidget {
///
const Controls({super.key});

@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const MetaDataSection(),
_space,
const SourceInputSection(),
_space,
PlayPauseButtonBar(),
_space,
const VideoPositionSeeker(),
_space,
const PlayerStateSection(),
],
),
);
}

Widget get _space => const SizedBox(height: 10);
}

///
class VideoPlaylistIconButton extends StatelessWidget {
///
const VideoPlaylistIconButton({super.key});

@override
Widget build(BuildContext context) {
final controller = context.ytController;

return IconButton(
onPressed: () async {
controller.pauseVideo();
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const VideoListPage(),
),
);
controller.playVideo();
},
icon: const Icon(Icons.playlist_play_sharp),
);
}
}

///
class VideoPositionIndicator extends StatelessWidget {
///
const VideoPositionIndicator({super.key});

@override
Widget build(BuildContext context) {
final controller = context.ytController;

return StreamBuilder<YoutubeVideoState>(
stream: controller.videoStateStream,
initialData: const YoutubeVideoState(),
builder: (context, snapshot) {
final position = snapshot.data?.position.inMilliseconds ?? 0;
final duration = controller.metadata.duration.inMilliseconds;

return LinearProgressIndicator(
value: duration == 0 ? 0 : position / duration,
minHeight: 1,
);
},
);
}
}

///
class VideoPositionSeeker extends StatelessWidget {
///
const VideoPositionSeeker({super.key});

@override
Widget build(BuildContext context) {
var value = 0.0;

return Row(
children: [
const Text(
'Seek',
style: TextStyle(fontWeight: FontWeight.w300),
),
const SizedBox(width: 14),
Expanded(
child: StreamBuilder<YoutubeVideoState>(
stream: context.ytController.videoStateStream,
initialData: const YoutubeVideoState(),
builder: (context, snapshot) {
final position = snapshot.data?.position.inSeconds ?? 0;
final duration = context.ytController.metadata.duration.inSeconds;

value = position == 0 || duration == 0 ? 0 : position / duration;

return StatefulBuilder(
builder: (context, setState) {
return Slider(
value: value,
onChanged: (positionFraction) {
value = positionFraction;
setState(() {});

context.ytController.seekTo(
seconds: (value * duration).toDouble(),
allowSeekAhead: true,
);
},
min: 0,
max: 1,
);
},
);
},
),
),
],
routerConfig: router,
);
}
}
Loading

0 comments on commit b33cc7e

Please sign in to comment.