video: prevent frame capture when video is not ready

This commit is contained in:
Thibault Deckers 2021-06-22 17:06:07 +09:00
parent 2e1622fc88
commit 7bedca9537
3 changed files with 32 additions and 2 deletions

View file

@ -245,6 +245,18 @@ class _ButtonRow extends StatelessWidget {
);
break;
case VideoAction.captureFrame:
child = ValueListenableBuilder<bool>(
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<VideoAction> _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,
);
}

View file

@ -27,6 +27,8 @@ abstract class AvesVideoController {
Stream<VideoStatus> get statusStream;
ValueNotifier<bool> get renderingVideoNotifier;
bool get isReady;
bool get isPlaying => status == VideoStatus.playing;

View file

@ -38,6 +38,9 @@ class IjkPlayerAvesVideoController extends AvesVideoController {
@override
final double maxSpeed = 2;
@override
final ValueNotifier<bool> renderingVideoNotifier = ValueNotifier(false);
@override
final ValueNotifier<double> 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<Uint8List> captureFrame() => _instance.takeSnapShot();
Future<Uint8List> captureFrame() {
if (!_instance.value.videoRenderStart) {
return Future.error('cannot capture frame when video is not rendered');
}
return _instance.takeSnapShot();
}
@override
Widget buildPlayerWidget(BuildContext context) {