Pārlūkot izejas kodu

Refactory controller code

Caijinglong 6 gadi atpakaļ
vecāks
revīzija
3b60094025

+ 2 - 3
README-EN.md

@@ -2,7 +2,7 @@
 
 [![pub package](https://img.shields.io/pub/v/flutter_ijkplayer.svg)](https://pub.dartlang.org/packages/flutter_ijkplayer)
 
-ijkplayer for bilibili/ijkplayer, use flutter Texture widget.
+ijkplayer for [bilibili/ijkplayer](https://github.com/bilibili/ijkplayer), use flutter Texture widget.
 Read this README and refer to example/lib/main.dart before using it.
 The question of Android might not be able to run will be explained in detail.
 The simulator is out of use, so please use the real machine for debugging.
@@ -52,8 +52,7 @@ dependencies:
 
 Current config file see [url](https://gitee.com/kikt/ijkplayer_thrid_party/blob/master/config/module.sh).
 
-Compilation options for ijkplayer:
-https://github.com/CaiJingLong/flutter_ijkplayer_pod/blob/master/config/module.sh
+For custom configuration options, refer to the [bibibili/ijkplayer](https://github.com/bilibili/ijkplayer) or [ffmpeg](http://ffmpeg.org/).
 
 Custom compilation options:
 https://github.com/CaiJingLong/flutter_ijkplayer/blob/master/compile.md

+ 2 - 2
README.md

@@ -2,7 +2,7 @@
 
 [![pub package](https://img.shields.io/pub/v/flutter_ijkplayer.svg)](https://pub.dartlang.org/packages/flutter_ijkplayer)
 
-ijkplayer,通过纹理的方式接入 bilibili/ijkplayer
+ijkplayer,通过纹理的方式接入 [bilibili/ijkplayer](https://github.com/bilibili/ijkplayer)
 
 使用前请完整阅读本 README 并参阅 example/lib/main.dart
 
@@ -62,7 +62,7 @@ dependencies:
 
 ## 原生部分说明
 
-编译规则可以参考[这个](https://gitee.com/kikt/ijkplayer_thrid_party/blob/master/config/module.sh),如果你有自己的特定需求,可以修改编译选项,这个参考 bilibili/ijkplayer 或 ffmpeg
+编译规则可以参考[这个](https://gitee.com/kikt/ijkplayer_thrid_party/blob/master/config/module.sh),如果你有自己的特定需求,可以修改编译选项,这个参考 [bilibili/ijkplayer](https://github.com/bilibili/ijkplayer)[ffmpeg](http://ffmpeg.org/)
 
 自定义编译选项可以看[这里](https://github.com/CaiJingLong/flutter_ijkplayer/blob/master/compile-cn.md)
 

+ 7 - 5
TODOLIST.md

@@ -37,9 +37,9 @@
   - [x] 屏幕旋转: 这个指强制当前屏幕旋转至哪个方向
     - [ ] iPad 无效,暂不知原因
   - [x] 截图
-  - [ ]  悬浮窗中播放
-    - [ ] 悬浮窗的UI控制器
-    - [ ] 自定义UI
+  - [ ] 悬浮窗中播放
+    - [ ] 悬浮窗的 UI 控制器
+    - [ ] 自定义 UI
 - [x] 默认控制器 UI
   - [x] 进度条
   - [x] 播放/暂停按钮
@@ -74,6 +74,8 @@
   - [x] 在列表中(ListView)
   - [x] 视频竖向分页滑动
   - [x] 在悬浮窗中播放
-    - [x] 悬浮窗的UI控制器
-      - [ ] 允许自定义UI
+    - [x] 悬浮窗的 UI 控制器
 - [x] iOS 部分视频无法显示图像的问题: 可能很长时间内都无法解决
+- [ ] 支持在 dart 端初始化 ijkPlayer 播放器的 option
+  - [ ] android
+  - [ ] iOS

+ 10 - 272
lib/src/controller/controller.dart

@@ -1,133 +1,22 @@
 part of '../ijkplayer.dart';
 
 /// Media Controller
-class IjkMediaController with IjkMediaControllerMixin {
-  /// MediaController
-  IjkMediaController({
-    this.autoRotate = true,
-  }) {
-    index = IjkMediaPlayerManager().add(this);
-  }
-
-  int index;
-
-  String get debugLabel => index.toString();
-
-  /// texture id from native
-  int _textureId;
-
+class IjkMediaController
+    with IjkMediaControllerMixin, IjkMediaControllerStreamMixin {
   /// It will automatically correct the direction of the video.
   bool autoRotate;
 
-  /// texture id from native
-  int get textureId => _textureId;
-
-  /// set texture id, Normally the user does not call
-  set textureId(int id) {
-    _textureId = id;
-    _textureIdController.add(id);
-  }
-
-  /// on texture id change
-  StreamController<int> _textureIdController = StreamController.broadcast();
-
-  /// on texture id change
-  Stream<int> get textureIdStream => _textureIdController?.stream;
-
-  /// Channel of flutter and native.
-  _IjkPlugin _plugin;
-
-  /// Whether texture id is null
-  bool get isInit => textureId == null;
-
-  /// channel of native to flutter
-  _IJKEventChannel eventChannel;
-
-  /// playing state
-  bool _isPlaying = false;
-
-  /// playing state
-  bool get isPlaying => _isPlaying == true;
-
-  /// playing state
-  set isPlaying(bool value) {
-    this._isPlaying = value;
-    _playingController?.add(value);
-    if (value == true) {
-      _ijkStatus = IjkStatus.playing;
-    }
-  }
-
-  /// playing state stream controller
-  StreamController<bool> _playingController = StreamController.broadcast();
-
-  /// playing state stream
-  Stream<bool> get playingStream => _playingController?.stream;
-
-  /// video info stream controller
-  StreamController<VideoInfo> _videoInfoController =
-      StreamController.broadcast();
-
-  /// video info stream
-  Stream<VideoInfo> get videoInfoStream => _videoInfoController?.stream;
-
-  VideoInfo _videoInfo = VideoInfo.fromMap(null);
-
-  /// last update video info.
-  VideoInfo get videoInfo => _videoInfo;
-
-  /// video volume stream controller
-  StreamController<int> _volumeController = StreamController.broadcast();
-
-  /// video volume stream
-  Stream<int> get volumeStream => _volumeController?.stream;
-
-  /// video volume, not system volume
-  int _volume = 100;
-
-  /// video volume, not system volume
-  set volume(int value) {
-    if (value > 100) {
-      value = 100;
-    } else if (value < 0) {
-      value = 0;
-    }
-    this._volume = value;
-    _volumeController?.add(value);
-    _setVolume(value);
-  }
-
-  /// video volume, not system volume
-  int get volume => _volume;
-
-  /// playFinish
-  StreamController<IjkMediaController> _playFinishController =
-      StreamController.broadcast();
-
-  /// On play finish
-  Stream<IjkMediaController> get playFinishStream =>
-      _playFinishController.stream;
-
-  IjkStatus __ijkStatus = IjkStatus.noDatasource;
+  int index;
 
-  IjkStatus get ijkStatus => __ijkStatus;
+  String get debugLabel => index.toString();
 
-  set _ijkStatus(IjkStatus status) {
-    if (status != __ijkStatus) {
-      __ijkStatus = status;
-      _ijkStatusController?.add(status);
-    } else {
-      __ijkStatus = status;
-    }
+  /// MediaController
+  IjkMediaController({
+    this.autoRotate = true,
+  }) {
+    index = IjkMediaPlayerManager().add(this);
   }
 
-  /// playFinish
-  StreamController<IjkStatus> _ijkStatusController =
-      StreamController.broadcast();
-
-  /// On play finish
-  Stream<IjkStatus> get ijkStatusStream => _ijkStatusController.stream;
-
   /// create ijk texture id from native
   Future<void> _initIjk() async {
     try {
@@ -146,20 +35,7 @@ class IjkMediaController with IjkMediaControllerMixin {
   /// [reset] and close all controller
   void dispose() async {
     await reset();
-    _ijkStatus = IjkStatus.disposed;
-    _playingController?.close();
-    _videoInfoController?.close();
-    _textureIdController?.close();
-    _volumeController?.close();
-    _playFinishController?.close();
-    _ijkStatusController?.close();
-
-    _playingController = null;
-    _videoInfoController = null;
-    _textureIdController = null;
-    _volumeController = null;
-    _playFinishController = null;
-    _ijkStatusController = null;
+    await _disposeStream();
 
     IjkMediaPlayerManager().remove(this);
   }
@@ -392,141 +268,3 @@ class IjkMediaController with IjkMediaControllerMixin {
     return _plugin.screenShot();
   }
 }
-
-/// about channel
-MethodChannel _globalChannel = MethodChannel("top.kikt/ijkplayer");
-
-Future<int> _createIjk() async {
-  int id = await _globalChannel.invokeMethod("create");
-  return id;
-}
-
-class _IjkPlugin {
-  MethodChannel get channel => MethodChannel("top.kikt/ijkplayer/$textureId");
-
-  /// texture id
-  int textureId;
-
-  _IjkPlugin(this.textureId);
-
-  Future<void> dispose() async {
-    await _globalChannel.invokeMethod("dispose", {"id": textureId});
-  }
-
-  Future<void> play() async {
-    await channel.invokeMethod("play");
-  }
-
-  Future<void> pause() async {
-    await channel.invokeMethod("pause");
-  }
-
-  Future<void> stop() async {
-    await channel.invokeMethod("stop");
-  }
-
-  Future<void> setNetworkDataSource(
-      {String uri, Map<String, String> headers = const {}}) async {
-    LogUtils.debug("id = $textureId net uri = $uri ,headers = $headers");
-    await channel.invokeMethod("setNetworkDataSource", <String, dynamic>{
-      "uri": uri,
-      "headers": headers,
-    });
-  }
-
-  Future<void> setAssetDataSource(String name, String package) async {
-    LogUtils.debug("id = $textureId asset name = $name package = $package");
-    var params = <String, dynamic>{
-      "name": name,
-    };
-    if (package != null) {
-      params["package"] = package;
-    }
-    await channel.invokeMethod("setAssetDataSource", params);
-  }
-
-  Future<void> setFileDataSource(String path) async {
-    if (!File(path).existsSync()) {
-      return Error.fileNotExists;
-    }
-    await channel.invokeMethod("setFileDataSource", <String, dynamic>{
-      "path": path,
-    });
-    LogUtils.debug("id = $textureId file path = $path");
-  }
-
-  Future<Map<String, dynamic>> getInfo() async {
-    var map = await channel.invokeMethod("getInfo");
-    if (map == null) {
-      return null;
-    } else {
-      return map.cast<String, dynamic>();
-    }
-  }
-
-  Future<void> seekTo(double target) async {
-    await channel.invokeMethod("seekTo", <String, dynamic>{
-      "target": target,
-    });
-  }
-
-  ///
-  Future<void> setVolume(int volume) async {
-    await channel.invokeMethod("setVolume", <String, dynamic>{
-      "volume": volume,
-    });
-  }
-
-  Future<Uint8List> screenShot() async {
-    var result = await channel.invokeMethod("screenShot");
-    if (result == null) {
-      return null;
-    }
-    return result;
-  }
-}
-
-/// Entity classe for data sources.
-class DataSource {
-  /// See [DataSourceType]
-  DataSourceType _type;
-
-  File _file;
-
-  String _assetName;
-
-  String _assetPackage;
-
-  String _netWorkUrl;
-
-  Map<String, String> _headers;
-
-  DataSource._();
-
-  /// Create file data source
-  factory DataSource.file(File file) {
-    var ds = DataSource._();
-    ds._file = file;
-    ds._type = DataSourceType.file;
-    return ds;
-  }
-
-  /// Create network data source
-  factory DataSource.network(String url,
-      {Map<String, String> headers = const {}}) {
-    var ds = DataSource._();
-    ds._netWorkUrl = url;
-    ds._headers = headers;
-    ds._type = DataSourceType.network;
-    return ds;
-  }
-
-  /// Create asset data source
-  factory DataSource.asset(String assetName, {String package}) {
-    var ds = DataSource._();
-    ds._assetName = assetName;
-    ds._assetPackage = package;
-    ds._type = DataSourceType.asset;
-    return ds;
-  }
-}

+ 46 - 0
lib/src/controller/datasoure.dart

@@ -0,0 +1,46 @@
+part of '../ijkplayer.dart';
+
+/// Entity classe for data sources.
+class DataSource {
+  /// See [DataSourceType]
+  DataSourceType _type;
+
+  File _file;
+
+  String _assetName;
+
+  String _assetPackage;
+
+  String _netWorkUrl;
+
+  Map<String, String> _headers;
+
+  DataSource._();
+
+  /// Create file data source
+  factory DataSource.file(File file) {
+    var ds = DataSource._();
+    ds._file = file;
+    ds._type = DataSourceType.file;
+    return ds;
+  }
+
+  /// Create network data source
+  factory DataSource.network(String url,
+      {Map<String, String> headers = const {}}) {
+    var ds = DataSource._();
+    ds._netWorkUrl = url;
+    ds._headers = headers;
+    ds._type = DataSourceType.network;
+    return ds;
+  }
+
+  /// Create asset data source
+  factory DataSource.asset(String assetName, {String package}) {
+    var ds = DataSource._();
+    ds._assetName = assetName;
+    ds._assetPackage = package;
+    ds._type = DataSourceType.asset;
+    return ds;
+  }
+}

+ 134 - 1
lib/src/controller/ijkplayer_controller_mixin.dart

@@ -1,4 +1,4 @@
-import 'package:flutter/material.dart';
+part of '../ijkplayer.dart';
 
 mixin IjkMediaControllerMixin {
   List<GlobalKey> _keys = [];
@@ -13,3 +13,136 @@ mixin IjkMediaControllerMixin {
     _keys.remove(key);
   }
 }
+
+mixin IjkMediaControllerStreamMixin {
+  /// texture id from native
+  int _textureId;
+
+  /// texture id from native
+  int get textureId => _textureId;
+
+  /// set texture id, Normally the user does not call
+  set textureId(int id) {
+    _textureId = id;
+    _textureIdController.add(id);
+  }
+
+  /// on texture id change
+  StreamController<int> _textureIdController = StreamController.broadcast();
+
+  /// on texture id change
+  Stream<int> get textureIdStream => _textureIdController?.stream;
+
+  /// Channel of flutter and native.
+  _IjkPlugin _plugin;
+
+  /// Whether texture id is null
+  bool get isInit => textureId == null;
+
+  /// channel of native to flutter
+  _IJKEventChannel eventChannel;
+
+  /// playing state
+  bool _isPlaying = false;
+
+  /// playing state
+  bool get isPlaying => _isPlaying == true;
+
+  /// playing state
+  set isPlaying(bool value) {
+    this._isPlaying = value;
+    _playingController?.add(value);
+    if (value == true) {
+      _ijkStatus = IjkStatus.playing;
+    }
+  }
+
+  /// playing state stream controller
+  StreamController<bool> _playingController = StreamController.broadcast();
+
+  /// playing state stream
+  Stream<bool> get playingStream => _playingController?.stream;
+
+  /// video info stream controller
+  StreamController<VideoInfo> _videoInfoController =
+      StreamController.broadcast();
+
+  /// video info stream
+  Stream<VideoInfo> get videoInfoStream => _videoInfoController?.stream;
+
+  VideoInfo _videoInfo = VideoInfo.fromMap(null);
+
+  /// last update video info.
+  VideoInfo get videoInfo => _videoInfo;
+
+  /// video volume stream controller
+  StreamController<int> _volumeController = StreamController.broadcast();
+
+  /// video volume stream
+  Stream<int> get volumeStream => _volumeController?.stream;
+
+  /// video volume, not system volume
+  int _volume = 100;
+
+  /// video volume, not system volume
+  set volume(int value) {
+    if (value > 100) {
+      value = 100;
+    } else if (value < 0) {
+      value = 0;
+    }
+    this._volume = value;
+    _volumeController?.add(value);
+    _setVolume(value);
+  }
+
+  /// video volume, not system volume
+  int get volume => _volume;
+
+  /// playFinish
+  StreamController<IjkMediaController> _playFinishController =
+      StreamController.broadcast();
+
+  /// On play finish
+  Stream<IjkMediaController> get playFinishStream =>
+      _playFinishController.stream;
+
+  IjkStatus __ijkStatus = IjkStatus.noDatasource;
+
+  IjkStatus get ijkStatus => __ijkStatus;
+
+  set _ijkStatus(IjkStatus status) {
+    if (status != __ijkStatus) {
+      __ijkStatus = status;
+      _ijkStatusController?.add(status);
+    } else {
+      __ijkStatus = status;
+    }
+  }
+
+  /// playFinish
+  StreamController<IjkStatus> _ijkStatusController =
+      StreamController.broadcast();
+
+  /// On play finish
+  Stream<IjkStatus> get ijkStatusStream => _ijkStatusController.stream;
+
+  void _setVolume(int value);
+
+  Future<void> _disposeStream() async {
+    _ijkStatus = IjkStatus.disposed;
+    _playingController?.close();
+    _videoInfoController?.close();
+    _textureIdController?.close();
+    _volumeController?.close();
+    _playFinishController?.close();
+    _ijkStatusController?.close();
+
+    _playingController = null;
+    _videoInfoController = null;
+    _textureIdController = null;
+    _volumeController = null;
+    _playFinishController = null;
+    _ijkStatusController = null;
+  }
+}

+ 98 - 0
lib/src/controller/plugin.dart

@@ -0,0 +1,98 @@
+part of '../ijkplayer.dart';
+
+/// about channel
+MethodChannel _globalChannel = MethodChannel("top.kikt/ijkplayer");
+
+Future<int> _createIjk() async {
+  int id = await _globalChannel.invokeMethod("create");
+  return id;
+}
+
+class _IjkPlugin {
+  MethodChannel get channel => MethodChannel("top.kikt/ijkplayer/$textureId");
+
+  /// texture id
+  int textureId;
+
+  _IjkPlugin(this.textureId);
+
+  Future<void> dispose() async {
+    await _globalChannel.invokeMethod("dispose", {"id": textureId});
+  }
+
+  Future<void> play() async {
+    await channel.invokeMethod("play");
+  }
+
+  Future<void> pause() async {
+    await channel.invokeMethod("pause");
+  }
+
+  Future<void> stop() async {
+    await channel.invokeMethod("stop");
+  }
+
+  Future<void> setNetworkDataSource(
+      {String uri, Map<String, String> headers = const {}}) async {
+    LogUtils.debug("id = $textureId net uri = $uri ,headers = $headers");
+    await channel.invokeMethod("setNetworkDataSource", <String, dynamic>{
+      "uri": uri,
+      "headers": headers,
+    });
+  }
+
+  Future<void> setAssetDataSource(String name, String package) async {
+    LogUtils.debug("id = $textureId asset name = $name package = $package");
+    var params = <String, dynamic>{
+      "name": name,
+    };
+    if (package != null) {
+      params["package"] = package;
+    }
+    await channel.invokeMethod("setAssetDataSource", params);
+  }
+
+  Future<void> setFileDataSource(String path) async {
+    if (!File(path).existsSync()) {
+      return Error.fileNotExists;
+    }
+    await channel.invokeMethod("setFileDataSource", <String, dynamic>{
+      "path": path,
+    });
+    LogUtils.debug("id = $textureId file path = $path");
+  }
+
+  Future<Map<String, dynamic>> getInfo() async {
+    try {
+      var map = await channel.invokeMethod("getInfo");
+      if (map == null) {
+        return null;
+      } else {
+        return map.cast<String, dynamic>();
+      }
+    } on Exception {
+      return null;
+    }
+  }
+
+  Future<void> seekTo(double target) async {
+    await channel.invokeMethod("seekTo", <String, dynamic>{
+      "target": target,
+    });
+  }
+
+  ///
+  Future<void> setVolume(int volume) async {
+    await channel.invokeMethod("setVolume", <String, dynamic>{
+      "volume": volume,
+    });
+  }
+
+  Future<Uint8List> screenShot() async {
+    var result = await channel.invokeMethod("screenShot");
+    if (result == null) {
+      return null;
+    }
+    return result;
+  }
+}

+ 3 - 1
lib/src/ijkplayer.dart

@@ -5,7 +5,6 @@ import 'dart:typed_data';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 
-import 'controller/ijkplayer_controller_mixin.dart';
 import 'entity/video_info.dart';
 import 'engine/ijk_controller_manager.dart';
 import 'error.dart';
@@ -15,8 +14,11 @@ import 'widget/ijkplayer_builder.dart';
 import 'widget/ijk_status_widget.dart';
 
 part 'controller/controller.dart';
+part 'controller/datasoure.dart';
 part 'controller/enums.dart';
 part 'controller/ijk_event_channel.dart';
+part 'controller/ijkplayer_controller_mixin.dart';
+part 'controller/plugin.dart';
 part 'engine/manager.dart';
 
 /// Main Classes of Library