Browse Source

Merge pull request #84 from CaiJingLong/set-speed

Set media speed
Caijinglong 6 năm trước cách đây
mục cha
commit
cef483fa07

+ 10 - 0
CHANGELOG.md

@@ -1,3 +1,13 @@
+## 0.2.8
+
+New feature:
+
+- Now, user can setSpeed.
+
+Fix:
+
+- About setDataSource and autoPlay.
+
 ## 0.2.7
 
 Fix bug:

+ 17 - 0
README-EN.md

@@ -31,6 +31,7 @@ Before using library, you can star and download the code to try the example.
       - [get media info](#get-media-info)
       - [screen shot](#screen-shot)
       - [Observer for resource](#observer-for-resource)
+      - [Media Speed](#media-speed)
       - [IjkStatus](#ijkstatus)
       - [Custom Options](#custom-options)
         - [IjkOptionCategory](#ijkoptioncategory)
@@ -264,6 +265,22 @@ Stream<IjkStatus> ijkStatusStream = controller.ijkStatusStream;
 
 ```
 
+#### Media Speed
+
+code:
+
+```dart
+controller.setSpeed(2.0);
+```
+
+Default speed is 1.0, the min value need bigger than 0
+
+Because of the speed change, the tone will change. So you need to use an option to keep the tone unchanged. The option **default value is open**, and if you want to close it, use the code:
+
+```dart
+IjkMediaController(needChangeSpeed: false); // set needChangeSpeed to false, the tone will change on speed change.
+```
+
 #### IjkStatus
 
 | name              | describe                                                       |

+ 18 - 0
README.md

@@ -36,6 +36,7 @@ android 模拟器 mac android sdk 自带的 emulator(API28 android9)可用,其
       - [获取播放信息](#%E8%8E%B7%E5%8F%96%E6%92%AD%E6%94%BE%E4%BF%A1%E6%81%AF)
       - [截取视频帧](#%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)
+      - [倍速播放](#%E5%80%8D%E9%80%9F%E6%92%AD%E6%94%BE)
       - [IjkStatus 说明](#ijkstatus-%E8%AF%B4%E6%98%8E)
       - [自定义 Option](#%E8%87%AA%E5%AE%9A%E4%B9%89-option)
         - [IjkOptionCategory](#ijkoptioncategory)
@@ -291,6 +292,23 @@ Stream<bool> volumeStream = controller.playingStream;
 Stream<IjkStatus> ijkStatusStream = controller.ijkStatusStream;
 ```
 
+#### 倍速播放
+
+调用代码:
+
+```dart
+controller.setSpeed(2.0);
+```
+
+支持的倍率默认为 1.0, 上限不明,下限请不要小于等于 0,否则可能会 crash
+
+变调的问题:
+由于变速变调的问题, 如果需要不变调, 需要一个 option 的支持, 这个 option **默认开启**, 如果要关闭这个, 可以使用如下代码
+
+```dart
+IjkMediaController(needChangeSpeed: false); // 这个设置为false后, 则变速时会声音会变调的情况发生
+```
+
 #### IjkStatus 说明
 
 | 名称              | 说明                     |

+ 1 - 1
TODOLIST.md

@@ -22,7 +22,7 @@
     - [x] 总时长
     - [x] 视频方向
     - [x] 视频播放速度
-      - [x] tcp 速度
+    - [x] tcp 速度
     - [ ] 当前视频编解码器(作为未来备选方案,目前 android 端可获取,iOS 端只有解码器 id 没有名字)
       - [ ] 视频
       - [ ] 音频

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

@@ -164,6 +164,10 @@ class Ijk(private val registry: PluginRegistry.Registrar, val options: Map<Strin
                 val bytes = screenShot()
                 result?.success(bytes)
             }
+            "setSpeed" -> {
+                val speed = call.arguments<Double>()
+                mediaPlayer.setSpeed(speed.toFloat())
+            }
             else -> {
                 result?.notImplemented()
             }

+ 3 - 0
example/lib/i18n/cn.dart

@@ -74,4 +74,7 @@ class _I18nZh extends I18n {
 
   @override
   String get customFullScreenWidget => "自定义全屏界面";
+
+  @override
+  String get setSpeed => "播放速度";
 }

+ 3 - 0
example/lib/i18n/en.dart

@@ -74,4 +74,7 @@ class _I18nEn extends I18n {
 
   @override
   String get customFullScreenWidget => "Custom Full Screen Interface";
+
+  @override
+  String get setSpeed => "Set media speed";
 }

+ 2 - 0
example/lib/i18n/i18n.dart

@@ -52,6 +52,8 @@ abstract class I18n {
   String get errorUrl;
 
   String get customFullScreenWidget;
+
+  String get setSpeed;
 }
 
 I18n get currentI18n => I18n(window.locale);

+ 3 - 1
example/lib/page/developing/develop_index.dart

@@ -1,6 +1,7 @@
 import 'package:flutter/material.dart';
 
 import 'develop_prepare_page.dart';
+import 'live_interruption_page.dart';
 
 class DevelopingIndexPage extends StatefulWidget {
   @override
@@ -12,11 +13,12 @@ class DevelopingIndexPageState extends State<DevelopingIndexPage> {
   Widget build(BuildContext context) {
     return Scaffold(
       appBar: AppBar(
-        title: Text("开发中"),
+        title: Text("For Developer , user don't use."),
       ),
       body: ListView(
         children: <Widget>[
           buildButton("developing preare page", ForPreparePage()),
+          buildButton("直播中断", LiveInterruptionPage()),
         ],
       ),
     );

+ 66 - 0
example/lib/page/developing/live_interruption_page.dart

@@ -0,0 +1,66 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
+import 'package:ijkplayer_example/i18n/i18n.dart';
+
+/// 直播异常中断
+class LiveInterruptionPage extends StatefulWidget {
+  @override
+  _LiveInterruptionPageState createState() => _LiveInterruptionPageState();
+}
+
+class _LiveInterruptionPageState extends State<LiveInterruptionPage> {
+  TextEditingController editingController = TextEditingController();
+  IjkMediaController mediaController = IjkMediaController();
+
+  @override
+  void initState() {
+    super.initState();
+
+    editingController.text =
+        "http://js.flv.huya.com/huyalive/94525224-2460685313-10568562945082523648-2789274524-10057-A-0-1.flv?wsSecret=9b67d35535b6956aec37815c21e43cc8&wsTime=5cbbea84&ratio=2000";
+  }
+
+  @override
+  void dispose() {
+    editingController.dispose();
+    mediaController.dispose();
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        title: Text(currentI18n.networkButton),
+      ),
+      body: ListView(
+        children: <Widget>[
+          Row(
+            children: <Widget>[
+              Expanded(
+                child: TextField(
+                  controller: editingController,
+                ),
+              ),
+              FlatButton(
+                child: Text(currentI18n.play),
+                onPressed: _playInput,
+              ),
+            ],
+          ),
+          Container(
+            height: 400,
+            child: IjkPlayer(
+              mediaController: mediaController,
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+
+  void _playInput() async {
+    var text = editingController.text;
+    await mediaController.setNetworkDataSource(text, autoPlay: true);
+  }
+}

+ 2 - 1
example/lib/page/index.dart

@@ -7,7 +7,6 @@ import '../i18n/i18n.dart';
 import 'asset_page.dart';
 import 'controller_stream_use.dart';
 import 'custom_ijk_opt_page.dart';
-import 'package:ijkplayer_example/page/developing/develop_prepare_page.dart';
 import 'developing/develop_index.dart';
 import 'dialog_video_page.dart';
 import 'error_url.dart';
@@ -16,6 +15,7 @@ import 'gallery_page.dart';
 import 'ijk_status_page.dart';
 import 'in_overlay_page.dart';
 import 'network.dart';
+import 'speed_page.dart';
 
 class IndexPage extends StatefulWidget {
   @override
@@ -46,6 +46,7 @@ class _IndexPageState extends State<IndexPage> {
           buildButton(currentI18n.ijkStatusTitle, IjkStatusPage()),
           buildButton(currentI18n.customOption, CustomIjkOptionPage()),
           buildButton(currentI18n.errorUrl, ErrorUrlPage()),
+          buildButton(currentI18n.setSpeed, SpeedPage()),
           buildButton(
               currentI18n.customFullScreenWidget, CustomFullControllerPage()),
         ],

+ 64 - 0
example/lib/page/speed_page.dart

@@ -0,0 +1,64 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
+import 'package:ijkplayer_example/i18n/i18n.dart';
+
+class SpeedPage extends StatefulWidget {
+  @override
+  _SpeedPageState createState() => _SpeedPageState();
+}
+
+class _SpeedPageState extends State<SpeedPage> {
+  IjkMediaController controller = IjkMediaController();
+
+  double speed = 1;
+
+  @override
+  void initState() {
+    super.initState();
+    var url = "http://img.ksbbs.com/asset/Mon_1703/05cacb4e02f9d9e.mp4";
+    var dataSource = DataSource.network(url);
+    controller?.setDataSource(dataSource, autoPlay: true);
+  }
+
+  @override
+  void dispose() {
+    controller.dispose();
+    controller = null;
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        title: Text(currentI18n.setSpeed),
+      ),
+      body: Container(
+        child: ListView(
+          children: <Widget>[
+            Container(
+              height: 280,
+              child: IjkPlayer(
+                mediaController: controller,
+              ),
+            ),
+            Slider(
+              value: speed,
+              max: 2,
+              min: 0.5,
+              divisions: 6,
+              onChanged: _onChangeSpeed,
+            ),
+            Center(child: Text("speed is $speed")),
+          ],
+        ),
+      ),
+    );
+  }
+
+  void _onChangeSpeed(double value) {
+    this.speed = value;
+    setState(() {});
+    controller?.setSpeed(speed);
+  }
+}

+ 1 - 1
example/pubspec.lock

@@ -82,7 +82,7 @@ packages:
       path: ".."
       relative: true
     source: path
-    version: "0.2.7"
+    version: "0.2.8"
   flutter_localizations:
     dependency: "direct main"
     description: flutter

+ 6 - 0
ios/Classes/CoolFlutterIJK.m

@@ -108,6 +108,12 @@
             NSData *data = [weakSelf screenShot];
             result(data);
         });
+    } else if ([@"setSpeed" isEqualToString:call.method]) {
+        float speedValue = [call.arguments floatValue];
+        if (controller) {
+            [controller setPlaybackRate:speedValue];
+        }
+        result(@YES);
     } else {
         result(FlutterMethodNotImplemented);
     }

+ 19 - 11
lib/src/controller/controller.dart

@@ -12,11 +12,24 @@ class IjkMediaController
 
   Map<TargetPlatform, Set<IjkOption>> _options = {};
 
+  bool needChangeSpeed;
+
   /// MediaController
   IjkMediaController({
     this.autoRotate = true,
+    this.needChangeSpeed = true,
   }) {
     index = IjkMediaPlayerManager().add(this);
+    if (needChangeSpeed) {
+      setIjkPlayerOptions(
+          [
+            TargetPlatform.iOS,
+            TargetPlatform.android,
+          ],
+          <IjkOption>[
+            IjkOption(IjkOptionCategory.player, "soundtouch", 1),
+          ].toSet());
+    }
   }
 
   @override
@@ -245,15 +258,6 @@ class IjkMediaController
     }
   }
 
-  /// AutoPlay use
-  Future<void> _autoPlay(bool autoPlay) async {
-    if (autoPlay) {
-      await eventChannel?.autoPlay(this);
-    } else {
-      await eventChannel?.disableAutoPlay(this);
-    }
-  }
-
   /// set video volume
   Future<void> _setVolume(int volume) async {
     await _plugin?.setVolume(volume);
@@ -317,10 +321,10 @@ class IjkMediaController
   /// It will only take effect if you call [setDataSource] again.
   void setIjkPlayerOptions(
     List<TargetPlatform> platforms,
-    Set<IjkOption> options,
+    Iterable<IjkOption> options,
   ) {
     for (var platform in platforms) {
-      _options[platform] = options;
+      _options[platform] = options.toSet();
     }
   }
 
@@ -340,4 +344,8 @@ class IjkMediaController
       opts.addAll(options);
     }
   }
+
+  Future<void> setSpeed(double speed) async {
+    await _plugin.setSpeed(speed);
+  }
 }

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

@@ -108,4 +108,8 @@ class _IjkPlugin {
     }
     return result;
   }
+
+  Future<void> setSpeed(double speed) async {
+    await channel.invokeMethod("setSpeed", speed);
+  }
 }

+ 1 - 1
pubspec.yaml

@@ -1,6 +1,6 @@
 name: flutter_ijkplayer
 description: Flutter version of bilibilibili ijkplayer, supports common playback protocols, easy to use.
-version: 0.2.7
+version: 0.2.8
 author: caijinglong<cjl_spy@163.com>
 homepage: https://github.com/CaiJingLong/flutter_ijkplayer