gplayer 0.0.2

  • Readme
  • Changelog
  • Example
  • Installing
  • 83

GPlayer #

pub package

Video Player plugin for Flutter,On Android, the backing player is base on ijkplayer 0.8.8 (not implement on iOS)

The example app running in Android

features #

  1. base on ijkplayer(ffmpeg),support RTMP , HLS (http & https) , MP4,M4A etc.
  2. gestures for volume control
  3. gestures for brightness control
  4. gestures for forward or backward
  5. support fullscreen
  6. try to replay when error(only for live video)
  7. specify video scale type
  8. support lazy load (download player on demand)
  9. customize media controller (without change this project source code)

note: this using lazy load for default,it will take a few seconds to download decoders before first play, if you want to include the decoder in your apk just find the android/build.gradle and add the dependencies which you want to support.

Getting Started #

1.add dependency #

First, add gplayer as a dependency in your pubspec.yaml file.

dependencies:
  flutter:
    sdk: flutter

  # add gplayer dependency
  gplayer: ^0.0.2

2.create player #

import 'package:flutter/material.dart';
import 'package:gplayer/gplayer.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  GPlayer player;
  @override
  void initState() {
    super.initState();
    //1.create & init player
    player = GPlayer(uri: 'http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4')
      ..init()
      ..addListener((_) {
        //update control button out of player
        setState(() {});
      });
  }

  @override
  void dispose() {
    player?.dispose(); //2.release player
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Video Demo',
      home: Scaffold(
        appBar: AppBar(
          title: Text('GPlayer'),
        ),
        body: player.display,//3.put the player display in Widget tree
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            setState(() {
              player.isPlaying ? player.pause() : player.start();
            });
          },
          child: Icon(
            player.isPlaying ? Icons.pause : Icons.play_arrow,
          ),
        ),
      ),
    );
  }
}

Customize media contoller #

1.define a class extend from buildMediaController

2.implement method Widget buildMediaController(BuildContext context)

3.pass the instance to player constructor GPlayer(uri:'',mediaController:MyMeidaController())

0.0.1 #

  • init release.

0.0.2 #

  • support float window
  • fixed some bugs

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:gplayer/defaultmediacontrol.dart';
import 'package:gplayer/gplayer.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  GPlayer player;

  @override
  void initState() {
    super.initState();
    player = GPlayer(
        uri: 'http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4',
        options: [Option(1, 'multiple_requests', 1)],
        mediaController: DefaultMediaController(
            title: 'bunny bear', gestureControlEnabled: true))
      ..init()
      ..addListener((_) {
        //update control button out of player
        setState(() {});
      });
  }

  void didUpdateWidget(oldWidget) {
    print('didUpdateWidget---------');
    super.didUpdateWidget(oldWidget);
  }

  @override
  void dispose() {
    super.dispose();
    player?.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Video Demo',
      routes: {'videoList': (context) => VideoList()},
      home: Scaffold(
        appBar: AppBar(
          title: Text('GPlayer'),
        ),
        body: Builder(
          builder: (context) =>
              Padding(
                padding: EdgeInsets.only(top: 0),
                child: ListView(
                  children: <Widget>[
                    AspectRatio(
                      aspectRatio: 16 / 9,
                      child: player.display,
                    ),
                    Padding(
                      padding: EdgeInsets.all(18),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: <Widget>[
                          Row(
                            children: <Widget>[
                              Text('landscapeWhenFullScreen:'),
                              Switch(
                                  value: player.landscapeWhenFullScreen,
                                  onChanged: (_) {
                                    player.landscapeWhenFullScreen = _;
                                    setState(() {});
                                  })
                            ],
                          ),
                          RaisedButton.icon(
                              onPressed: () {
                                player?.mediaController
                                    ?.control('toggleFloatWindow');
                              },
                              icon: Icon(Icons.featured_video),
                              label: Text("toggle float window")),
                          RaisedButton.icon(
                              onPressed: () {
                                if (player.isPlaying) {
                                  player.pause();
                                }
                                Navigator.pushNamed(context, 'videoList');
                              },
                              icon: Icon(Icons.list),
                              label: Text("video in list"))
                        ],
                      ),
                    ),
                  ],
                ),
              ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            setState(() {
              player.isPlaying ? player.pause() : player.start();
            });
          },
          child: Icon(
            player.isPlaying ? Icons.pause : Icons.play_arrow,
          ),
        ),
      ),
    );
  }
}

class GPlayerHolder extends StatefulWidget {
  final String url;
  final String title;

  GPlayerHolder({this.url, this.title});

  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return GPlayerHolderState();
  }
}

class GPlayerHolderState extends State<GPlayerHolder> {
  GPlayer player;

  @override
  void initState() {
    player = GPlayer(
        uri: widget.url,
        mediaController: DefaultMediaController(
            title: widget.title, gestureControlEnabled: false))
      ..init();
    super.initState();
  }


  @override
  void dispose() {
    player?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AspectRatio(
      aspectRatio: 16 / 9,
      child: player.display,
    );
  }
}

class VideoList extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    Widget divider1 = Divider(
      color: Colors.blue,
    );
    Widget divider2 = Divider(color: Colors.green);

    const videos = [
      'http://ivi.bupt.edu.cn/hls/cctv3hd.m3u8',
      'http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4',
      'http://ivi.bupt.edu.cn/hls/cctv6hd.m3u8',
      'http://zhibo.hkstv.tv/livestream/zb2yhapo/playlist.m3u8',
      'http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4',
    ];

    return Scaffold(
      appBar: AppBar(
        title: Text('video list'),
      ),
      body: ListView.separated(
          shrinkWrap: true,
          itemCount: videos.length,
          itemBuilder: (context, index) {
            return GPlayerHolder(
              title: 'video $index',
              url: videos[index],
            );
          },
          separatorBuilder: (BuildContext context, int index) {
            return index % 2 == 0 ? divider1 : divider2;
          }),
    );
  }
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  gplayer: ^0.0.2

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:gplayer/gplayer.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
75
Health:
Code health derived from static analysis. [more]
98
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
83
Overall:
Weighted score of the above. [more]
83
Learn more about scoring.

We analyzed this package on Apr 8, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.7.1
  • pana: 0.13.6
  • Flutter: 1.12.13+hotfix.8

Health suggestions

Fix lib/defaultmediacontrol.dart. (-1.99 points)

Analysis of lib/defaultmediacontrol.dart reported 4 hints:

line 313 col 14: 'ancestorStateOfType' is deprecated and shouldn't be used. Use findAncestorStateOfType instead. This feature was deprecated after v1.12.1..

line 313 col 40: 'TypeMatcher' is deprecated and shouldn't be used. TypeMatcher has been deprecated because it is no longer used in framework(only in deprecated methods). This feature was deprecated after v1.12.1..

line 319 col 14: 'ancestorStateOfType' is deprecated and shouldn't be used. Use findAncestorStateOfType instead. This feature was deprecated after v1.12.1..

line 319 col 40: 'TypeMatcher' is deprecated and shouldn't be used. TypeMatcher has been deprecated because it is no longer used in framework(only in deprecated methods). This feature was deprecated after v1.12.1..

Fix lib/gplayer.dart. (-0.50 points)

Analysis of lib/gplayer.dart reported 1 hint:

line 320 col 17: 'inheritFromWidgetOfExactType' is deprecated and shouldn't be used. Use dependOnInheritedWidgetOfExactType instead. This feature was deprecated after v1.12.1..

Format lib/util.dart.

Run flutter format to format lib/util.dart.

Maintenance suggestions

Package is pre-v0.1 release. (-10 points)

While nothing is inherently wrong with versions of 0.0.*, it might mean that the author is still experimenting with the general direction of the API.

The package description is too short. (-7 points)

Add more detail to the description field of pubspec.yaml. Use 60 to 180 characters to describe the package, what it does, and its target use case.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.1.0 <3.0.0
flutter 0.0.0
uuid ^2.0.2 2.0.4
Transitive dependencies
charcode 1.1.3
collection 1.14.11 1.14.12
convert 2.1.1
crypto 2.1.4
meta 1.1.8
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8