Ver Fonte

ijkplayer内部自适应视频宽高和角度

Caijinglong há 6 anos atrás
pai
commit
09bd34510e

+ 11 - 7
example/lib/main.dart

@@ -59,14 +59,9 @@ class HomePageState extends State<HomePage> {
       body: Container(
         // width: MediaQuery.of(context).size.width,
         // height: 400,
-        child: Column(
+        child: ListView(
           children: <Widget>[
-            AspectRatio(
-              aspectRatio: 1280 / 720,
-              child: IjkPlayer(
-                mediaController: controller,
-              ),
-            ),
+            buildIjkPlayer(),
             _buildPlayAssetButton(),
             _buildControllerButtons(),
             _buildVolumeBar(),
@@ -91,6 +86,15 @@ class HomePageState extends State<HomePage> {
     );
   }
 
+  Widget buildIjkPlayer() {
+    return Container(
+      height: 400,
+      child: IjkPlayer(
+        mediaController: controller,
+      ),
+    );
+  }
+
   void _pickVideo() async {
     List<AssetEntity> imgList = await PhotoPicker.pickAsset(
       // BuildContext required

+ 11 - 5
lib/src/controller.dart

@@ -2,8 +2,14 @@ part of './ijkplayer.dart';
 
 /// Media Controller
 class IjkMediaController {
+  IjkMediaController({
+    this.autoRotate = true,
+  });
+
   int _textureId;
 
+  bool autoRotate;
+
   int get textureId => _textureId;
 
   set textureId(int id) {
@@ -161,25 +167,25 @@ class IjkMediaController {
   Future<void> refreshVideoInfo() async {
     var info = await getVideoInfo();
     isPlaying = info.isPlaying;
-    if (info.hasData) _videoInfoController.add(info);
+    if (info.hasData) _videoInfoController?.add(info);
     print("info = $info");
   }
 
   void _autoPlay(bool autoPlay) {
     if (autoPlay) {
-      eventChannel.autoPlay(this);
+      eventChannel?.autoPlay(this);
     }
   }
 
   Future<void> _setVolume(int volume) async {
-    await _plugin.setVolume(volume);
+    await _plugin?.setVolume(volume);
   }
 
   Future<void> stop() async {
 //    await _plugin?.stop();
 //    refreshVideoInfo();
-    await _plugin.pause();
-    await _plugin.seekTo(0);
+    await _plugin?.pause();
+    await _plugin?.seekTo(0);
     refreshVideoInfo();
   }
 }

+ 21 - 3
lib/src/ijkplayer.dart

@@ -5,11 +5,13 @@ import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 import 'package:flutter_ijkplayer/src/ijk_event_channel.dart';
 import 'package:flutter_ijkplayer/src/video_info.dart';
-import './error.dart';
+import 'package:flutter_ijkplayer/src/widget/ijkplayer_builder.dart';
 
 import './controller_builder.dart';
+import './error.dart';
 
 part './controller.dart';
+
 part './manager.dart';
 
 typedef Widget ControllerWidgetBuilder(IjkMediaController controller);
@@ -17,11 +19,13 @@ typedef Widget ControllerWidgetBuilder(IjkMediaController controller);
 class IjkPlayer extends StatefulWidget {
   final IjkMediaController mediaController;
   final ControllerWidgetBuilder controllerWidgetBuilder;
+  final PlayerBuilder playerBuilder;
 
   const IjkPlayer({
     Key key,
     this.mediaController,
     this.controllerWidgetBuilder = defaultBuildIjkControllerWidget,
+    this.playerBuilder = buildDefaultIjkPlayer,
   }) : super(key: key);
 
   @override
@@ -37,6 +41,11 @@ class IjkPlayerState extends State<IjkPlayer> {
     controller = widget.mediaController ?? IjkMediaController();
   }
 
+  @override
+  void didUpdateWidget(IjkPlayer oldWidget) {
+    super.didUpdateWidget(oldWidget);
+  }
+
   @override
   void dispose() {
     controller?.dispose();
@@ -52,7 +61,12 @@ class IjkPlayerState extends State<IjkPlayer> {
         if (!snapshot.hasData) {
           return Container();
         }
-        return _buildVideoContent(snapshot.data);
+        var id = snapshot.data;
+        return StreamBuilder<VideoInfo>(
+            stream: controller.videoInfoStream,
+            builder: (context, videoInfoSnapShot) {
+              return _buildTexture(id, videoInfoSnapShot.data);
+            });
       },
     );
     var controllerWidget = widget.controllerWidgetBuilder?.call(controller);
@@ -64,7 +78,11 @@ class IjkPlayerState extends State<IjkPlayer> {
     );
   }
 
-  Widget _buildVideoContent(int id) {
+  Widget _buildTexture(int id, VideoInfo info) {
+    if (widget?.playerBuilder != null) {
+      return widget.playerBuilder.call(context, controller, info);
+    }
+
     if (id == null) {
       return Container(
         color: Colors.black,

+ 13 - 0
lib/src/video_info.dart

@@ -6,6 +6,7 @@ class VideoInfo {
   double duration;
   double currentPosition;
   bool isPlaying;
+  int degree;
 
   Map<String, dynamic> _map;
 
@@ -15,6 +16,17 @@ class VideoInfo {
 
   bool get hasData => _map != null;
 
+  double get ratio {
+    double r;
+    if (width != null && height != null) {
+      r = width / height;
+    } else {
+      r = 1280 / 720;
+    }
+
+    return r;
+  }
+
   VideoInfo.fromMap(Map<String, dynamic> map) {
     if (map == null) {
       return;
@@ -25,6 +37,7 @@ class VideoInfo {
     this.duration = map["duration"];
     this.currentPosition = map["currentPosition"];
     this.isPlaying = map["isPlaying"];
+    this.degree = map["degree"];
   }
 
   @override

+ 51 - 0
lib/src/widget/ijkplayer_builder.dart

@@ -0,0 +1,51 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
+
+typedef Widget PlayerBuilder(
+  BuildContext context,
+  IjkMediaController controller,
+  VideoInfo info,
+);
+
+Widget buildDefaultIjkPlayer(
+  BuildContext context,
+  IjkMediaController controller,
+  VideoInfo info,
+) {
+  print("buildPlayer");
+
+  int degree = info?.degree ?? 0;
+  double ratio = info?.ratio ?? 1280 / 720;
+
+  var id = controller.textureId;
+
+  if (id == null) {
+    return Container(
+      color: Colors.black,
+    );
+  }
+
+  Widget w = Container(
+    child: Texture(
+      textureId: id,
+    ),
+  );
+
+  w = AspectRatio(
+    aspectRatio: ratio,
+    child: w,
+  );
+
+  if (degree != 0) {
+    w = RotatedBox(
+      quarterTurns: degree ~/ 90,
+      child: w,
+    );
+  }
+
+  return Container(
+    child: w,
+    alignment: Alignment.center,
+    color: Colors.black,
+  );
+}