youtube_player_flutter icon indicating copy to clipboard operation
youtube_player_flutter copied to clipboard

No progress bar and No buttons on full screen[BUG]

Open alexaung opened this issue 1 year ago • 2 comments

Describe the bug When click full screen button, change to full screen mode. But there is no progress bar or button. Only show title and share button on top when touch the screen.

To Reproduce Steps to reproduce the behavior:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:youtube_player_iframe/youtube_player_iframe.dart' as yt;

void main() {
  runApp( MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'My App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const VideoScreen(),
    );
  }
}

class VideoScreen extends StatefulWidget {
  static const routeName = '/video';
  const VideoScreen({Key? key}) : super(key: key);

  @override
  State<VideoScreen> createState() => _VideoScreenState();
}

class _VideoScreenState extends State<VideoScreen> {
  bool _isFullScreen = false;
  late yt.YoutubePlayerController _controller;

  @override
  void initState() {
    super.initState();

    _controller = yt.YoutubePlayerController.fromVideoId(
      videoId: 'dQw4w9WgXcQ',
      autoPlay: false,
      params: const yt.YoutubePlayerParams(
        showControls: true,
        showFullscreenButton: true,
      ),
    );

    _controller.setFullScreenListener((isFullScreen) {
      if (isFullScreen) {
        SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive);
        SystemChrome.setPreferredOrientations([
          DeviceOrientation.landscapeLeft,
          DeviceOrientation.landscapeRight,
        ]);
      } else {
        SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
            overlays: SystemUiOverlay.values);
        SystemChrome.setPreferredOrientations([
          DeviceOrientation.portraitDown,
          DeviceOrientation.portraitUp,
        ]);
      }

      setState(() {
        _isFullScreen = isFullScreen;
      });
    });
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: _isFullScreen
          ? null
          : AppBar(
              centerTitle: true,
              title: const Text("Youtube Live"),
              leading: IconButton(
                onPressed: () {
                  Navigator.pop(context);
                },
                icon: const Icon(
                  Icons.arrow_back,
                ),
              ),
            ),
      body: yt.YoutubePlayerControllerProvider(
        controller: _controller,
        child: ListView(
          children: [
            yt.YoutubePlayer(
              controller: _controller,
              aspectRatio: 16 / 9,
            ),
            // ... Other children widgets ...
          ],
        ),
      ),
    );
  }
}

Expected behavior Should show the player like real youtube.

Screenshots If applicable, add screenshots to help explain your problem.

Technical Details:

  • Device: [All Devices]
  • OS: [e.g. iOS8.1]
  • Version
  • youtube_player_iframe: ^4.0.4

Additional context Flutter (Channel stable, 3.10.5, on macOS 13.4.1 22F82 darwin-x64, locale en-GB) • Flutter version 3.10.5 on channel stable at /Users/aungmyooo/Development/flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision 796c8ef792 (4 weeks ago), 2023-06-13 15:51:02 -0700 • Engine revision 45f6e00911 • Dart version 3.0.5 • DevTools version 2.23.1

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0) • Android SDK at /Users/aungmyooo/Library/Android/sdk • Platform android-34, build-tools 33.0.0 • ANDROID_HOME = /Users/aungmyooo/Library/Android/sdk • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694) • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.3.1) • Xcode at /Applications/Xcode.app/Contents/Developer • Build 14E300c • CocoaPods version 1.11.3

[✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2022.2) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)

[✓] VS Code (version 1.80.0) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.68.0

[✓] Connected device (4 available) • SM N975F (mobile) • RF8M82Y3K9A • android-arm64 • Android 12 (API 31) • Aung Myo’s iPhone (mobile) • 06e02964e429eeebf29550b03ef955abe09891ef • ios • iOS 16.5.1 20F75 • macOS (desktop) • macos • darwin-x64 • macOS 13.4.1 22F82 darwin-x64 • Chrome (web) • chrome • web-javascript • Google Chrome 114.0.5735.198

[✓] Network resources • All expected network resources are available.

alexaung avatar Jul 11 '23 16:07 alexaung

youtube_player_iframe: ^2.3.0 is working perfect.

import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:thitsarparami/blocs/bloc.dart';
import 'package:thitsarparami/helper/constants.dart';
import 'package:thitsarparami/helper/enum.dart';
import 'package:thitsarparami/ui/error/something_went_wrong.dart';
import 'package:thitsarparami/widgets/circular_progress_indicator_widget.dart';
import 'package:transparent_image/transparent_image.dart';
import 'package:youtube_player_iframe/youtube_player_iframe.dart';

import '../../helper/ad_helper.dart';
import '../../widgets/native_template_ad.dart';

class VideoScreen extends StatefulWidget {
  static const routeName = '/video';
  //final Video video;
  const VideoScreen({Key? key}) : super(key: key);

  @override
  VideoScreenState createState() => VideoScreenState();
}

class VideoScreenState extends State<VideoScreen> {
  @override
  void initState() {
    super.initState();
    _loadYoutube();
  }

  _loadYoutube() async {
    List<String> codes = [
      systemDataCodeToString(SystemDataCode.youtube_live),
    ];
    BlocProvider.of<SystemDataBloc>(context).add(GetYoutubeLiveEvent(codes));
  }

  bool shouldPop = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        backgroundColor: Theme.of(context).scaffoldBackgroundColor,
        elevation: 0,
        title: AutoSizeText(
          kYouTubeChannel,
          style: Theme.of(context).appBarTheme.titleTextStyle,
        ),
        leading: IconButton(
          onPressed: () {
            Navigator.pop(context);
          },
          icon: Icon(
            Icons.arrow_back,
            color: Theme.of(context).primaryIconTheme.color!,
          ),
        ),
      ),
      body: BlocBuilder<SystemDataBloc, SystemDataState>(
        builder: (context, state) {
          if (state is SystemDataError) {
            return SomethingWentWrongScreen(
                error: state.error, screenName: 'Video Screen');
          } else if (state is YoutubeLiveDataLoaded) {
            return MyYoutubePlayer(
              videoId: state.systemData.youtubeLive!.videoId!,
              title: state.systemData.youtubeLive!.videoTitle!,
            );
          }
          return const CircularProgressIndicatorWidget();
        },
      ),
    );
  }
}

class MyYoutubePlayer extends StatefulWidget {
  final String videoId;
  final String title;
  const MyYoutubePlayer({Key? key, required this.videoId, required this.title})
      : super(key: key);

  @override
  State<MyYoutubePlayer> createState() => _MyYoutubePlayerState();
}

class _MyYoutubePlayerState extends State<MyYoutubePlayer> {
  late YoutubePlayerController _controller;

  @override
  void initState() {
    _controller = YoutubePlayerController(
      initialVideoId: widget.videoId,
      params: YoutubePlayerParams(
        playlist: [
          widget.videoId,
        ],
        showControls: true,
        showFullscreenButton: true,
        desktopMode: false,
        privacyEnhanced: true,
        useHybridComposition: true,
      ),
    );

    _controller.onEnterFullscreen = () {
      SystemChrome.setPreferredOrientations([
        DeviceOrientation.landscapeLeft,
        DeviceOrientation.landscapeRight,
      ]);
      //log('Entered Fullscreen');
    };
    _controller.onExitFullscreen = () {
      SystemChrome.setPreferredOrientations([
        DeviceOrientation.portraitDown,
        DeviceOrientation.portraitUp,
      ]);
      //log('Exited Fullscreen');
    };

    super.initState();
  }

  @override
  void dispose() {
    super.dispose();

    _controller.close();
  }

  @override
  Widget build(BuildContext context) {
    const player = YoutubePlayerIFrame();
    return YoutubePlayerControllerProvider(
      // Passing controller to widgets below.
      controller: _controller,
      child: LayoutBuilder(
        builder: (context, constraints) {
          return ListView(
            children: [
              Stack(
                children: [
                  player,
                  Positioned.fill(
                    child: YoutubeValueBuilder(
                      controller: _controller,
                      builder: (context, value) {
                        return AnimatedCrossFade(
                          firstChild: const SizedBox.shrink(),
                          secondChild: Material(
                            child: DecoratedBox(
                              decoration: BoxDecoration(
                                image: DecorationImage(
                                  image: FadeInImage.memoryNetwork(
                                    image: YoutubePlayerController.getThumbnail(
                                      videoId:
                                          _controller.params.playlist.first,
                                      quality: ThumbnailQuality.medium,
                                    ),
                                    placeholder: kTransparentImage,
                                    imageErrorBuilder:
                                        (context, error, stackTrace) {
                                      return Container(color: Colors.grey);
                                    },
                                  ).image,
                                  fit: BoxFit.fitWidth,
                                ),
                              ),
                              child: const Center(
                                child: CircularProgressIndicator(),
                              ),
                            ),
                          ),
                          crossFadeState: value.isReady
                              ? CrossFadeState.showFirst
                              : CrossFadeState.showSecond,
                          duration: const Duration(milliseconds: 300),
                        );
                      },
                    ),
                  ),
                ],
              ),
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: Text(
                  widget.title,
                  style: const TextStyle(
                      color: Colors.black,
                      fontSize: 16.0,
                      fontWeight: FontWeight.bold),
                ),
              ),
              const SizedBox(
                height: 20,
              ),
              Container(
                padding: const EdgeInsets.all(10.0),
                child: NativeTemplateAd(
                  adUnitId: AdHelper.nativeAdUnitId,
                  templateType: TemplateType.medium,
                ),
              ),
            ],
          );
        },
      ),
    );
  }
}

alexaung avatar Jul 11 '23 16:07 alexaung

Finally I can upgrade to youtube_player_iframe: ^4.0.4. Below code is working with full screen.

import 'package:flutter/material.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:thitsarparami/helper/ad_helper.dart';
import 'package:thitsarparami/helper/constants.dart';
import 'package:thitsarparami/widgets/custom_app_bar.dart';
import 'package:thitsarparami/widgets/native_template_ad.dart';
import 'package:youtube_player_iframe/youtube_player_iframe.dart';

class MyYoutubePlayer extends StatefulWidget {
  final String videoId;
  final String title;
  const MyYoutubePlayer(
      {super.key, required this.videoId, required this.title});

  @override
  State<MyYoutubePlayer> createState() => _MyYoutubePlayerState();
}

class _MyYoutubePlayerState extends State<MyYoutubePlayer> {
  late YoutubePlayerController _controller;
  bool _isFullscreen = false;

  @override
  void initState() {
    super.initState();
    _initYoutubePlayer();
  }

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

  void _initYoutubePlayer() {
    _controller = YoutubePlayerController.fromVideoId(
      videoId: widget.videoId,
      params: const YoutubePlayerParams(
        enableJavaScript: false,
        loop: false,
        mute: false,
        playsInline: true,
        showControls: true,
        showFullscreenButton: true,
        showVideoAnnotations: false,
      ),
    );

    _controller.setFullScreenListener((isFullScreen) {
      setState(() {
        _isFullscreen = isFullScreen;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: _isFullscreen
          ? null
          : CustomAppBar(
              title: kYouTubeChannel,
              onBackPressed: () {
                Navigator.pop(context);
              },
            ),
      body: YoutubePlayerScaffold(
        controller: _controller,
        builder: (context, player) {
          return Column(
            children: [
              player,
              Container(
                padding: const EdgeInsets.all(10.0),
                child: NativeTemplateAd(
                  adUnitId: AdHelper.nativeAdUnitId,
                  templateType: TemplateType.medium,
                ),
              )
            ],
          );
        },
      ),
    );
  }
}


alexaungmyooo avatar Jan 29 '24 10:01 alexaungmyooo