diff --git a/lib/widgets/viewer/overlay/bottom/video.dart b/lib/widgets/viewer/overlay/bottom/video.dart index a31a3c432..ff21a00f1 100644 --- a/lib/widgets/viewer/overlay/bottom/video.dart +++ b/lib/widgets/viewer/overlay/bottom/video.dart @@ -245,6 +245,18 @@ class _ButtonRow extends StatelessWidget { ); break; case VideoAction.captureFrame: + child = ValueListenableBuilder( + valueListenable: controller?.renderingVideoNotifier ?? ValueNotifier(false), + builder: (context, canDo, child) { + return IconButton( + icon: child!, + onPressed: canDo ? onPressed : null, + tooltip: action.getText(context), + ); + }, + child: Icon(action.getIcon()), + ); + break; case VideoAction.replay10: case VideoAction.selectStreams: case VideoAction.setSpeed: @@ -265,6 +277,7 @@ class _ButtonRow extends StatelessWidget { } PopupMenuEntry _buildPopupMenuItem(BuildContext context, VideoAction action) { + var enabled = true; Widget? child; switch (action) { case VideoAction.togglePlay: @@ -274,6 +287,9 @@ class _ButtonRow extends StatelessWidget { ); break; case VideoAction.captureFrame: + enabled = controller?.renderingVideoNotifier.value ?? false; + child = MenuRow(text: action.getText(context), icon: action.getIcon()); + break; case VideoAction.replay10: case VideoAction.selectStreams: case VideoAction.setSpeed: @@ -282,6 +298,7 @@ class _ButtonRow extends StatelessWidget { } return PopupMenuItem( value: action, + enabled: enabled, child: child, ); } diff --git a/lib/widgets/viewer/video/controller.dart b/lib/widgets/viewer/video/controller.dart index 792b5bdd1..5a32c1b28 100644 --- a/lib/widgets/viewer/video/controller.dart +++ b/lib/widgets/viewer/video/controller.dart @@ -27,6 +27,8 @@ abstract class AvesVideoController { Stream get statusStream; + ValueNotifier get renderingVideoNotifier; + bool get isReady; bool get isPlaying => status == VideoStatus.playing; diff --git a/lib/widgets/viewer/video/fijkplayer.dart b/lib/widgets/viewer/video/fijkplayer.dart index 3778293c1..ebd0d6761 100644 --- a/lib/widgets/viewer/video/fijkplayer.dart +++ b/lib/widgets/viewer/video/fijkplayer.dart @@ -38,6 +38,9 @@ class IjkPlayerAvesVideoController extends AvesVideoController { @override final double maxSpeed = 2; + @override + final ValueNotifier renderingVideoNotifier = ValueNotifier(false); + @override final ValueNotifier sarNotifier = ValueNotifier(1); @@ -52,6 +55,10 @@ class IjkPlayerAvesVideoController extends AvesVideoController { _staticInitialized = true; } _instance = FijkPlayer(); + _valueStream.firstWhere((value) => value.videoRenderStart).then( + (value) => renderingVideoNotifier.value = true, + onError: (error) {}, + ); _startListening(); } @@ -340,9 +347,13 @@ class IjkPlayerAvesVideoController extends AvesVideoController { return Map.fromEntries(_streams.map((stream) => MapEntry(stream, selectedIndices.contains(stream.index)))); } - // TODO TLAD [video] bug: crash when video stream is not supported @override - Future captureFrame() => _instance.takeSnapShot(); + Future captureFrame() { + if (!_instance.value.videoRenderStart) { + return Future.error('cannot capture frame when video is not rendered'); + } + return _instance.takeSnapShot(); + } @override Widget buildPlayerWidget(BuildContext context) {