浏览代码

Merge pull request #83 from CaiJingLong/fix-prepare

Fix autoplay problem
Caijinglong 6 年之前
父节点
当前提交
c920663f81

+ 3 - 3
README.md

@@ -67,11 +67,11 @@ dependencies:
 
 ### 自定义编译和原生部分源码
 
-自定义编译的主要目的是修改支持的格式, 因为默认包含了一些格式, 这些格式
+自定义编译的主要目的是修改支持的格式, 因为默认包含了一些编解码器,解复用,协议等等, 这些格式可能你的项目用不到, 这时候可以修改 ffmpeg 的自定义编译选项, 以便于可以缩小库文件的体积, 以达到给 app 瘦身的目的
 
-[当前的编译规则文件](https://gitee.com/kikt/ijkplayer_thrid_party/blob/master/config/module.sh),如果你有自己的特定需求,可以修改编译选项,这个参考 [bilibili/ijkplayer](https://github.com/bilibili/ijkplayer) 或 [ffmpeg](http://ffmpeg.org/)
+[当前的编译规则文件](https://gitee.com/kikt/ijkplayer_thrid_party/blob/master/config/module.sh),修改编译选项,这个参考 [bilibili/ijkplayer](https://github.com/bilibili/ijkplayer) 或 [ffmpeg](http://ffmpeg.org/),ffmpeg 的相关信息也可以通过搜索引擎获取
 
-自定义编译选项的完整过程请看[文档](https://github.com/CaiJingLong/flutter_ijkplayer/blob/master/compile-cn.md),否则不保证编译出来的代码不报错, 具体的更改方案也请查看编译文档,本篇不再提及
+自定义编译选项的完整过程请看[文档](https://github.com/CaiJingLong/flutter_ijkplayer/blob/master/compile-cn.md), 否则不保证编译出来的代码不报错, 具体的更改方案也请查看编译文档, 本篇不再提及
 
 ### iOS
 

+ 33 - 0
example/lib/page/developing/develop_index.dart

@@ -0,0 +1,33 @@
+import 'package:flutter/material.dart';
+
+import 'develop_prepare_page.dart';
+
+class DevelopingIndexPage extends StatefulWidget {
+  @override
+  DevelopingIndexPageState createState() => DevelopingIndexPageState();
+}
+
+class DevelopingIndexPageState extends State<DevelopingIndexPage> {
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        title: Text("开发中"),
+      ),
+      body: ListView(
+        children: <Widget>[
+          buildButton("developing preare page", ForPreparePage()),
+        ],
+      ),
+    );
+  }
+
+  Widget buildButton(String text, Widget targetPage) {
+    return FlatButton(
+      onPressed: () {
+        Navigator.push(context, MaterialPageRoute(builder: (_) => targetPage));
+      },
+      child: Text(text),
+    );
+  }
+}

+ 48 - 0
example/lib/page/developing/develop_prepare_page.dart

@@ -0,0 +1,48 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
+
+class ForPreparePage extends StatefulWidget {
+  @override
+  _ForPreparePageState createState() => _ForPreparePageState();
+}
+
+class _ForPreparePageState extends State<ForPreparePage> {
+  IjkMediaController controller = IjkMediaController();
+
+  @override
+  void initState() {
+    super.initState();
+    initPlayer();
+  }
+
+  @override
+  void dispose() {
+    controller.dispose();
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        title: Text("prepare属性"),
+      ),
+      body: Column(
+        children: <Widget>[
+          Container(
+            child: IjkPlayer(mediaController: controller),
+            height: 300,
+          ),
+        ],
+      ),
+    );
+  }
+
+  Future initPlayer() async {
+    await controller.setDataSource(
+      DataSource.asset("assets/sample1.mp4"),
+      autoPlay: true,
+    );
+    controller.pause();
+  }
+}

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

@@ -4,11 +4,13 @@ import 'package:ijkplayer_example/page/screen_shot_page.dart';
 import 'package:ijkplayer_example/page/video_list.dart';
 
 import '../i18n/i18n.dart';
-import 'error_url.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';
 import 'full_screen.dart';
 import 'gallery_page.dart';
 import 'ijk_status_page.dart';
@@ -29,6 +31,7 @@ class _IndexPageState extends State<IndexPage> {
       ),
       body: ListView(
         children: <Widget>[
+          buildButton("For developer, user don't use.", DevelopingIndexPage()),
           buildButton(currentI18n.networkButton, NetworkPage()),
           buildButton(currentI18n.photoButton, PlayGalleryPage()),
           buildButton(currentI18n.assetButton, AssetPage()),

+ 20 - 14
ios/Classes/CoolFlutterIJK.m

@@ -4,9 +4,7 @@
 
 #import "CoolFlutterIJK.h"
 #import "CoolVideoInfo.h"
-#import "CoolIjkNotifyChannel.h"
-#import <IJKMediaFramework/IJKMediaFramework.h>
-#import <IJKMediaFramework/IJKMediaPlayer.h>
+#import "CoolFlutterResult.h"
 #import <AVFoundation/AVFoundation.h>
 #import <libkern/OSAtomic.h>
 
@@ -22,6 +20,7 @@
     FlutterMethodChannel *channel;
     CoolIjkNotifyChannel *notifyChannel;
     int degree;
+    CoolFlutterResult *prepareResult;
 }
 
 - (instancetype)initWithRegistrar:(NSObject <FlutterPluginRegistrar> *)registrar {
@@ -67,8 +66,7 @@
             NSDictionary *params = call.arguments;
             NSString *uri = params[@"uri"];
             NSDictionary *headers = params[@"headers"];
-            [self setDataSourceWithUri:uri headers:headers];
-            result(@(YES));
+            [self setDataSourceWithUri:uri headers:headers result:[CoolFlutterResult resultWithResult:result]];
         }
         @catch (NSException *exception) {
             NSLog(@"Exception occurred: %@, %@", exception, [exception userInfo]);
@@ -80,8 +78,7 @@
             NSString *name = params[@"name"];
             NSString *pkg = params[@"package"];
             IJKFFMoviePlayerController *playerController = [self createControllerWithAssetName:name pkg:pkg];
-            [self setDataSourceWithController:playerController];
-            result(@(YES));
+            [self setDataSourceWithController:playerController result:[CoolFlutterResult resultWithResult:result]];
         }
         @catch (NSException *exception) {
             NSLog(@"Exception occurred: %@, %@", exception, [exception userInfo]);
@@ -91,8 +88,7 @@
         NSDictionary *params = call.arguments;
         NSString *path = params[@"path"];
         IJKFFMoviePlayerController *playerController = [self createControllerWithPath:path];
-        [self setDataSourceWithController:playerController];
-        result(@(YES));
+        [self setDataSourceWithController:playerController result:[CoolFlutterResult resultWithResult:result]];
     } else if ([@"seekTo" isEqualToString:call.method]) {
         NSDictionary *params = call.arguments;
         double target = [params[@"target"] doubleValue];
@@ -150,10 +146,10 @@
     }
 }
 
-- (void)setDataSourceWithController:(IJKFFMoviePlayerController *)ctl {
+- (void)setDataSourceWithController:(IJKFFMoviePlayerController *)ctl result:(CoolFlutterResult *)result {
     if (ctl) {
         controller = ctl;
-        [self prepare];
+        [self prepare:result];
     }
 }
 
@@ -221,7 +217,7 @@
     return options;
 }
 
-- (void)setDataSourceWithUri:(NSString *)uri headers:(NSDictionary *)headers {
+- (void)setDataSourceWithUri:(NSString *)uri headers:(NSDictionary *)headers result:(CoolFlutterResult *)result {
     IJKFFOptions *options = [self createOption];
     if (headers) {
         NSMutableString *headerString = [NSMutableString new];
@@ -234,7 +230,7 @@
     }
     controller = [[IJKFFMoviePlayerController alloc] initWithContentURLString:uri withOptions:options];
 
-    [self prepare];
+    [self prepare:result];
 }
 
 - (void)setDegree:(int)d {
@@ -242,7 +238,8 @@
 }
 
 
-- (void)prepare {
+- (void)prepare:(CoolFlutterResult *)result {
+    prepareResult = result;
     [controller prepareToPlay];
     if (displayLink) {
         displayLink.paused = YES;
@@ -258,6 +255,15 @@
     notifyChannel.infoDelegate = self;
 }
 
+- (void)onLoadStateChange {
+//    IJKMPMovieLoadState loadState = controller.loadState;
+    if (prepareResult) {
+        [prepareResult replyResult:@YES];
+    }
+    prepareResult = nil;
+}
+
+
 - (IJKFFMoviePlayerController *)createControllerWithAssetName:(NSString *)assetName pkg:(NSString *)pkg {
     NSString *asset;
     if (!pkg) {

+ 20 - 0
ios/Classes/CoolFlutterResult.h

@@ -0,0 +1,20 @@
+//
+// Created by Caijinglong on 2019-06-12.
+//
+
+
+#import <Flutter/Flutter.h>
+
+@interface CoolFlutterResult : NSObject
+
+@property(nonatomic, strong) FlutterResult result;
+
+@property(nonatomic, assign) BOOL isReply;
+
+- (instancetype)initWithResult:(FlutterResult)result;
+
++ (instancetype)resultWithResult:(FlutterResult)result;
+
+- (void)replyResult:(id _Nullable)result;
+
+@end

+ 33 - 0
ios/Classes/CoolFlutterResult.m

@@ -0,0 +1,33 @@
+//
+// Created by Caijinglong on 2019-06-12.
+//
+
+#import "CoolFlutterResult.h"
+
+@implementation CoolFlutterResult {
+
+}
+- (instancetype)initWithResult:(FlutterResult)result {
+    self = [super init];
+    if (self) {
+        self.result = result;
+        self.isReply = NO;
+    }
+
+    return self;
+}
+
++ (instancetype)resultWithResult:(FlutterResult)result {
+    return [[self alloc] initWithResult:result];
+}
+
+- (void)replyResult:(id _Nullable)result {
+    if (self.isReply) {
+        return;
+    }
+    self.isReply = YES;
+    self.result(result);
+}
+
+
+@end

+ 2 - 0
ios/Classes/CoolIjkNotifyChannel.h

@@ -12,6 +12,8 @@
 - (CoolVideoInfo *)getInfo;
 
 - (void)setDegree:(int)newDegree;
+
+- (void)onLoadStateChange;
 @end
 
 @interface CoolIjkNotifyChannel : NSObject

+ 2 - 1
ios/Classes/CoolIjkNotifyChannel.m

@@ -122,7 +122,8 @@
 }
 
 - (void)loadStateDidChange:(NSNotification *)notification {
-//    [channel invokeMethod:@"loadStateChange" arguments:[self getInfo]];
+    NSLog(@"load state change, state = %lu", (unsigned long)_controller.loadState);
+    [self.infoDelegate onLoadStateChange];
 }
 
 - (void)movieRotationChange:(NSNotification *)notification {

+ 32 - 26
lib/src/controller/controller.dart

@@ -40,6 +40,8 @@ class IjkMediaController
         options.addAll(opt);
       }
 
+      print("options = $options");
+
       var id = await _createIjk(options: options);
       this.textureId = id;
       _plugin = _IjkPlugin(id);
@@ -82,13 +84,12 @@ class IjkMediaController
     bool autoPlay = false,
   }) async {
     _ijkStatus = IjkStatus.preparing;
-    await _initDataSource(() async {
-      await _plugin?.setNetworkDataSource(
-        uri: url,
-        headers: headers,
-      );
-      _ijkStatus = IjkStatus.prepared;
-    }, autoPlay);
+    await _initDataSource(autoPlay);
+    await _plugin?.setNetworkDataSource(
+      uri: url,
+      headers: headers,
+    );
+    _ijkStatus = IjkStatus.prepared;
   }
 
   /// set asset DataSource
@@ -100,10 +101,9 @@ class IjkMediaController
     bool autoPlay = false,
   }) async {
     _ijkStatus = IjkStatus.preparing;
-    await _initDataSource(() async {
-      await _plugin?.setAssetDataSource(name, package);
-      _ijkStatus = IjkStatus.prepared;
-    }, autoPlay);
+    await _initDataSource(autoPlay);
+    await _plugin?.setAssetDataSource(name, package);
+    _ijkStatus = IjkStatus.prepared;
   }
 
   /// set file DataSource
@@ -114,10 +114,9 @@ class IjkMediaController
     bool autoPlay = false,
   }) async {
     _ijkStatus = IjkStatus.preparing;
-    await _initDataSource(() async {
-      await _plugin?.setFileDataSource(file.absolute.path);
-      _ijkStatus = IjkStatus.prepared;
-    }, autoPlay);
+    await _initDataSource(autoPlay);
+    await _plugin?.setFileDataSource(file.absolute.path);
+    _ijkStatus = IjkStatus.prepared;
   }
 
   /// Set datasource with [DataSource]
@@ -150,24 +149,31 @@ class IjkMediaController
     }
   }
 
+  void setAutoPlay() {
+    this.addIjkPlayerOptions([
+      TargetPlatform.android,
+      TargetPlatform.iOS,
+    ], [
+      IjkOption(IjkOptionCategory.player, "start-on-prepared", 0),
+    ]);
+  }
+
   /// dispose last textureId resource
-  Future<void> _initDataSource(
-    Future setDataSource(),
-    bool autoPlay,
-  ) async {
+  Future<void> _initDataSource(bool autoPlay) async {
     autoPlay ??= false;
 
+    var autoPlayValue = autoPlay ? 1 : 0;
+    addIjkPlayerOptions([
+      TargetPlatform.android,
+      TargetPlatform.iOS,
+    ], [
+      IjkOption(IjkOptionCategory.player, "start-on-prepared", autoPlayValue),
+    ]);
+
     if (this.textureId != null) {
       await _plugin?.dispose();
     }
     await _initIjk();
-    Future playFuture = _autoPlay(autoPlay);
-    try {
-      await setDataSource();
-    } on Exception catch (e) {
-      print("init data error is ${e.toString()}");
-    }
-    return playFuture;
   }
 
   /// Play or pause according to your current status

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

@@ -44,4 +44,9 @@ class IjkOption {
     }
     return this.category == other.category && this.key == other.key;
   }
+
+  @override
+  String toString() {
+    return 'IjkOption{category: $category, key: $key, value: $value}';
+  }
 }