在 Flutter 中关闭迷你播放器时 VideoPlayer 变黑
VideoPlayer becomes black when dismissing a miniplayer in Flutter
我有一个 miniplayer
,其中有一个视频小部件(我使用 better_player which depends on chewie and video_player)。一切都很好,除非我想关闭迷你播放器。视频被黑屏取代。我进行了一些调试,发现由于某种原因,dispose()
方法在我的 video_widget
上被调用了两次(当我开始关闭和结束关闭我的迷你播放器时)。以下是显示此行为的视频:
你能帮我解决这个问题吗?
编辑
我又调试了一下,发现可能和video widget
或者better_player包有关。我还发现,当使用 chewie 时,行为几乎相同,但当我开始关闭时,使用 chewie 视频会变黑一毫秒,然后再次初始化并从头开始播放。这是我的 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,);
}
);
}
}
这是我开始解雇时的日志
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 [video/avc] 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
我相信出于某种原因,当我开始关闭时,此小部件会调用 dispose()
方法。但为什么会发生这种情况,我该如何防止这种情况发生?
我找到了答案。问题出在迷你播放器包中。如果有人有同样的问题在这里评论,我会解释如何解决它。
我有一个 miniplayer
,其中有一个视频小部件(我使用 better_player which depends on chewie and video_player)。一切都很好,除非我想关闭迷你播放器。视频被黑屏取代。我进行了一些调试,发现由于某种原因,dispose()
方法在我的 video_widget
上被调用了两次(当我开始关闭和结束关闭我的迷你播放器时)。以下是显示此行为的视频:
你能帮我解决这个问题吗?
编辑
我又调试了一下,发现可能和video widget
或者better_player包有关。我还发现,当使用 chewie 时,行为几乎相同,但当我开始关闭时,使用 chewie 视频会变黑一毫秒,然后再次初始化并从头开始播放。这是我的 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,);
}
);
}
}
这是我开始解雇时的日志
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 [video/avc] 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
我相信出于某种原因,当我开始关闭时,此小部件会调用 dispose()
方法。但为什么会发生这种情况,我该如何防止这种情况发生?
我找到了答案。问题出在迷你播放器包中。如果有人有同样的问题在这里评论,我会解释如何解决它。