Jelajahi Sumber

更新了example中的代码

Caijinglong 6 tahun lalu
induk
melakukan
b7f01901c2

+ 2 - 210
example/lib/main.dart

@@ -3,6 +3,7 @@ import 'dart:io';
 
 import 'package:flutter/material.dart';
 import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
+import 'package:ijkplayer_example/page/index.dart';
 import 'package:photo/photo.dart';
 import 'package:photo_manager/photo_manager.dart';
 
@@ -21,216 +22,7 @@ class _MyAppState extends State<MyApp> {
   @override
   Widget build(BuildContext context) {
     return MaterialApp(
-      home: HomePage(),
-    );
-  }
-}
-
-class HomePage extends StatefulWidget {
-  @override
-  HomePageState createState() => HomePageState();
-}
-
-class HomePageState extends State<HomePage> {
-  IjkMediaController controller = IjkMediaController();
-
-  @override
-  void initState() {
-    super.initState();
-  }
-
-  @override
-  void dispose() {
-    controller.dispose();
-    super.dispose();
-  }
-
-  @override
-  Widget build(BuildContext context) {
-    return Scaffold(
-      appBar: AppBar(
-        title: const Text('Plugin example app'),
-        actions: <Widget>[
-          IconButton(
-            icon: Icon(Icons.videocam),
-            onPressed: _pickVideo,
-          ),
-        ],
-      ),
-      body: Container(
-        // width: MediaQuery.of(context).size.width,
-        // height: 400,
-        child: ListView(
-          children: <Widget>[
-            buildIjkPlayer(),
-            _buildPlayAssetButton(),
-            _buildControllerButtons(),
-            _buildVolumeBar(),
-            _buildSystemVolumeButton(),
-          ],
-        ),
-      ),
-      floatingActionButton: FloatingActionButton(
-        child: Icon(Icons.play_arrow),
-        onPressed: () async {
-          await controller.setNetworkDataSource(
-//              'http://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_20mb.mp4',
-              'https://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_20mb.mp4',
-//              'rtmp://172.16.100.245/live1',
-              // 'https://www.sample-videos.com/video123/flv/720/big_buck_bunny_720p_10mb.flv',
-//              "https://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4",
-              // 'http://184.72.239.149/vod/smil:BigBuckBunny.smil/playlist.m3u8',
-              // "file:///sdcard/Download/Sample1.mp4",
-              autoPlay: true);
-          print("set data source success");
-          // controller.playOrPause();
-        },
-      ),
-    );
-  }
-
-  Widget buildIjkPlayer() {
-    return Container(
-      height: 400,
-      child: IjkPlayer(
-        mediaController: controller,
-      ),
-    );
-  }
-
-  void _pickVideo() async {
-    List<AssetEntity> imgList = await PhotoPicker.pickAsset(
-      // BuildContext required
-      context: context,
-
-      /// The following are optional parameters.
-      themeColor: Colors.green,
-      // the title color and bottom color
-      padding: 1.0,
-      // item padding
-      dividerColor: Colors.grey,
-      // divider color
-      disableColor: Colors.grey.shade300,
-      // the check box disable color
-      itemRadio: 0.88,
-      // the content item radio
-      maxSelected: 8,
-      // max picker image count
-      // provider: I18nProvider.english,
-      provider: I18nProvider.chinese,
-      // i18n provider ,default is chinese. , you can custom I18nProvider or use ENProvider()
-      rowCount: 3,
-      // item row count
-      textColor: Colors.white,
-      // text color
-      thumbSize: 160,
-      // preview thumb size , default is 64
-      sortDelegate: SortDelegate.common,
-      // default is common ,or you make custom delegate to sort your gallery
-      checkBoxBuilderDelegate: DefaultCheckBoxBuilderDelegate(
-        activeColor: Colors.white,
-        unselectedColor: Colors.white,
-      ),
-      // default is DefaultCheckBoxBuilderDelegate ,or you make custom delegate to create checkbox
-
-      badgeDelegate: const DurationBadgeDelegate(),
-      // badgeDelegate to show badge widget
-
-      pickType: PickType.onlyVideo,
-    );
-
-    if (imgList != null && imgList.isNotEmpty) {
-      var asset = imgList[0];
-      var file = (await asset.file).absolute;
-      playFile(file);
-    }
-  }
-
-  void playFile(File file) async {
-    await controller.setFileDataSource(file, autoPlay: true);
-  }
-
-  void playUri(String uri) async {
-    await controller.setNetworkDataSource(uri, autoPlay: true);
-  }
-
-  _buildPlayAssetButton() {
-    return FlatButton(
-      child: Text("play sample asset"),
-      onPressed: () async {
-        await controller.setAssetDataSource(
-          "assets/sample1.mp4",
-          autoPlay: true,
-        );
-
-        Timer.periodic(Duration(seconds: 2), (timer) async {
-          var info = await controller.getVideoInfo();
-          print("info = $info");
-          if (info == null) {
-            return;
-          }
-
-          if (info.progress >= 0.95) {
-            timer.cancel();
-          }
-        });
-      },
-    );
-  }
-
-  _buildControllerButtons() {
-    return Row(
-      children: <Widget>[
-        FlatButton(
-          child: StreamBuilder<bool>(
-            stream: controller.playingStream,
-            initialData: controller?.isPlaying ?? false,
-            builder: (context, snapshot) {
-              var isPlaying = snapshot.hasData && snapshot.data;
-              return Text(isPlaying ? "暂停" : "播放");
-            },
-          ),
-          onPressed: () async {
-            await controller?.playOrPause();
-          },
-        ),
-        FlatButton(
-          child: Text("停止"),
-          onPressed: () async {
-            await controller?.stop();
-          },
-        ),
-      ],
-    );
-  }
-
-  _buildVolumeBar() {
-    return StreamBuilder<int>(
-      stream: controller?.volumeStream,
-      initialData: controller?.volume,
-      builder: (context, snapshot) {
-        if (!snapshot.hasData) {
-          return Container();
-        }
-        var volume = snapshot.data;
-        return Slider(
-          value: volume / 100,
-          onChanged: (double value) {
-            var targetVolume = (value * 100).toInt();
-            controller.volume = targetVolume;
-          },
-        );
-      },
-    );
-  }
-
-  _buildSystemVolumeButton() {
-    return FlatButton(
-      child: Text("显示系统音量"),
-      onPressed: () async {
-        var systemVolume = await IjkManager.getSystemVolume();
-        print(systemVolume);
-      },
+      home: IndexPage(),
     );
   }
 }

+ 82 - 0
example/lib/page/gallery_page.dart

@@ -0,0 +1,82 @@
+import 'dart:io';
+
+import 'package:flutter/material.dart';
+import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
+import 'package:photo/photo.dart';
+
+class PlayGalleryPage extends StatefulWidget {
+  @override
+  _PlayGalleryPageState createState() => _PlayGalleryPageState();
+}
+
+class _PlayGalleryPageState extends State<PlayGalleryPage> {
+  IjkMediaController mediaController = IjkMediaController();
+
+  File file;
+
+  @override
+  void initState() {
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    mediaController.dispose();
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        title: Text("播放相册视频"),
+      ),
+      body: ListView(
+        children: <Widget>[
+          FlatButton(
+            child: Text("选择"),
+            onPressed: _pickVideo,
+          ),
+          _buildFileText(),
+          Container(
+            height: 400,
+            child: IjkPlayer(
+              mediaController: mediaController,
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+
+  _buildFileText() {
+    if (file?.existsSync() == true) {
+      return Padding(
+        padding: const EdgeInsets.all(8.0),
+        child: Text(
+          "file.path: ${file.path}",
+          textAlign: TextAlign.center,
+        ),
+      );
+    }
+    return Container();
+  }
+
+  void _pickVideo() async {
+    var assetList = await PhotoPicker.pickAsset(
+      context: context,
+      pickType: PickType.onlyVideo,
+      maxSelected: 1,
+    );
+    if (assetList?.isNotEmpty == true) {
+      var asset = assetList[0];
+      this.file = await asset.file;
+      _playVideo();
+    }
+  }
+
+  void _playVideo() async {
+    if (this.file != null && this.file.existsSync())
+      await mediaController.setFileDataSource(file, autoPlay: true);
+  }
+}

+ 34 - 0
example/lib/page/index.dart

@@ -0,0 +1,34 @@
+import 'package:flutter/material.dart';
+import 'package:ijkplayer_example/page/gallery_page.dart';
+import 'package:ijkplayer_example/page/network.dart';
+
+class IndexPage extends StatefulWidget {
+  @override
+  _IndexPageState createState() => _IndexPageState();
+}
+
+class _IndexPageState extends State<IndexPage> {
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        title: Text("首页"),
+      ),
+      body: ListView(
+        children: <Widget>[
+          buildButton("播放网络视频", NetworkPage()),
+          buildButton("播放相册视频", PlayGalleryPage()),
+        ],
+      ),
+    );
+  }
+
+  Widget buildButton(String text, Widget targetPage) {
+    return FlatButton(
+      onPressed: () {
+        Navigator.push(context, MaterialPageRoute(builder: (_) => targetPage));
+      },
+      child: Text(text),
+    );
+  }
+}

+ 63 - 0
example/lib/page/network.dart

@@ -0,0 +1,63 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
+
+class NetworkPage extends StatefulWidget {
+  @override
+  _NetworkPageState createState() => _NetworkPageState();
+}
+
+class _NetworkPageState extends State<NetworkPage> {
+  TextEditingController editingController = TextEditingController();
+  IjkMediaController mediaController = IjkMediaController();
+
+  @override
+  void initState() {
+    super.initState();
+    editingController.text =
+        "https://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_20mb.mp4";
+  }
+
+  @override
+  void dispose() {
+    editingController.dispose();
+    mediaController.dispose();
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        title: Text("播放网络资源"),
+      ),
+      body: ListView(
+        children: <Widget>[
+          Row(
+            children: <Widget>[
+              Expanded(
+                child: TextField(
+                  controller: editingController,
+                ),
+              ),
+              FlatButton(
+                child: Text("播放"),
+                onPressed: _playInput,
+              ),
+            ],
+          ),
+          Container(
+            height: 400,
+            child: IjkPlayer(
+              mediaController: mediaController,
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+
+  void _playInput() async {
+    var text = editingController.text;
+    await mediaController.setNetworkDataSource(text, autoPlay: true);
+  }
+}

+ 216 - 0
example/lib/page/simple_use.dart

@@ -0,0 +1,216 @@
+import 'dart:async';
+import 'dart:io';
+
+import 'package:flutter/material.dart';
+import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
+import 'package:photo/photo.dart';
+import 'package:photo_manager/photo_manager.dart';
+
+class HomePage extends StatefulWidget {
+  @override
+  HomePageState createState() => HomePageState();
+}
+
+class HomePageState extends State<HomePage> {
+  IjkMediaController controller = IjkMediaController();
+
+  @override
+  void initState() {
+    super.initState();
+  }
+
+  @override
+  void dispose() {
+    controller?.dispose();
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        title: const Text('Plugin example app'),
+        actions: <Widget>[
+          IconButton(
+            icon: Icon(Icons.videocam),
+            onPressed: _pickVideo,
+          ),
+        ],
+      ),
+      body: Container(
+        // width: MediaQuery.of(context).size.width,
+        // height: 400,
+        child: ListView(
+          children: <Widget>[
+            buildIjkPlayer(),
+            _buildPlayAssetButton(),
+            _buildControllerButtons(),
+            _buildVolumeBar(),
+            _buildSystemVolumeButton(),
+          ],
+        ),
+      ),
+      floatingActionButton: FloatingActionButton(
+        child: Icon(Icons.play_arrow),
+        onPressed: () async {
+          await controller.setNetworkDataSource(
+//              'http://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_20mb.mp4',
+              'https://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_20mb.mp4',
+//              'rtmp://172.16.100.245/live1',
+              // 'https://www.sample-videos.com/video123/flv/720/big_buck_bunny_720p_10mb.flv',
+//              "https://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4",
+              // 'http://184.72.239.149/vod/smil:BigBuckBunny.smil/playlist.m3u8',
+              // "file:///sdcard/Download/Sample1.mp4",
+              autoPlay: true);
+          print("set data source success");
+          // controller.playOrPause();
+        },
+      ),
+    );
+  }
+
+  Widget buildIjkPlayer() {
+    return Container(
+      height: 400,
+      child: IjkPlayer(
+        mediaController: controller,
+      ),
+    );
+  }
+
+  void _pickVideo() async {
+    List<AssetEntity> imgList = await PhotoPicker.pickAsset(
+      // BuildContext required
+      context: context,
+
+      /// The following are optional parameters.
+      themeColor: Colors.green,
+      // the title color and bottom color
+      padding: 1.0,
+      // item padding
+      dividerColor: Colors.grey,
+      // divider color
+      disableColor: Colors.grey.shade300,
+      // the check box disable color
+      itemRadio: 0.88,
+      // the content item radio
+      maxSelected: 8,
+      // max picker image count
+      // provider: I18nProvider.english,
+      provider: I18nProvider.chinese,
+      // i18n provider ,default is chinese. , you can custom I18nProvider or use ENProvider()
+      rowCount: 3,
+      // item row count
+      textColor: Colors.white,
+      // text color
+      thumbSize: 160,
+      // preview thumb size , default is 64
+      sortDelegate: SortDelegate.common,
+      // default is common ,or you make custom delegate to sort your gallery
+      checkBoxBuilderDelegate: DefaultCheckBoxBuilderDelegate(
+        activeColor: Colors.white,
+        unselectedColor: Colors.white,
+      ),
+      // default is DefaultCheckBoxBuilderDelegate ,or you make custom delegate to create checkbox
+
+      badgeDelegate: const DurationBadgeDelegate(),
+      // badgeDelegate to show badge widget
+
+      pickType: PickType.onlyVideo,
+    );
+
+    if (imgList != null && imgList.isNotEmpty) {
+      var asset = imgList[0];
+      var file = (await asset.file).absolute;
+      playFile(file);
+    }
+  }
+
+  void playFile(File file) async {
+    await controller.setFileDataSource(file, autoPlay: true);
+  }
+
+  void playUri(String uri) async {
+    await controller.setNetworkDataSource(uri, autoPlay: true);
+  }
+
+  _buildPlayAssetButton() {
+    return FlatButton(
+      child: Text("play sample asset"),
+      onPressed: () async {
+        await controller.setAssetDataSource(
+          "assets/sample1.mp4",
+          autoPlay: true,
+        );
+
+        Timer.periodic(Duration(seconds: 2), (timer) async {
+          var info = await controller.getVideoInfo();
+          print("info = $info");
+          if (info == null) {
+            return;
+          }
+
+          if (info.progress >= 0.95) {
+            timer.cancel();
+          }
+        });
+      },
+    );
+  }
+
+  _buildControllerButtons() {
+    return Row(
+      children: <Widget>[
+        FlatButton(
+          child: StreamBuilder<bool>(
+            stream: controller.playingStream,
+            initialData: controller?.isPlaying ?? false,
+            builder: (context, snapshot) {
+              var isPlaying = snapshot.hasData && snapshot.data;
+              return Text(isPlaying ? "暂停" : "播放");
+            },
+          ),
+          onPressed: () async {
+            await controller?.playOrPause();
+          },
+        ),
+        FlatButton(
+          child: Text("停止"),
+          onPressed: () async {
+            await controller?.stop();
+          },
+        ),
+      ],
+    );
+  }
+
+  _buildVolumeBar() {
+    return StreamBuilder<int>(
+      stream: controller?.volumeStream,
+      initialData: controller?.volume,
+      builder: (context, snapshot) {
+        if (!snapshot.hasData) {
+          return Container();
+        }
+        var volume = snapshot.data;
+        return Slider(
+          value: volume / 100,
+          onChanged: (double value) {
+            var targetVolume = (value * 100).toInt();
+            controller.volume = targetVolume;
+          },
+        );
+      },
+    );
+  }
+
+  _buildSystemVolumeButton() {
+    return FlatButton(
+      child: Text("显示系统音量"),
+      onPressed: () async {
+        var systemVolume = await IjkManager.getSystemVolume();
+        print(systemVolume);
+      },
+    );
+  }
+}

+ 1 - 1
example/pubspec.lock

@@ -47,7 +47,7 @@ packages:
       path: ".."
       relative: true
     source: path
-    version: "0.1.3"
+    version: "0.1.4"
   flutter_test:
     dependency: "direct dev"
     description: flutter

+ 15 - 10
lib/src/controller.dart

@@ -26,7 +26,7 @@ class IjkMediaController {
   StreamController<int> _textureIdController = StreamController.broadcast();
 
   /// on texture id change
-  Stream<int> get textureIdStream => _textureIdController.stream;
+  Stream<int> get textureIdStream => _textureIdController?.stream;
 
   /// Channel of flutter and native.
   _IjkPlugin _plugin;
@@ -46,27 +46,27 @@ class IjkMediaController {
   /// playing state
   set isPlaying(bool value) {
     this._isPlaying = value;
-    _playingController.add(value);
+    _playingController?.add(value);
   }
 
   /// playing state stream controller
   StreamController<bool> _playingController = StreamController.broadcast();
 
   /// playing state stream
-  Stream<bool> get playingStream => _playingController.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;
+  Stream<VideoInfo> get videoInfoStream => _videoInfoController?.stream;
 
   /// video volume stream controller
   StreamController<int> _volumeController = StreamController.broadcast();
 
   /// video volume stream
-  Stream<int> get volumeStream => _volumeController.stream;
+  Stream<int> get volumeStream => _volumeController?.stream;
 
   /// video volume, not system volume
   int _volume = 100;
@@ -79,7 +79,7 @@ class IjkMediaController {
       value = 0;
     }
     this._volume = value;
-    _volumeController.add(value);
+    _volumeController?.add(value);
     _setVolume(value);
   }
 
@@ -104,10 +104,15 @@ class IjkMediaController {
   /// [reset] and close all controller
   void dispose() async {
     await reset();
-    _playingController.close();
-    _videoInfoController.close();
-    _textureIdController.close();
-    _volumeController.close();
+    _playingController?.close();
+    _videoInfoController?.close();
+    _textureIdController?.close();
+    _volumeController?.close();
+
+    _playingController = null;
+    _videoInfoController = null;
+    _textureIdController = null;
+    _volumeController = null;
   }
 
   /// dispose all resource

+ 0 - 1
lib/src/ijkplayer.dart

@@ -52,7 +52,6 @@ class IjkPlayerState extends State<IjkPlayer> {
 
   @override
   void dispose() {
-    controller?.dispose();
     super.dispose();
   }
 

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

@@ -28,6 +28,7 @@ Widget buildDefaultIjkPlayer(
   }
 
   Widget w = Container(
+    color: Colors.black,
     child: Texture(
       textureId: id,
     ),