pparth602

youtube_player_example_main.dart

Mar 17th, 2021
158
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Dart 14.61 KB | None | 0 0
  1. import 'dart:developer';
  2.  
  3. import 'package:flutter/cupertino.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:flutter/rendering.dart';
  6. import 'package:flutter/services.dart';
  7. import 'package:youtube_player_flutter/youtube_player_flutter.dart';
  8.  
  9. import 'video_list.dart';
  10.  
  11. void main() {
  12.   WidgetsFlutterBinding.ensureInitialized();
  13.   SystemChrome.setSystemUIOverlayStyle(
  14.     const SystemUiOverlayStyle(
  15.       statusBarColor: Colors.blueAccent,
  16.     ),
  17.   );
  18.   runApp(YoutubePlayerDemoApp());
  19. }
  20.  
  21. /// Creates [YoutubePlayerDemoApp] widget.
  22. class YoutubePlayerDemoApp extends StatelessWidget {
  23.   @override
  24.   Widget build(BuildContext context) {
  25.     return MaterialApp(
  26.       debugShowCheckedModeBanner: false,
  27.       title: 'Youtube Player Flutter',
  28.       theme: ThemeData(
  29.         primarySwatch: Colors.blue,
  30.         appBarTheme: const AppBarTheme(
  31.           color: Colors.blueAccent,
  32.           textTheme: TextTheme(
  33.             headline6: TextStyle(
  34.               color: Colors.white,
  35.               fontWeight: FontWeight.w300,
  36.               fontSize: 20.0,
  37.             ),
  38.           ),
  39.         ),
  40.         iconTheme: const IconThemeData(
  41.           color: Colors.blueAccent,
  42.         ),
  43.       ),
  44.       home: MyHomePage(),
  45.     );
  46.   }
  47. }
  48.  
  49. /// Homepage
  50. class MyHomePage extends StatefulWidget {
  51.   @override
  52.   _MyHomePageState createState() => _MyHomePageState();
  53. }
  54.  
  55. class _MyHomePageState extends State<MyHomePage> {
  56.   final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey();
  57.   YoutubePlayerController _controller;
  58.   TextEditingController _idController;
  59.   TextEditingController _seekToController;
  60.  
  61.   PlayerState _playerState;
  62.   YoutubeMetaData _videoMetaData;
  63.   double _volume = 100;
  64.   bool _muted = false;
  65.   bool _isPlayerReady = false;
  66.  
  67.   final List<String> _ids = [
  68.     'nPt8bK2gbaU',
  69.     'gQDByCdjUXw',
  70.     'iLnmTe5Q2Qw',
  71.     '_WoCV4c6XOE',
  72.     'KmzdUe0RSJo',
  73.     '6jZDSSZZxjQ',
  74.     'p2lYr3vM_1w',
  75.     '7QUtEmBT_-w',
  76.     '34_PXCzGw1M',
  77.   ];
  78.  
  79.   @override
  80.   void initState() {
  81.     super.initState();
  82.     _controller = YoutubePlayerController(
  83.       initialVideoId: _ids.first,
  84.       flags: const YoutubePlayerFlags(
  85.         mute: false,
  86.         autoPlay: true,
  87.         disableDragSeek: false,
  88.         loop: false,
  89.         isLive: false,
  90.         forceHD: false,
  91.         enableCaption: true,
  92.       ),
  93.     )..addListener(listener);
  94.     _idController = TextEditingController();
  95.     _seekToController = TextEditingController();
  96.     _videoMetaData = const YoutubeMetaData();
  97.     _playerState = PlayerState.unknown;
  98.   }
  99.  
  100.   void listener() {
  101.     if (_isPlayerReady && mounted && !_controller.value.isFullScreen) {
  102.       setState(() {
  103.         _playerState = _controller.value.playerState;
  104.         _videoMetaData = _controller.metadata;
  105.       });
  106.     }
  107.   }
  108.  
  109.   @override
  110.   void deactivate() {
  111.     // Pauses video while navigating to next page.
  112.     _controller.pause();
  113.     super.deactivate();
  114.   }
  115.  
  116.   @override
  117.   void dispose() {
  118.     _controller.dispose();
  119.     _idController.dispose();
  120.     _seekToController.dispose();
  121.     super.dispose();
  122.   }
  123.  
  124.   @override
  125.   Widget build(BuildContext context) {
  126.     return YoutubePlayerBuilder(
  127.       onExitFullScreen: () {
  128.         // The player forces portraitUp after exiting fullscreen. This overrides the behaviour.
  129.         SystemChrome.setPreferredOrientations(DeviceOrientation.values);
  130.       },
  131.       player: YoutubePlayer(
  132.         controller: _controller,
  133.         showVideoProgressIndicator: true,
  134.         progressIndicatorColor: Colors.blueAccent,
  135.         topActions: <Widget>[
  136.           const SizedBox(width: 8.0),
  137.           Expanded(
  138.             child: Text(
  139.               _controller.metadata.title,
  140.               style: const TextStyle(
  141.                 color: Colors.white,
  142.                 fontSize: 18.0,
  143.               ),
  144.               overflow: TextOverflow.ellipsis,
  145.               maxLines: 1,
  146.             ),
  147.           ),
  148.           IconButton(
  149.             icon: const Icon(
  150.               Icons.settings,
  151.               color: Colors.white,
  152.               size: 25.0,
  153.             ),
  154.             onPressed: () {
  155.               log('Settings Tapped!');
  156.             },
  157.           ),
  158.         ],
  159.         onReady: () {
  160.           _isPlayerReady = true;
  161.         },
  162.         onEnded: (data) {
  163.           _controller
  164.               .load(_ids[(_ids.indexOf(data.videoId) + 1) % _ids.length]);
  165.           print("================================================");
  166.  
  167.           _showSnackBar(
  168.               _ids[(_ids.indexOf(data.videoId) + 1) % _ids.length].toString());
  169.         },
  170.       ),
  171.       builder: (context, player) => Scaffold(
  172.         key: _scaffoldKey,
  173.         appBar: AppBar(
  174.           leading: Padding(
  175.             padding: const EdgeInsets.only(left: 12.0),
  176.             child: Image.asset(
  177.               'assets/ypf.png',
  178.               fit: BoxFit.fitWidth,
  179.             ),
  180.           ),
  181.           title: const Text(
  182.             'Youtube Player Flutter',
  183.             style: TextStyle(color: Colors.white),
  184.           ),
  185.           actions: [
  186.             IconButton(
  187.               icon: const Icon(Icons.video_library),
  188.               onPressed: () => Navigator.push(
  189.                 context,
  190.                 CupertinoPageRoute(
  191.                   builder: (context) => VideoList(),
  192.                 ),
  193.               ),
  194.             ),
  195.           ],
  196.         ),
  197.         body: ListView(
  198.           children: [
  199.             player,
  200.             Padding(
  201.               padding: const EdgeInsets.all(8.0),
  202.               child: Column(
  203.                 crossAxisAlignment: CrossAxisAlignment.stretch,
  204.                 children: [
  205.                   _space,
  206.                   _text('Title', _videoMetaData.title),
  207.                   _space,
  208.                   _text('Channel', _videoMetaData.author),
  209.                   _space,
  210.                   _text('Video Id', _videoMetaData.videoId),
  211.                   _space,
  212.                   Row(
  213.                     children: [
  214.                       _text(
  215.                         'Playback Quality',
  216.                         _controller.value.playbackQuality,
  217.                       ),
  218.                       const Spacer(),
  219.                       _text(
  220.                         'Playback Rate',
  221.                         '${_controller.value.playbackRate}x  ',
  222.                       ),
  223.                     ],
  224.                   ),
  225.                   _space,
  226.                   TextField(
  227.                     enabled: _isPlayerReady,
  228.                     controller: _idController,
  229.                     decoration: InputDecoration(
  230.                       border: InputBorder.none,
  231.                       hintText: 'Enter youtube \<video id\> or \<link\>',
  232.                       fillColor: Colors.blueAccent.withAlpha(20),
  233.                       filled: true,
  234.                       hintStyle: const TextStyle(
  235.                         fontWeight: FontWeight.w300,
  236.                         color: Colors.blueAccent,
  237.                       ),
  238.                       suffixIcon: IconButton(
  239.                         icon: const Icon(Icons.clear),
  240.                         onPressed: () => _idController.clear(),
  241.                       ),
  242.                     ),
  243.                   ),
  244.                   _space,
  245.                   Row(
  246.                     children: [
  247.                       _loadCueButton('LOAD'),
  248.                       const SizedBox(width: 10.0),
  249.                       _loadCueButton('CUE'),
  250.                     ],
  251.                   ),
  252.                   _space,
  253.                   Row(
  254.                     mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  255.                     children: [
  256.                       IconButton(
  257.                         icon: const Icon(Icons.skip_previous),
  258.                         onPressed: _isPlayerReady
  259.                             ? () => _controller.load(_ids[
  260.                                 (_ids.indexOf(_controller.metadata.videoId) -
  261.                                         1) %
  262.                                     _ids.length])
  263.                             : null,
  264.                       ),
  265.                       IconButton(
  266.                         icon: Icon(
  267.                           _controller.value.isPlaying
  268.                               ? Icons.pause
  269.                               : Icons.play_arrow,
  270.                         ),
  271.                         onPressed: _isPlayerReady
  272.                             ? () {
  273.                                 _controller.value.isPlaying
  274.                                     ? _controller.pause()
  275.                                     : _controller.play();
  276.                                 setState(() {});
  277.                               }
  278.                             : null,
  279.                       ),
  280.                       IconButton(
  281.                         icon: Icon(_muted ? Icons.volume_off : Icons.volume_up),
  282.                         onPressed: _isPlayerReady
  283.                             ? () {
  284.                                 _muted
  285.                                     ? _controller.unMute()
  286.                                     : _controller.mute();
  287.                                 setState(() {
  288.                                   _muted = !_muted;
  289.                                 });
  290.                               }
  291.                             : null,
  292.                       ),
  293.                       FullScreenButton(
  294.                         controller: _controller,
  295.                         color: Colors.blueAccent,
  296.                       ),
  297.                       IconButton(
  298.                         icon: const Icon(Icons.skip_next),
  299.                         onPressed: _isPlayerReady
  300.                             ? () => _controller.load(_ids[
  301.                                 (_ids.indexOf(_controller.metadata.videoId) +
  302.                                         1) %
  303.                                     _ids.length])
  304.                             : null,
  305.                       ),
  306.                     ],
  307.                   ),
  308.                   _space,
  309.                   Row(
  310.                     children: <Widget>[
  311.                       const Text(
  312.                         "Volume",
  313.                         style: TextStyle(fontWeight: FontWeight.w300),
  314.                       ),
  315.                       Expanded(
  316.                         child: Slider(
  317.                           inactiveColor: Colors.transparent,
  318.                           value: _volume,
  319.                           min: 0.0,
  320.                           max: 100.0,
  321.                           divisions: 10,
  322.                           label: '${(_volume).round()}',
  323.                           onChanged: _isPlayerReady
  324.                               ? (value) {
  325.                                   setState(() {
  326.                                     _volume = value;
  327.                                   });
  328.                                   _controller.setVolume(_volume.round());
  329.                                 }
  330.                               : null,
  331.                         ),
  332.                       ),
  333.                     ],
  334.                   ),
  335.                   _space,
  336.                   AnimatedContainer(
  337.                     duration: const Duration(milliseconds: 800),
  338.                     decoration: BoxDecoration(
  339.                       borderRadius: BorderRadius.circular(20.0),
  340.                       color: _getStateColor(_playerState),
  341.                     ),
  342.                     padding: const EdgeInsets.all(8.0),
  343.                     child: Text(
  344.                       _playerState.toString(),
  345.                       style: const TextStyle(
  346.                         fontWeight: FontWeight.w300,
  347.                         color: Colors.white,
  348.                       ),
  349.                       textAlign: TextAlign.center,
  350.                     ),
  351.                   ),
  352.                 ],
  353.               ),
  354.             ),
  355.           ],
  356.         ),
  357.       ),
  358.     );
  359.   }
  360.  
  361.   Widget _text(String title, String value) {
  362.     return RichText(
  363.       text: TextSpan(
  364.         text: '$title : ',
  365.         style: const TextStyle(
  366.           color: Colors.blueAccent,
  367.           fontWeight: FontWeight.bold,
  368.         ),
  369.         children: [
  370.           TextSpan(
  371.             text: value ?? '',
  372.             style: const TextStyle(
  373.               color: Colors.blueAccent,
  374.               fontWeight: FontWeight.w300,
  375.             ),
  376.           ),
  377.         ],
  378.       ),
  379.     );
  380.   }
  381.  
  382.   Color _getStateColor(PlayerState state) {
  383.     switch (state) {
  384.       case PlayerState.unknown:
  385.         return Colors.grey[700];
  386.       case PlayerState.unStarted:
  387.         return Colors.pink;
  388.       case PlayerState.ended:
  389.         return Colors.red;
  390.       case PlayerState.playing:
  391.         return Colors.blueAccent;
  392.       case PlayerState.paused:
  393.         return Colors.orange;
  394.       case PlayerState.buffering:
  395.         return Colors.yellow;
  396.       case PlayerState.cued:
  397.         return Colors.blue[900];
  398.       default:
  399.         return Colors.blue;
  400.     }
  401.   }
  402.  
  403.   Widget get _space => const SizedBox(height: 10);
  404.  
  405.   Widget _loadCueButton(String action) {
  406.     return Expanded(
  407.       child: MaterialButton(
  408.         color: Colors.blueAccent,
  409.         onPressed: _isPlayerReady
  410.             ? () {
  411.                 if (_idController.text.isNotEmpty) {
  412.                   var id = YoutubePlayer.convertUrlToId(
  413.                     _idController.text,
  414.                   );
  415.                   if (action == 'LOAD') _controller.load(id);
  416.                   if (action == 'CUE') _controller.cue(id);
  417.                   FocusScope.of(context).requestFocus(FocusNode());
  418.                 } else {
  419.                   _showSnackBar('Source can\'t be empty!');
  420.                 }
  421.               }
  422.             : null,
  423.         disabledColor: Colors.grey,
  424.         disabledTextColor: Colors.black,
  425.         child: Padding(
  426.           padding: const EdgeInsets.symmetric(vertical: 14.0),
  427.           child: Text(
  428.             action,
  429.             style: const TextStyle(
  430.               fontSize: 18.0,
  431.               color: Colors.white,
  432.               fontWeight: FontWeight.w300,
  433.             ),
  434.             textAlign: TextAlign.center,
  435.           ),
  436.         ),
  437.       ),
  438.     );
  439.   }
  440.  
  441.   void _showSnackBar(String message) {
  442.     _scaffoldKey.currentState.showSnackBar(
  443.       SnackBar(
  444.         content: Text(
  445.           message,
  446.           textAlign: TextAlign.center,
  447.           style: const TextStyle(
  448.             fontWeight: FontWeight.w300,
  449.             fontSize: 16.0,
  450.           ),
  451.         ),
  452.         backgroundColor: Colors.blueAccent,
  453.         behavior: SnackBarBehavior.floating,
  454.         elevation: 1.0,
  455.         shape: RoundedRectangleBorder(
  456.           borderRadius: BorderRadius.circular(50.0),
  457.         ),
  458.       ),
  459.     );
  460.   }
  461. }
  462.  
Advertisement
Add Comment
Please, Sign In to add comment