|
@@ -0,0 +1,128 @@
|
|
|
+import 'dart:typed_data';
|
|
|
+import 'package:fis_measure/view/frame_view/native/frame_view.dart';
|
|
|
+import 'package:fis_measure/view/player/controller.dart';
|
|
|
+import 'package:fis_measure/view/player/enums.dart';
|
|
|
+import 'package:fis_measure/view/player/events.dart';
|
|
|
+import 'package:flutter/material.dart';
|
|
|
+
|
|
|
+///基于Canvas组件的播放器
|
|
|
+class VidCanvasPlayer extends StatefulWidget {
|
|
|
+ const VidCanvasPlayer(
|
|
|
+ this.controller, {
|
|
|
+ Key? key,
|
|
|
+ this.width,
|
|
|
+ this.height,
|
|
|
+ }) : super(key: key);
|
|
|
+
|
|
|
+ final VidPlayerController controller;
|
|
|
+
|
|
|
+ final double? width;
|
|
|
+ final double? height;
|
|
|
+
|
|
|
+ @override
|
|
|
+ State<StatefulWidget> createState() => _VidCanvasPlayerState();
|
|
|
+}
|
|
|
+
|
|
|
+class _VidCanvasPlayerState extends State<VidCanvasPlayer> {
|
|
|
+ Uint8List? frameBytes;
|
|
|
+
|
|
|
+ @override
|
|
|
+ void initState() {
|
|
|
+ widget.controller.eventHandler.addListener(onControllerEvent);
|
|
|
+ super.initState();
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ void didUpdateWidget(covariant VidCanvasPlayer oldWidget) {
|
|
|
+ if (oldWidget.controller != widget.controller) {
|
|
|
+ throw UnsupportedError("[VidTestPlayer] unsupport replace controller.");
|
|
|
+ }
|
|
|
+ super.didUpdateWidget(oldWidget);
|
|
|
+ }
|
|
|
+
|
|
|
+ void onControllerEvent(Object sender, VidPlayerEvent e) {
|
|
|
+ if (e is VidPlayerStatusChangeEvent) {
|
|
|
+ if (!widget.controller.hasView) {
|
|
|
+ setState(() {});
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (e is VidPlayerFrameIndexChangeEvent) {
|
|
|
+ onFrameChanged(e);
|
|
|
+ }
|
|
|
+ if (e is VidPlayerBrightnessChangeEvent) {
|
|
|
+ updateFrame();
|
|
|
+ }
|
|
|
+ if (e is VidPlayerContrastChangeEvent) {
|
|
|
+ updateFrame();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void onFrameChanged(VidPlayerFrameIndexChangeEvent e) {
|
|
|
+ setState(() {
|
|
|
+ frameBytes = e.bytes;
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ void updateFrame() {
|
|
|
+ setState(() {});
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ Widget build(BuildContext context) {
|
|
|
+ Widget? child;
|
|
|
+ switch (widget.controller.status) {
|
|
|
+ case VidPlayStatus.init:
|
|
|
+ child = Container(child: const Text("Loading"));
|
|
|
+ break;
|
|
|
+ case VidPlayStatus.ready:
|
|
|
+ child = Container(child: const Text("Ready"));
|
|
|
+ break;
|
|
|
+ case VidPlayStatus.loadFail:
|
|
|
+ child = Container(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"));
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return buildBox(context, child);
|
|
|
+ }
|
|
|
+
|
|
|
+ Widget buildBox(BuildContext context, Widget child) {
|
|
|
+ return Container(
|
|
|
+ alignment: Alignment.center,
|
|
|
+ child: child,
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ Widget buildFrameView(BuildContext context) {
|
|
|
+ if (frameBytes != null) {
|
|
|
+ final size = MediaQuery.of(context).size;
|
|
|
+ return VidFrameView(
|
|
|
+ frameBytes!,
|
|
|
+ // width: widget.width,
|
|
|
+ // height: widget.height,
|
|
|
+ width: size.width,
|
|
|
+ height: size.height,
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ return Container();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ void dispose() {
|
|
|
+ widget.controller.eventHandler.removeListener(onControllerEvent);
|
|
|
+ super.dispose();
|
|
|
+ }
|
|
|
+}
|