Sfoglia il codice sorgente

update readme
refactory set options

Caijinglong 6 anni fa
parent
commit
255831f724

+ 41 - 0
README-EN.md

@@ -31,6 +31,8 @@ Before using library, you can star and download the code to try the example.
       - [screen shot](#screen-shot)
       - [Observer for resource](#observer-for-resource)
       - [IjkStatus](#ijkstatus)
+      - [自定义 Option](#%E8%87%AA%E5%AE%9A%E4%B9%89-option)
+        - [IjkOptionCategory](#ijkoptioncategory)
       - [release resource](#release-resource)
     - [Use self controller UI](#use-self-controller-ui)
     - [Build widget from IjkStatus](#build-widget-from-ijkstatus)
@@ -269,6 +271,45 @@ Stream<IjkStatus> ijkStatusStream = controller.ijkStatusStream;
 | complete          | Media is play complete.                                        |
 | disposed          | After Controller calls `dispose()`.                            |
 
+#### 自定义 Option
+
+Support custom IJKPlayer options, which are transmitted directly to Android/iOS native. For specific values and meanings, you need to see bilibili/ijkplayer](https://github.com/bilibili/ijkplayer).
+
+However, this option does not take effect immediately.
+It will only take effect if you call `setDataSource` again.
+
+Setup method `setIjkPlayerOptions`
+
+```dart
+void initIjkController() async {
+  var option1 = IjkOption(IjkOptionCategory.format, "fflags", "fastseek");// category, key ,value
+
+  controller.setIjkPlayerOptions(
+    [TargetPlatform.iOS, TargetPlatform.android],
+    [option1].toSet(),
+  );
+
+  await controller.setDataSource(
+    DataSource.network(
+        "http://img.ksbbs.com/asset/Mon_1703/05cacb4e02f9d9e.mp4"),
+    autoPlay: true,
+  );
+}
+```
+
+第一个参数是一个数组,代表了你 option 目标设备的类型(android/iOS)
+
+第二个参数是一个`Set<IjkOption>`,代表了 Option 的集合,因为 category 和 key 均相同的情况下会覆盖,所以这里使用了 set
+
+##### IjkOptionCategory
+
+| name   |
+| ------ |
+| format |
+| codec  |
+| sws    |
+| player |
+
 #### release resource
 
 ```dart

+ 41 - 0
README.md

@@ -36,6 +36,8 @@ android 模拟器 mac android sdk 自带的 emulator(API28 android9)可用,其
       - [截取视频帧](#%E6%88%AA%E5%8F%96%E8%A7%86%E9%A2%91%E5%B8%A7)
       - [资源监听](#%E8%B5%84%E6%BA%90%E7%9B%91%E5%90%AC)
       - [IjkStatus 说明](#ijkstatus-%E8%AF%B4%E6%98%8E)
+      - [自定义 Option](#%E8%87%AA%E5%AE%9A%E4%B9%89-option)
+        - [IjkOptionCategory](#ijkoptioncategory)
       - [释放资源](#%E9%87%8A%E6%94%BE%E8%B5%84%E6%BA%90)
     - [自定义控制器 UI](#%E8%87%AA%E5%AE%9A%E4%B9%89%E6%8E%A7%E5%88%B6%E5%99%A8-ui)
     - [自定义纹理界面](#%E8%87%AA%E5%AE%9A%E4%B9%89%E7%BA%B9%E7%90%86%E7%95%8C%E9%9D%A2)
@@ -294,6 +296,45 @@ Stream<IjkStatus> ijkStatusStream = controller.ijkStatusStream;
 | complete          | 播放完毕后               |
 | disposed          | 调用 dispose 后的状态    |
 
+#### 自定义 Option
+
+支持自定义 IJKPlayer 的 option,这个 option 会直接传输至 android/iOS 原生,具体的数值和含义你需要查看[bilibili/ijkplayer](https://github.com/bilibili/ijkplayer)的设置选项
+
+但这个设置后的选项不是即时生效的
+只有在你重新 setDataSource 以后才会生效
+
+设置方法`setIjkPlayerOptions`
+
+```dart
+void initIjkController() async {
+  var option1 = IjkOption(IjkOptionCategory.format, "fflags", "fastseek");// category, key ,value
+
+  controller.setIjkPlayerOptions(
+    [TargetPlatform.iOS, TargetPlatform.android],
+    [option1].toSet(),
+  );
+
+  await controller.setDataSource(
+    DataSource.network(
+        "http://img.ksbbs.com/asset/Mon_1703/05cacb4e02f9d9e.mp4"),
+    autoPlay: true,
+  );
+}
+```
+
+第一个参数是一个数组,代表了你 option 目标设备的类型(android/iOS)
+
+第二个参数是一个`Set<IjkOption>`,代表了 Option 的集合,因为 category 和 key 均相同的情况下会覆盖,所以这里使用了 set
+
+##### IjkOptionCategory
+
+| name   |
+| ------ |
+| format |
+| codec  |
+| sws    |
+| player |
+
 #### 释放资源
 
 ```dart

+ 2 - 7
example/lib/page/custom_ijk_opt_page.dart

@@ -45,13 +45,8 @@ class _CustomIjkOptionPageState extends State<CustomIjkOptionPage> {
     var option1 = IjkOption(IjkOptionCategory.format, "fflags", "fastseek");
 
     controller.setIjkPlayerOptions(
-      TargetPlatform.iOS,
-      [option1],
-    );
-
-    controller.setIjkPlayerOptions(
-      TargetPlatform.android,
-      [option1],
+      [TargetPlatform.iOS, TargetPlatform.android],
+      [option1].toSet(),
     );
 
     await controller.setDataSource(

+ 48 - 17
lib/src/controller/controller.dart

@@ -10,7 +10,7 @@ class IjkMediaController
 
   String get debugLabel => index.toString();
 
-  Map<TargetPlatform, List<IjkOption>> _options = {};
+  Map<TargetPlatform, Set<IjkOption>> _options = {};
 
   /// MediaController
   IjkMediaController({
@@ -24,10 +24,10 @@ class IjkMediaController
     try {
       List<IjkOption> options = [];
       if (Platform.isAndroid) {
-        var opt = _options[TargetPlatform.android] ?? [];
+        var opt = _options[TargetPlatform.android] ?? Set();
         options.addAll(opt);
       } else {
-        var opt = _options[TargetPlatform.iOS] ?? [];
+        var opt = _options[TargetPlatform.iOS] ?? Set();
         options.addAll(opt);
       }
 
@@ -63,6 +63,8 @@ class IjkMediaController
   }
 
   /// set net DataSource
+  ///
+  /// see [setDataSource]
   Future<void> setNetworkDataSource(
     String url, {
     Map<String, String> headers = const {},
@@ -79,6 +81,8 @@ class IjkMediaController
   }
 
   /// set asset DataSource
+  ///
+  /// see [setDataSource]
   Future<void> setAssetDataSource(
     String name, {
     String package,
@@ -91,6 +95,20 @@ class IjkMediaController
     }, autoPlay);
   }
 
+  /// set file DataSource
+  ///
+  /// see [setDataSource]
+  Future<void> setFileDataSource(
+    File file, {
+    bool autoPlay = false,
+  }) async {
+    _ijkStatus = IjkStatus.preparing;
+    await _initDataSource(() async {
+      await _plugin?.setFileDataSource(file.absolute.path);
+      _ijkStatus = IjkStatus.prepared;
+    }, autoPlay);
+  }
+
   /// Set datasource with [DataSource]
   Future<void> setDataSource(
     DataSource source, {
@@ -121,18 +139,6 @@ class IjkMediaController
     }
   }
 
-  /// set file DataSource
-  Future<void> setFileDataSource(
-    File file, {
-    bool autoPlay = false,
-  }) async {
-    _ijkStatus = IjkStatus.preparing;
-    await _initDataSource(() async {
-      await _plugin?.setFileDataSource(file.absolute.path);
-      _ijkStatus = IjkStatus.prepared;
-    }, autoPlay);
-  }
-
   /// dispose last textureId resource
   Future<void> _initDataSource(
     Future setDataSource(),
@@ -279,7 +285,32 @@ class IjkMediaController
     return _plugin.screenShot();
   }
 
-  void setIjkPlayerOptions(TargetPlatform platform, List<IjkOption> options) {
-    _options[platform] = options;
+  /// Set [IjkOption] with IJKPlayer.
+  ///
+  /// It will only take effect if you call [setDataSource] again.
+  void setIjkPlayerOptions(
+    List<TargetPlatform> platforms,
+    Set<IjkOption> options,
+  ) {
+    for (var platform in platforms) {
+      _options[platform] = options;
+    }
+  }
+
+  /// Add [IjkOption] with IJKPlayer in native
+  ///
+  /// see [setIjkPlayerOptions]
+  void addIjkPlayerOptions(
+    List<TargetPlatform> platforms,
+    Iterable<IjkOption> options,
+  ) {
+    for (var platform in platforms) {
+      var opts = _options[platform];
+      if (opts == null) {
+        opts = Set();
+        _options[platform] = opts;
+      }
+      opts.addAll(options);
+    }
   }
 }

+ 25 - 0
lib/src/entity/options.dart

@@ -1,3 +1,4 @@
+/// see [bilibili/ijkplayer](https://github.com/bilibili/ijkplayer)
 enum IjkOptionCategory {
   format,
   codec,
@@ -5,13 +6,20 @@ enum IjkOptionCategory {
   player,
 }
 
+/// see [bilibili/ijkplayer](https://github.com/bilibili/ijkplayer)
 class IjkOption {
+  /// see [bilibili/ijkplayer](https://github.com/bilibili/ijkplayer)
   final IjkOptionCategory category;
+
+  /// see [bilibili/ijkplayer](https://github.com/bilibili/ijkplayer)
   final String key;
+
+  /// see [bilibili/ijkplayer](https://github.com/bilibili/ijkplayer)
   final dynamic value;
 
   IjkOption(this.category, this.key, this.value);
 
+  /// to map
   Map<String, dynamic> toMap() {
     return {
       "category": category.index,
@@ -19,4 +27,21 @@ class IjkOption {
       "value": value,
     };
   }
+
+  @override
+  int get hashCode => category.hashCode + key.hashCode;
+
+  @override
+  bool operator ==(other) {
+    if (identical(other, this)) {
+      return true;
+    }
+    if (other == null) {
+      return false;
+    }
+    if (other is! IjkOption) {
+      return false;
+    }
+    return this.category == other.category && this.key == other.key;
+  }
 }