|
@@ -1,3 +1,4 @@
|
|
|
+import 'dart:collection';
|
|
|
import 'dart:typed_data';
|
|
|
import 'package:fis_measure/view/frame_view/native/frame_view.dart';
|
|
|
import 'package:fis_measure/view/player/controller.dart';
|
|
@@ -25,6 +26,10 @@ class VidImagePlayer extends StatefulWidget {
|
|
|
|
|
|
class _VidImagePlayerState extends State<VidImagePlayer> {
|
|
|
Uint8List? frameBytes;
|
|
|
+ DateTime lastFrameTime = DateTime.now();
|
|
|
+ ListQueue<int> frames = ListQueue<int>()..addFirst(30); //预留一位防止分母为0
|
|
|
+ int maxFramesNum = 10;
|
|
|
+ int curFPS = 30;
|
|
|
|
|
|
@override
|
|
|
void initState() {
|
|
@@ -58,6 +63,7 @@ class _VidImagePlayerState extends State<VidImagePlayer> {
|
|
|
}
|
|
|
|
|
|
void onFrameChanged(VidPlayerFrameIndexChangeEvent e) {
|
|
|
+ countCurFPS(); //计算视频帧率
|
|
|
setState(() {
|
|
|
frameBytes = e.bytes;
|
|
|
});
|
|
@@ -67,41 +73,51 @@ class _VidImagePlayerState extends State<VidImagePlayer> {
|
|
|
setState(() {});
|
|
|
}
|
|
|
|
|
|
+ void countCurFPS() {
|
|
|
+ int fps = 1000 ~/ DateTime.now().difference(lastFrameTime).inMilliseconds;
|
|
|
+ lastFrameTime = DateTime.now();
|
|
|
+ frames.addFirst(fps);
|
|
|
+ while (frames.length > maxFramesNum) {
|
|
|
+ frames.removeLast();
|
|
|
+ }
|
|
|
+ curFPS = frames.reduce((a, b) => a + b) ~/ frames.length;
|
|
|
+ }
|
|
|
+
|
|
|
@override
|
|
|
Widget build(BuildContext context) {
|
|
|
Widget? child;
|
|
|
switch (widget.controller.status) {
|
|
|
case VidPlayStatus.init:
|
|
|
- child = Container(child: const Text("Loading"));
|
|
|
+ child = const Text("Loading");
|
|
|
break;
|
|
|
case VidPlayStatus.ready:
|
|
|
- child = Container(child: const Text("Ready"));
|
|
|
+ child = const Text("Ready");
|
|
|
break;
|
|
|
case VidPlayStatus.loadFail:
|
|
|
- child = Container(child: const Text("Load fail"));
|
|
|
+ child = const Text("Load fail");
|
|
|
break;
|
|
|
case VidPlayStatus.play:
|
|
|
case VidPlayStatus.pause:
|
|
|
- // return buildFrameView(context);
|
|
|
- // child = Container(
|
|
|
- // child: Text(
|
|
|
- // widget.controller.currentFrameIndex.toString(),
|
|
|
- // ),
|
|
|
- // );
|
|
|
child = buildFrameView(context);
|
|
|
break;
|
|
|
case VidPlayStatus.stop:
|
|
|
case VidPlayStatus.dispose:
|
|
|
- child = Container(child: const Text("Closed"));
|
|
|
+ child = const Text("Closed");
|
|
|
break;
|
|
|
}
|
|
|
return buildBox(context, child);
|
|
|
}
|
|
|
|
|
|
+ ///创建播放器容器,可以在此叠加信息
|
|
|
Widget buildBox(BuildContext context, Widget child) {
|
|
|
- return Container(
|
|
|
- alignment: Alignment.center,
|
|
|
- child: child,
|
|
|
+ return Stack(
|
|
|
+ children: [
|
|
|
+ Text("当前帧:${widget.controller.currentFrameIndex}\n 估算平均帧率:$curFPS fps"),
|
|
|
+ Container(
|
|
|
+ alignment: Alignment.center,
|
|
|
+ child: child,
|
|
|
+ ),
|
|
|
+ ],
|
|
|
);
|
|
|
}
|
|
|
|
|
@@ -110,8 +126,6 @@ class _VidImagePlayerState extends State<VidImagePlayer> {
|
|
|
final size = MediaQuery.of(context).size;
|
|
|
return VidFrameView(
|
|
|
frameBytes!,
|
|
|
- // width: widget.width,
|
|
|
- // height: widget.height,
|
|
|
width: size.width,
|
|
|
height: size.height,
|
|
|
);
|