Browse Source

播放器内存优化完成

gavin.chen 2 years ago
parent
commit
459f99e590

+ 44 - 9
lib/pages/canvas_player/widgets/canvas_player.dart

@@ -1,9 +1,11 @@
+import 'dart:async';
 import 'dart:collection';
 import 'dart:typed_data';
+import 'dart:ui';
 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';
+import 'package:flutter/material.dart' hide Image;
 import 'package:vid_player_demo/utils/image_holder.dart';
 import 'package:vid_player_demo/utils/utils.dart';
 import 'dart:ui' as ui;
@@ -48,6 +50,7 @@ class _VidCanvasPlayerState extends State<VidCanvasPlayer> {
     if (oldWidget.controller != widget.controller) {
       throw UnsupportedError("[VidTestPlayer] unsupport replace controller.");
     }
+    // image?.dispose(); //TODO 不知是否生效
     super.didUpdateWidget(oldWidget);
   }
 
@@ -69,21 +72,53 @@ class _VidCanvasPlayerState extends State<VidCanvasPlayer> {
   }
 
   void onFrameChanged(VidPlayerFrameIndexChangeEvent e) {
-    loadFrame(e.bytes);
+    loadFrame(e);
   }
 
-  void loadFrame(Uint8List bytes) async {
+  void loadFrame(VidPlayerFrameIndexChangeEvent e) async {
     // List<StackTrace>? debugList = image?.debugGetOpenHandleStackTraces();
     // print("${DateTime.now()} Load frame \n ${debugList.toString()}");
     // image?.dispose();
-    image = await decodeImageFromList(bytes);
-    print("${DateTime.now()} Load frame ${image?.width} x ${image?.height}");
+
+    image = await _loadImage(e.bytes);
+    // image = await decodeImageFromList(e.bytes);
+
+    /// 输出数组的前20位数字
+    // print(
+    //     "${e.width} x ${e.height} ${e.bytes.length} ${e.bytes.sublist(3000, 3020)}");
+    // print("${DateTime.now()} Load frame ${image?.width} x ${image?.height}");
     // holder = MyImageHolder(image!.clone());
-    image?.dispose();
-    // setState(() {});
+    setState(() {});
+    // image?.dispose();
+    // image?.dispose();
+
     countCurFPS();
   }
 
+  Future<Image> _loadImage(Uint8List bytes) async {
+    final Completer<Image> completer = Completer<Image>();
+    decodeVidFromList(bytes, (Image image) => completer.complete(image));
+
+    // ui.decodeImageFromList(bytes, (Image image) => completer.complete(image));
+
+    return completer.future;
+  }
+
+  void decodeVidFromList(Uint8List bytes, ImageDecoderCallback callback) async {
+    ImmutableBuffer.fromUint8List(bytes).then((ImmutableBuffer buffer) async {
+      final ImageDescriptor descriptor = await ImageDescriptor.encoded(buffer);
+      descriptor.instantiateCodec().then((Codec codec) {
+        final Future<FrameInfo> frameInfo = codec.getNextFrame();
+        codec.dispose();
+        return frameInfo;
+      }).then((FrameInfo frameInfo) {
+        buffer.dispose();
+        descriptor.dispose();
+        return callback(frameInfo.image);
+      });
+    });
+  }
+
   void updateFrame() {
     setState(() {});
   }
@@ -141,12 +176,12 @@ class _VidCanvasPlayerState extends State<VidCanvasPlayer> {
     if (image != null) {
       final size = MediaQuery.of(context).size;
       return CustomPaint(
-        painter: VidPainter(holder: holder!),
+        painter: VidPainter(image: image!),
         isComplex: false, //是否为复杂图像(true会缓存)
         size: size,
       );
     } else {
-      return Container();
+      return const Text("No holder");
     }
   }
 

+ 18 - 6
lib/pages/canvas_player/widgets/vid_painter.dart

@@ -1,15 +1,27 @@
 import 'package:flutter/material.dart';
-
-import 'package:vid_player_demo/utils/image_holder.dart';
+import 'dart:ui' as ui;
 
 class VidPainter extends CustomPainter {
-  VidPainter({required this.holder});
-  MyImageHolder holder;
+  VidPainter({required this.image});
+  ui.Image image;
 
   @override
   void paint(Canvas canvas, Size size) async {
-    holder.draw(canvas, size);
-    holder.dispose();
+    final double scale = size.width / image.width;
+    final double offsetY = (size.height - image.height * scale) / 2;
+
+    Paint paint = Paint();
+    canvas.save();
+    // canvas.scale(scale);
+    // canvas.drawImage(image, Offset(0, offsetY), paint);
+    canvas.drawImageRect(
+        image,
+        Rect.fromLTWH(0, 0, image.width.toDouble(), image.height.toDouble()),
+        Rect.fromLTWH(0, offsetY, size.width, image.height * scale),
+        paint);
+
+    canvas.restore();
+    image.dispose();
   }
 
   @override

+ 2 - 3
lib/pages/image_test/page.dart

@@ -11,14 +11,13 @@ class ImageTestPage extends StatefulWidget {
 
 class _ImageTestPageState extends State<ImageTestPage> {
   final imageNum = [
-    500,
-    500,
+    200,
+    200,
   ];
 
   final _playerStateController = Get.put(PlayerStateController());
   @override
   void initState() {
-    // TODO: implement initState
     super.initState();
   }
 

+ 8 - 6
lib/pages/image_test/view.dart

@@ -4,7 +4,7 @@ import 'dart:async';
 import 'dart:typed_data';
 import 'dart:ui';
 
-import 'package:flutter/material.dart' hide Image;
+import 'package:flutter/material.dart' hide Image, decodeImageFromList;
 import 'package:get/get.dart';
 import 'package:vid_player_demo/controller/player_controller.dart';
 
@@ -31,8 +31,7 @@ class _ImageTestViewState extends State<ImageTestView> {
   void clickPlay() async {
     print("${DateTime.now()} Click play");
     for (int i = 0; i < widget.imageNum; i++) {
-      image = await _loadImage(
-          776, 518, Color.fromARGB(i * 255 ~/ widget.imageNum, 0, 0, 0));
+      image = await _loadImage(776, 518);
       // final cloneImage = image.clone();
       print(
           "${DateTime.now()} load image $i ${image?.width} x ${image?.height}");
@@ -53,11 +52,14 @@ class _ImageTestViewState extends State<ImageTestView> {
     clickPlay();
   }
 
-  Future<Image> _loadImage(int width, int height, Color color) async {
+  Future<Image> _loadImage(int width, int height) async {
     final Completer<Image> completer = Completer<Image>();
+    // decodeImageFromList(
+    //   Uint8List.fromList(List<int>.filled(width * height * 4, 0xFF)),
+    //   (Image image) => completer.complete(image),
+    // );
     decodeImageFromPixels(
-      Uint8List.fromList(List<int>.filled(
-          width * height * 4, int.parse(color.value.toString()))),
+      Uint8List.fromList(List<int>.filled(width * height * 4, 0xFF)),
       width,
       height,
       PixelFormat.rgba8888,

+ 0 - 1
web/index.html

@@ -100,6 +100,5 @@
         loadMainDartJs();
       }
     </script>
-    <canvas id="vid-player" width="300" height="300" style="z-index: 9999;"></canvas>
   </body>
 </html>