LJaraCastillo / native_video_view

A video player widget displayed using the platform native player (VideoView in Android and AVPlayer in iOS).
MIT License
37 stars 30 forks source link

Memory Leak on iOS #5

Closed mentalmap closed 4 years ago

mentalmap commented 4 years ago

Environment

Flutter (Channel stable, v1.12.13+hotfix.9, on Mac OS X 10.15.4 19E287, locale zh-Hans-CN)

DEMO

import 'package:flutter/material.dart';
import 'package:native_video_view/native_video_view.dart';

void main() {
  runApp(MaterialApp(
    title: 'NativeView DEMO',
    debugShowCheckedModeBanner: false,
    theme: ThemeData(
      brightness: Brightness.light,
      primaryColor: Colors.cyan,
    ),
    home: MyApp(),
  ));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('NativeView DEMO'),
      ),
      body: Center(
        child: RaisedButton(
          child: Text('open video'),
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(
                builder: (context) => VideoPage(),
              ),
            );
          },
        ),
      ),
    );
  }
}

class VideoPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('NativeView DEMO'),
      ),
      body: Container(
        alignment: Alignment.center,
        child: NativeVideoView(
          keepAspectRatio: true,
          showMediaController: false,
          onCreated: (controller) {
            controller.setVideoSource(
              'assets/1.mov',
              sourceType: VideoSourceType.asset,
            );
          },
          onPrepared: (controller, info) {
            controller.play();
          },
          onError: (controller, what, extra, message) {
            print('Player Error ($what | $extra | $message)');
          },
          onCompletion: (controller) {
            print('Video completed');
          },
          onProgress: (progress, duration) {},
        ),
      ),
    );
  }
}

Click "open video" button, then back, repeat that

image

Upgrade to Flutter 1.17

image

Patch

diff --git a/ios/Classes/NativeVideoViewController.swift b/ios/Classes/NativeVideoViewController.swift
index d2439fd..5fe880b 100644
--- a/ios/Classes/NativeVideoViewController.swift
+++ b/ios/Classes/NativeVideoViewController.swift
@@ -19,10 +19,25 @@ public class NativeVideoViewController: NSObject, FlutterPlatformView {
         self.videoView = VideoView(frame: frame)
         self.methodChannel = FlutterMethodChannel(name: "native_video_view_\(viewId)", binaryMessenger: registrar.messenger())
         super.init()
-        self.videoView?.addOnPreparedObserver(callback: self.onPrepared)
-        self.videoView?.addOnFailedObserver(callback: self.onFailed(message:))
-        self.videoView?.addOnCompletionObserver(callback: self.onCompletion)
-        self.methodChannel.setMethodCallHandler(handle)
+        self.videoView?.addOnPreparedObserver {
+            [weak self] () -> Void in
+            self?.onPrepared()
+        }
+
+        self.videoView?.addOnFailedObserver {
+            [weak self] (message: String) -> Void in
+            self?.onFailed(message: message)
+        }
+
+        self.videoView?.addOnCompletionObserver {
+            [weak self] () -> Void in
+            self?.onCompletion()
+        }
+
+        self.methodChannel.setMethodCallHandler {
+            [weak self] (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
+            self?.handle(call: call, result: result)
+        }
     }

     deinit {

After Patch(Flutter 1.17)

image