Переглянути джерело

ijk控制器逻辑部分完成

cjl_macbook 6 роки тому
батько
коміт
2eb3470fc6

+ 1 - 0
.gitignore

@@ -5,3 +5,4 @@
 .pub/
 
 build/
+.idea

+ 1 - 1
android/src/main/java/top/kikt/ijkplayer/Ijk.kt

@@ -101,7 +101,7 @@ class Ijk(private val registry: PluginRegistry.Registrar) : MethodChannel.Method
                 currentPosition = currentPosition.toDouble() / 1000,
                 width = width,
                 height = height,
-                isPlaying = ijkPlayer.isPlaying
+                isPlaying = mediaPlayer.isPlaying
         )
     }
 

+ 8 - 2
android/src/main/java/top/kikt/ijkplayer/NotifyChannel.kt

@@ -2,6 +2,7 @@ package top.kikt.ijkplayer
 
 import io.flutter.plugin.common.MethodChannel
 import io.flutter.plugin.common.PluginRegistry
+import tv.danmaku.ijk.media.player.IMediaPlayer
 
 class NotifyChannel(val registry: PluginRegistry.Registrar, val textureId: Long, val ijk: Ijk) {
 
@@ -38,7 +39,12 @@ class NotifyChannel(val registry: PluginRegistry.Registrar, val textureId: Long,
             false
         }
         player.setOnInfoListener { mp, what, extra ->
-            logi("onInfoListener $what")
+            logi("onInfoListener $what, extra = $extra, isPlaying = ${player.isPlaying} ")
+            when (what) {
+                IMediaPlayer.MEDIA_INFO_AUDIO_DECODED_START, IMediaPlayer.MEDIA_INFO_VIDEO_DECODED_START -> {
+                    channel.invokeMethod("playStateChange", info)
+                }
+            }
             false
         }
         player.setOnNativeInvokeListener { what, args ->
@@ -46,7 +52,7 @@ class NotifyChannel(val registry: PluginRegistry.Registrar, val textureId: Long,
             false
         }
         player.setOnControlMessageListener {
-            logi("onController message $it")
+            logi("onController message $it, isPlaying = ${player.isPlaying}")
             ""
         }
     }

+ 1 - 1
android/src/main/java/top/kikt/ijkplayer/entity/Info.kt

@@ -15,7 +15,7 @@ data class Info(
         map["currentPosition"] = currentPosition
         map["width"] = width
         map["height"] = height
-        map["playing"] = isPlaying
+        map["isPlaying"] = isPlaying
         return map
     }
 

+ 10 - 3
example/lib/main.dart

@@ -61,7 +61,7 @@ class HomePageState extends State<HomePage> {
             AspectRatio(
               aspectRatio: 1280 / 720,
               child: IjkPlayer(
-                controller: controller,
+                mediaController: controller,
               ),
             ),
             _buildPlayAssetButton(),
@@ -171,9 +171,16 @@ class HomePageState extends State<HomePage> {
     return Row(
       children: <Widget>[
         FlatButton(
-          child: Text("播放"),
+          child: StreamBuilder<bool>(
+            stream: controller.playingStream,
+            initialData: controller.isPlaying,
+            builder: (context, snapshot) {
+              var isPlaying = snapshot.data;
+              return Text(isPlaying ? "暂停" : "播放");
+            },
+          ),
           onPressed: () async {
-            await controller?.play();
+            await controller?.playOrPause();
           },
         ),
         FlatButton(

+ 2 - 0
lib/flutter_ijkplayer.dart

@@ -1,2 +1,4 @@
 export 'src/ijkplayer.dart';
 export 'src/error.dart';
+export 'src/video_info.dart';
+export 'src/controller_builder_delegate.dart' show DefaultControllerWidget;

+ 38 - 13
lib/src/controller.dart

@@ -13,12 +13,21 @@ class IjkMediaController extends ChangeNotifier {
 
   bool _isPlaying = false;
 
-  bool get isPlaying => _isPlaying;
+  bool get isPlaying => _isPlaying == true;
 
   set isPlaying(bool value) {
     this._isPlaying = value;
+    _playingController.add(value);
   }
 
+  StreamController<bool> _playingController = StreamController.broadcast();
+
+  Stream<bool> get playingStream => _playingController.stream;
+
+  StreamController<VideoInfo> _videoInfoController = StreamController.broadcast();
+
+  Stream<VideoInfo> get videoInfoStream => _videoInfoController.stream;
+
   Future<void> _initIjk() async {
     try {
       var id = await _createIjk();
@@ -32,14 +41,20 @@ class IjkMediaController extends ChangeNotifier {
     }
   }
 
-  void dispose() {
+  void dispose() async {
+    await reset();
+    _playingController.close();
+    _videoInfoController.close();
+    super.dispose();
+  }
+
+  Future<void> reset() async {
     this.textureId = null;
     this.notifyListeners();
     _plugin?.dispose();
     _plugin = null;
     eventChannel?.dispose();
     eventChannel = null;
-    super.dispose();
   }
 
   Future<void> setNetworkDataSource(
@@ -86,38 +101,46 @@ class IjkMediaController extends ChangeNotifier {
   }
 
   Future<void> playOrPause() async {
-    var playing = isPlaying == true;
+    var videoInfo = await getVideoInfo();
+    print(videoInfo);
+
+    var playing = videoInfo.isPlaying;
     if (playing) {
       await _plugin?.pause();
-      playing = false;
     } else {
       await _plugin?.play();
-      playing = true;
     }
-    this.notifyListeners();
+    refreshVideoInfo();
   }
 
   Future<void> play() async {
     await _plugin?.play();
-    this.notifyListeners();
+    refreshVideoInfo();
   }
 
   Future<void> pause() async {
     await _plugin?.pause();
-    this.notifyListeners();
+    refreshVideoInfo();
   }
 
   Future<void> seekTo(double target) async {
     await _plugin?.seekTo(target);
+    refreshVideoInfo();
   }
 
   Future<VideoInfo> getVideoInfo() async {
     Map<String, dynamic> result = await _plugin?.getInfo();
     var info = VideoInfo.fromMap(result);
-    isPlaying = info.isPlaying;
     return info;
   }
 
+  Future<void> refreshVideoInfo() async {
+    var info = await getVideoInfo();
+    isPlaying = info.isPlaying;
+    _videoInfoController.add(info);
+    this.notifyListeners();
+  }
+
   void _autoPlay(bool autoPlay) {
     if (autoPlay) {
       eventChannel.autoPlay(this);
@@ -125,9 +148,11 @@ class IjkMediaController extends ChangeNotifier {
   }
 
   Future<void> stop() async {
-    await _plugin?.stop();
-    isPlaying = false;
-    this.notifyListeners();
+//    await _plugin?.stop();
+//    refreshVideoInfo();
+    await _plugin.pause();
+    await _plugin.seekTo(0);
+    refreshVideoInfo();
   }
 }
 

+ 23 - 0
lib/src/controller_builder_delegate.dart

@@ -0,0 +1,23 @@
+import 'package:flutter/widgets.dart';
+import './ijkplayer.dart';
+
+Widget defaultBuildIjkControllerWidget(IjkMediaController controller) {
+  return DefaultControllerWidget(controller);
+}
+
+class DefaultControllerWidget extends StatefulWidget {
+  final IjkMediaController controller;
+
+  const DefaultControllerWidget(this.controller);
+
+  @override
+  _DefaultControllerWidgetState createState() =>
+      _DefaultControllerWidgetState();
+}
+
+class _DefaultControllerWidgetState extends State<DefaultControllerWidget> {
+  @override
+  Widget build(BuildContext context) {
+    return Container();
+  }
+}

+ 32 - 14
lib/src/ijkplayer.dart

@@ -7,19 +7,28 @@ import 'package:flutter_ijkplayer/src/ijk_event_channel.dart';
 import 'package:flutter_ijkplayer/src/video_info.dart';
 import './error.dart';
 
+import './controller_builder_delegate.dart';
+
 part './controller.dart';
 
+typedef Widget ControllerWidgetBuilder(IjkMediaController controller);
+
 class IjkPlayer extends StatefulWidget {
-  final IjkMediaController controller;
+  final IjkMediaController mediaController;
+  final ControllerWidgetBuilder controllerWidgetBuilder;
 
-  const IjkPlayer({Key key, this.controller}) : super(key: key);
+  const IjkPlayer({
+    Key key,
+    this.mediaController,
+    this.controllerWidgetBuilder = defaultBuildIjkControllerWidget,
+  }) : super(key: key);
 
   @override
-  _IjkPlayerState createState() => _IjkPlayerState();
+  IjkPlayerState createState() => IjkPlayerState();
 }
 
-class _IjkPlayerState extends State<IjkPlayer> {
-  IjkMediaController get controller => widget.controller;
+class IjkPlayerState extends State<IjkPlayer> {
+  IjkMediaController controller;
 
   StreamController<int> _streamController = StreamController.broadcast();
 
@@ -28,6 +37,7 @@ class _IjkPlayerState extends State<IjkPlayer> {
   @override
   void initState() {
     super.initState();
+    controller = widget.mediaController ?? IjkMediaController();
     controller?.addListener(updateTextureId);
   }
 
@@ -46,17 +56,25 @@ class _IjkPlayerState extends State<IjkPlayer> {
 
   @override
   Widget build(BuildContext context) {
-    return StreamBuilder<int>(
-        stream: stream,
-        builder: (context, snapshot) {
-          if (!snapshot.hasData) {
-            return Container();
-          }
-          return _buildContent(snapshot.data);
-        });
+    var video = StreamBuilder<int>(
+      stream: stream,
+      builder: (context, snapshot) {
+        if (!snapshot.hasData) {
+          return Container();
+        }
+        return _buildVideoContent(snapshot.data);
+      },
+    );
+    var controllerWidget = widget.controllerWidgetBuilder?.call(controller);
+    return Stack(
+      children: <Widget>[
+        video,
+        controllerWidget,
+      ],
+    );
   }
 
-  Widget _buildContent(int id) {
+  Widget _buildVideoContent(int id) {
     if (id == null) {
       return Container(
         color: Colors.black,