Advertisement
painkili3r

Untitled

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