VideoPlayer becomes black when dismissing a miniplayer in Flutter

Issue

I have a miniplayer where I have a video widget (I use better_player which depends on chewie and video_player). Everything works great unless I want to dismiss the miniplayer. The video is replaced with black screen. I did some debugging and found out that for some reason the dispose() method is called on my video_widget twice (when I start dismissing and when I end dismissing my miniplayer). Below is a video which shows this behavior:

enter image description here

Could you help me with fixing this issue?

EDIT

I did some more debugging and found out that it is probably related with the video widget or better_player package. Also I found out that when using chewie behavior is nearly the same but with chewie when I start dismissing video gets black for a millisecond and then initializes again and starts playing from the beginning. Here is the code of my video widget class.

import 'dart:io';
import 'package:flutter/services.dart' show rootBundle;
import 'package:flutter/services.dart';
import 'package:cook_it/screens/longs_page/providers/providers.dart';
import 'package:path_provider/path_provider.dart';
import 'package:better_player/better_player.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';


class LongsVideoItem extends StatefulWidget {
  const LongsVideoItem({Key? key }) : super(key: key);


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

class _LongsVideoItemState extends State<LongsVideoItem> {

  void _toggleVideoControls(bool show){

    if (show){
      _betterPlayerController.setControlsEnabled(true);
    }else{
      _betterPlayerController.setControlsEnabled(false);

    }
  }

  Future _saveAssetVideoToFile() async {
    final content = await rootBundle.load("assets/videos/second.mp4");
    final directory = await getApplicationDocumentsDirectory();
    final file = File("${directory.path}/second.mp4");
    _directory = "${directory.path}/second.mp4";
    file.writeAsBytesSync(content.buffer.asUint8List());
  }

  BetterPlayerController _betterPlayerController = BetterPlayerController(const BetterPlayerConfiguration());

  dynamic _directory;


  @override
  void initState() {

    _saveAssetVideoToFile().then((value) {
      final BetterPlayerDataSource betterPlayerDataSource = BetterPlayerDataSource(
        BetterPlayerDataSourceType.file,
        _directory.toString(),
      );
      _betterPlayerController = BetterPlayerController(
        const BetterPlayerConfiguration(
          deviceOrientationsAfterFullScreen: [DeviceOrientation.portraitUp],
          aspectRatio: 16/9,
          autoPlay: true,
          controlsConfiguration:  BetterPlayerControlsConfiguration(showControlsOnInitialize: false),
        ),
        betterPlayerDataSource: betterPlayerDataSource,
      );
    });
    
    super.initState();
  }

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

  @override
  Widget build(BuildContext context) {

    return Consumer(
      
      builder: (context, watch, _){

        
        if (watch(videoShowControlsProvider).state == true){
          _toggleVideoControls(true);
        }else if (watch(videoShowControlsProvider).state == false){
          _toggleVideoControls(false);
        }

          return BetterPlayer(controller: _betterPlayerController,);
    
      }
    );
  }
}

here are the logs when I start dismissing

I/ExoPlayerImpl(16667): Release cd87770 [ExoPlayerLib/2.14.1] [HWCLT, CLT-L29, HUAWEI, 28] [goog.exo.core]
W/ACodec  (16667): forcing OMX state to Idle when received shutdown in ExecutingState
3
E/BufferQueueProducer(16667): [SurfaceTexture-0-16667-145] cancelBuffer: BufferQueue has been abandoned
I/chatty  (16667): uid=10234(com.example.cook_it) JNISurfaceTextu identical 10 lines
E/BufferQueueProducer(16667): [SurfaceTexture-0-16667-145] cancelBuffer: BufferQueue has been abandoned
D/SurfaceUtils(16667): disconnecting from surface 0x797bec7010, reason disconnectFromSurface
I/ExoPlayerImpl(16667): Init 8b84e21 [ExoPlayerLib/2.14.1] [HWCLT, CLT-L29, HUAWEI, 28]
V/AudioManager(16667): getStreamVolume  treamType: 3
V/AudioManager(16667): isStreamMute   streamType: 3
V/AudioManager(16667): getStreamMaxVolume  treamType: 3
E/        (16667): [ZeroHung]zrhung_get_config: Get config failed for wp[0x0008]
I/OMXClient(16667): IOmx service obtained
I/ACodec  (16667): In onAllocateComponent create compenent, codec name: OMX.hisi.video.decoder.avc
D/SurfaceUtils(16667): connecting to surface 0x797c027010, reason connectToSurface
I/MediaCodec(16667): [OMX.hisi.video.decoder.avc] setting surface generation to 17067154
D/SurfaceUtils(16667): disconnecting from surface 0x797c027010, reason connectToSurface(reconnect)
D/SurfaceUtils(16667): connecting to surface 0x797c027010, reason connectToSurface(reconnect)
E/ACodec  (16667): [OMX.hisi.video.decoder.avc] setPortMode on output to DynamicANWBuffer failed w/ err -2147483648
I/HwExtendedCodec(16667): mime is  at setVideoFormat
I/ACodec  (16667): codec does not support config priority (err -22)
2
I/ACodec  (16667): [OMX.hisi.video.decoder.avc] got color aspects (R:2(Limited), P:1(BT709_5), M:1(BT709_5), T:3(SMPTE170M)) err=0(NO_ERROR)
I/ACodec  (16667): [OMX.hisi.video.decoder.avc] using color aspects (R:2(Limited), P:1(BT709_5), M:1(BT709_5), T:3(SMPTE170M)) and dataspace 0x104
I/ACodec  (16667): onStart
D/SurfaceUtils(16667): disconnecting from surface 0x797c027010, reason setNativeWindowSizeFormatAndUsage
D/SurfaceUtils(16667): connecting to surface 0x797c027010, reason setNativeWindowSizeFormatAndUsage
D/SurfaceUtils(16667): set up nativeWindow 0x797c027010 for 1920x1080, color 0x30d, rotation 0, usage 0x20002900
6
W/MapperHal(16667): buffer descriptor with invalid usage bits 0x2000
2
I/ACodec  (16667): [OMX.hisi.video.decoder.avc] got color aspects (R:2(Limited), P:1(BT709_5), M:1(BT709_5), T:3(SMPTE170M)) err=0(NO_ERROR)
I/ACodec  (16667): [OMX.hisi.video.decoder.avc] using color aspects (R:2(Limited), P:1(BT709_5), M:1(BT709_5), T:3(SMPTE170M)) and dataspace 0x104
2
I/ACodec  (16667): [OMX.hisi.video.decoder.avc] got color aspects (R:2(Limited), P:1(BT709_5), M:1(BT709_5), T:3(SMPTE170M)) err=0(NO_ERROR)
I/ACodec  (16667): [OMX.hisi.video.decoder.avc] using color aspects (R:2(Limited), P:1(BT709_5), M:1(BT709_5), T:3(SMPTE170M)) and dataspace 0x104
D/SurfaceUtils(16667): disconnecting from surface 0x797c027010, reason setNativeWindowSizeFormatAndUsage
D/SurfaceUtils(16667): connecting to surface 0x797c027010, reason setNativeWindowSizeFormatAndUsage
D/SurfaceUtils(16667): set up nativeWindow 0x797c027010 for 1920x1088, color 0x30d, rotation 0, usage 0x20002900
W/ACodec  (16667): [OMX.hisi.video.decoder.avc] setting nBufferCountActual to 19 failed: -2147483648
18
W/MapperHal(16667): buffer descriptor with invalid usage bits 0x2000
I/ACodec  (16667): date space update : 0x104

I believe that for some reason this widget calls the dispose() method when I start dismissing. But why is that happening and how can I prevent that from happening?

Solution

I found the answer. The problem was in the miniplayer package. In case someone has the same problem comment here and I will explain how to fix it.

Answered By – Karp

Answer Checked By – David Goodson (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *