flutter_vlc_player icon indicating copy to clipboard operation
flutter_vlc_player copied to clipboard

Portrait to FullScreen / Landscape mode is not working

Open Djain1764 opened this issue 2 years ago • 9 comments

I am trying to implement controls over vlc player and one of the main component is full screen mode which is something I have tried but not able to make it work, can someone please help me out here !!

Any help would be highly appreciated. Thanks

Djain1764 avatar Oct 06 '23 18:10 Djain1764

Please can anyone help me here in this issue !! @pinpong

Djain1764 avatar Oct 08 '23 09:10 Djain1764

To get help is always good to share a example app.

pinpong avatar Oct 08 '23 09:10 pinpong

Thanks for responding @pinpong Actually I am pretty new to flutter, and my aim is to make chewie work with vlcPlayerController instead of videoPlayerController so that I can use all of that features with vlcPlayer as vlc is the only player which can play .mkv in IOS in flutter and almost everything is working with chewie, but only full screen feature is creating issues.

When I try to push the same vlcPlayerController to the next page and try to play it, it gives the "Already Initialized" exception which is justified as chewie is again trying to reinitialize the initialized controller but I am not able to find any way to make the same controller portrait to landscape. It always becomes a simple black screen.

As a hack, what I tried which worked was, I made _viewId as public and commented "throw Exception('Already Initialized')" so it creates a new viewId when chewie tries to re-initialize the controller, and I set the time as same as the previous viewId so it can stay in sync, and similarly while popping landscape to portrait, I am setting viewId back to 0 and disposing the extra created platform, and setting the same time as landscape to maintain sync. But all of this seems pretty dangerous as I don't know why _viewId is kept private and why I should not comment the initialization exception. So @pinpong can you please please help me out here as I am stuck into this for a long time and have zero direction what to do now.

and let me paste the very basic problem I was in initially which is why I can't use the same controller in the next screen. so consider this example app, I have homescreen which is basically playing vlc in portrait mode initially and after navigating to fullscreen it becomes a pure black/white screen and it throws that initialization exception. so can you please tell me how can I avoid this in a proper way.

// HomeScreen.dart build method
 @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: Column(
          children: [
            Expanded(
              child: Center(
                child: Column(
                  children: [
                    VlcPlayer(
                      aspectRatio: 16 / 9,
                      controller: _videoPlayerController!,
                    ),
                    IconButton(
                        onPressed: () async {
                          await Navigator.of(context).push(MaterialPageRoute(
                              builder: ((context) => FullScreen(
                                    child: _videoPlayerController!,
                                  ))));
                        },
                        icon: const Icon(Icons.fullscreen_sharp))
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
  
  // FullScreen.dart build method
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: Stack(children: [
          AspectRatio(
            aspectRatio: 16 / 9,
            child: VlcPlayer(
              aspectRatio: 16 / 9,
              controller: widget.child,
            ),
          ),
          Positioned(
            right: 10,
            top: 10,
            child: IconButton(
              onPressed: () async {
                SystemChrome.setPreferredOrientations([
                  DeviceOrientation.portraitUp,
                  DeviceOrientation.portraitDown
                ]);
                Navigator.of(context).pop();
              },
              icon: const Icon(Icons.fullscreen_exit),
              color: Colors.cyan,
            ),
          )
        ]),
      ),
    );
  }

@pinpong , If possible please read my complete query to understand my workaround as I am stuck into this for a long time and any form of help is highly appreciated Above code is just a simple example to express my query, this is not my complete workaround

Djain1764 avatar Oct 08 '23 15:10 Djain1764

Hey @pinpong , if you get any chance, please help me know if this is possible ?

Djain1764 avatar Oct 10 '23 13:10 Djain1764

You can try something like:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_vlc_player/flutter_vlc_player.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
          useMaterial3: true,
          colorScheme: ColorScheme.fromSeed(seedColor: Colors.cyan)),
      home: const HomePage(),
    );
  }
}

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

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  late VlcPlayerController _videoPlayerController;

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

    _videoPlayerController = VlcPlayerController.network(
      'https://media.w3.org/2010/05/sintel/trailer.mp4',
      hwAcc: HwAcc.full,
      autoPlay: false,
    );
  }

  @override
  void dispose() async {
    super.dispose();
    await _videoPlayerController.stopRendererScanning();
    await _videoPlayerController.dispose();
  }

  _openFullScreen() async {
    final wasPlaying = await _videoPlayerController.isPlaying();
    _videoPlayerController.pause();
    final position = await _videoPlayerController.getPosition();
    await Navigator.of(context)
        .push(
          MaterialPageRoute(
            builder: ((context) => FullScreenPage(
                  position: position,
                )),
          ),
        )
        .then((value) =>
            wasPlaying == true ? _videoPlayerController.play() : null);
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: Column(
          children: [
            Expanded(
              child: Center(
                child: Column(
                  children: [
                    VlcPlayer(
                      aspectRatio: 16 / 9,
                      controller: _videoPlayerController,
                    ),
                    Row(
                      children: [
                        IconButton(
                            onPressed: _videoPlayerController.pause,
                            icon: const Icon(Icons.stop_outlined)),
                        IconButton(
                            onPressed: _videoPlayerController.play,
                            icon: const Icon(Icons.play_arrow_outlined)),
                        IconButton(
                            onPressed: _openFullScreen,
                            icon: const Icon(Icons.fullscreen_sharp))
                      ],
                    )
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class FullScreenPage extends StatefulWidget {
  final Duration position;

  const FullScreenPage({super.key, required this.position});

  @override
  State<FullScreenPage> createState() => _FullScreenPageState();
}

class _FullScreenPageState extends State<FullScreenPage> {
  late VlcPlayerController _videoPlayerController;

  @override
  void initState() {
    super.initState();
    _videoPlayerController = VlcPlayerController.network(
      'https://media.w3.org/2010/05/sintel/trailer.mp4',
      hwAcc: HwAcc.full,
      autoPlay: false,
    );

    _videoPlayerController.addOnInitListener(() async {
      /// TODO: seek to is not working, why?
      await _videoPlayerController.seekTo(widget.position);
      _videoPlayerController.play();
    });
  }

  @override
  void dispose() async {
    super.dispose();
    await _videoPlayerController.stopRendererScanning();
    await _videoPlayerController.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: Stack(children: [
          AspectRatio(
            aspectRatio: 16 / 9,
            child: VlcPlayer(
              aspectRatio: 16 / 9,
              controller: _videoPlayerController,
            ),
          ),
          Positioned(
            right: 10,
            top: 10,
            child: IconButton(
                onPressed: () async {
                  SystemChrome.setPreferredOrientations([
                    DeviceOrientation.portraitUp,
                    DeviceOrientation.portraitDown
                  ]);
                  Navigator.of(context).pop();
                },
                icon: const Icon(Icons.fullscreen_exit)),
          )
        ]),
      ),
    );
  }
}

pinpong avatar Oct 11 '23 15:10 pinpong

if you enter FullScreenPage,the _videoPlayerController is new create ,the video will reloading,hao to resove this problem

yuxingmin avatar May 11 '24 03:05 yuxingmin

仅仅通过控制position是不行的,如果网络差,还是需要重新加载的过程。用户体验不好。怎么通过overlay Entery实现

yuxingmin avatar Jun 21 '24 01:06 yuxingmin

I have the same problem, does anyone know how to solve it?

Gabriellsp avatar Jul 11 '24 19:07 Gabriellsp