flutter_tencentplayer_plus 0.1.0

  • Readme
  • Changelog
  • Example
  • Installing
  • 69

简介 #

flutter_tencentplayer_plus 是基于腾讯云点播封装的flutter版的播放器插件 提供video_player 相似的api, 是flutter_tencentplayer的优化版本 ,flutter_tencentplayer 开源项目是我和大帅一起合作的一个开源项目,

支持功能 #

  1. 支持直播源
  2. 视频跳转
  3. 切换视频源
  4. 边下边播放
  5. 清晰度切换
  6. 设置播放速度

效果图 #

1.Setup #

flutter_tencentplayer_plus: ${last_version}

or

flutter_tencentplayer_plus:
    git:
      url: https://github.com/yxwandroid/flutter_tencentplayer_plus.git

For Android

  1. project/android/build.gradle 添加依赖的aar:
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
    pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
}

allprojects {
    repositories {
        google()
        jcenter()
        flatDir {
            dirs "${plugins.get("flutter_tencentplayer")}android/libs"
        }
    }
}
  1. AndroidManifest.xml 声明权限:

     <!--网络权限-->
    
     <uses-permission android:name="android.permission.INTERNET" />
    
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    
     <!--点播播放器悬浮窗权限-->
    
     <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    
     <!--存储-->
    
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    

For Ios


//项目的info.plist文件上添加如下权限 
<key>NSAppTransportSecurity</key>
	<dict>
		<key>NSAllowsArbitraryLoads</key>
		<true/>
  </dict>

2.Usage(TencentPlayer) #

1.初始化播放器

提供 asset、network、filePath、fileId四种方式播放

TencentPlayerController _controller;

_MyAppState() {
    listener = () {
      if (!mounted) {
        return;
      }
      setState(() {});
    };
}

initState() {
    _controller = TencentPlayerController.network('http://file.jinxianyun.com/testhaha.mp4', playerConfig: PlayerConfig())
    //_controller = TencentPlayerController.asset('static/tencent1.mp4')
    //_controller = TencentPlayerController.file('/storage/emulated/0/test.mp4')
    //_controller = TencentPlayerController.network(null, playerConfig: {auth: {"appId": 1252463788, "fileId": '4564972819220421305'}})
    ..initialize().then((_) {
        setState(() {});
      });
    _controller.addListener(listener);
}

2. (播放器配置参数 )

_controller = TencentPlayerController.network(url, playerConfig: PlayerConfig())

PropTypeDefaultNote
autoPlaybooltrue是否自动播放
loopboolfalse是否循环播放
headersMap<String, String>请求头
cachePathString缓存路径(边播放边下载)
progressIntervalint200播放进度回调频率(毫秒)
startTimeint0哪里开始播放(秒)
authMap<String, dynamic>云点播视频源appId&fileId

3. (播放器回调)

Text("总时长:" + _controller.value.duration.toString())
PropTypeNote
initializedbool是否初始化完成从而显示播放器
aspectRatiodouble用来控制播放器宽高比
durationDuration时长
positionDuration播放进度
playableDuration缓冲进度
isPlayingbool是否在播放
sizeSize视频宽高
isLoadingbool是否在加载
netSpeedint视频播放网速
ratedouble播放速度
bitrateIndexint视频清晰度

4. (播放器事件)

a.跳转进度

_controller.seekTo(Duration(seconds: 5));

b.设置播放速度

_controller.setRate(1.5); // 1.0 ~ 2.0

c.切换播放源

controller?.removeListener(listener);
controller?.pause();
controller = TencentPlayerController.network(url, playerConfig: PlayerConfig(startTime: startTime ?? controller.value.position.inSeconds));
controller?.initialize().then((_) {
  if (mounted) setState(() {});
});
controller?.addListener(listener);

d.切换清晰度(实质就是切换播放源)

3.Usage(Download) #

离线下载, 支持断点续传(这里只支持m3u8视频、fileId), 支持多文件同时下载

1.初始化下载器

DownloadController _downloadController;

_MyAppState() {
    downloadListener = () {
      if (!mounted) {
        return;
      }
      setState(() {});
    };
}

initState() {
    _downloadController = DownloadController('/storage/emulated/0/tencentdownload', appId: 1252463788);
    _downloadController.addListener(downloadListener);
}

2. (下载事件)

a. 下载

_downloadController.dowload("4564972819220421305", quanlity: 2);
// _downloadController.dowload("http://1253131631.vod2.myqcloud.com/26f327f9vodgzp1253131631/f4bdff799031868222924043041/playlist.m3u8");

b. 暂停下载

_downloadController.pauseDownload("4564972819220421305");
// _downloadController.stopDownload("http://1253131631.vod2.myqcloud.com/26f327f9vodgzp1253131631/f4bdff799031868222924043041/playlist.m3u8");

b. 取消下载

_downloadController.cancelDownload("4564972819220421305");
// _downloadController.cancelDownload("http://1253131631.vod2.myqcloud.com/26f327f9vodgzp1253131631/f4bdff799031868222924043041/playlist.m3u8");

3. (下载信息回调)

因为支持多文件同时下载,回调以Map<String, DownloadValue>返回,key为url/fileId

PropTypeNote
downloadStatusString"start"、"progress"、"stop"、"complete"、"error"
quanlityint1: "FLU"、2: "SD"、3: "HD"、4: "FHD"、5: "2K"、6: "4K"
durationint
sizeint文件大小
downloadSizeint已下载大小
progressint已下载大小
playPathString下载文件的绝对路径
isStopbool是否暂停下载
urlString下载的视频链接
fileIdString下载的视频FileId
errorString下载的错误信息

4.Example #

5.更新内容 #

 1,升级android,IOS  LiteAVSDK 6.8.7969

6.参考 #

腾讯云点播android版本 腾讯云点播ios版本 flutter_tencentplayer

0.1.0 #

  • 格式化代码

0.0.1 #

  • 初始化项目

example/lib/main.dart

import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter_tencentplayer_plus/flutter_tencentplayer_plus.dart';
import 'package:flutter_tencentplayer_plus_example/home_page.dart';

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

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

class _MyAppState extends State<MyApp> {
  TencentPlayerController _controller;
  VoidCallback listener;

  DownloadController _downloadController;
  VoidCallback downloadListener;

  String videoUrl =
      'http://5815.liveplay.myqcloud.com/live/5815_89aad37e06ff11e892905cb9018cf0d4.flv';
  String videoUrlB =
      'http://5815.liveplay.myqcloud.com/live/5815_89aad37e06ff11e892905cb9018cf0d4_550.flv';
  String videoUrlG =
      'http://5815.liveplay.myqcloud.com/live/5815_89aad37e06ff11e892905cb9018cf0d4_900.flv';
  String videoUrlAAA = 'http://file.jinxianyun.com/2018-06-12_16_58_22.mp4';
  String videoUrlBBB = 'http://file.jinxianyun.com/testhaha.mp4';
  String mu =
      'http://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/gear2/prog_index.m3u8';
  String spe1 =
      'http://1252463788.vod2.myqcloud.com/95576ef5vodtransgzp1252463788/e1ab85305285890781763144364/v.f10.mp4';
  String spe2 =
      'http://1252463788.vod2.myqcloud.com/95576ef5vodtransgzp1252463788/e1ab85305285890781763144364/v.f20.mp4';
  String spe3 =
      'http://1252463788.vod2.myqcloud.com/95576ef5vodtransgzp1252463788/e1ab85305285890781763144364/v.f30.mp4';

  String testDownload =
      'http://1253131631.vod2.myqcloud.com/26f327f9vodgzp1253131631/f4bdff799031868222924043041/playlist.m3u8';
  String downloadRes =
      '/storage/emulated/0/tencentdownload/txdownload/2c58873a5b9916f9fef5103c74f0ce5e.m3u8.sqlite';
  String downloadRes2 =
      '/storage/emulated/0/tencentdownload/txdownload/cf3e281653e562303c8c2b14729ba7f5.m3u8.sqlite';

  @override
  void initState() {
    super.initState();

    addListener();
    initPlatformState();
  }

  addListener() {
//    listener = () {
//      if (!mounted) {
//        return;
//      }
//      setState(() {});
//    };
    downloadListener = () {
      if (!mounted) {
        return;
      }
      setState(() {});
    };
  }

  Future<void> initPlatformState() async {
    //点播
//     _controller = TencentPlayerController.network(null, playerConfig:  PlayerConfig(
//        auth: {"appId": , "fileId": ''}
//    ))
    _controller = TencentPlayerController.network(spe3,
        playerConfig: PlayerConfig(autoPlay: false))

//        _controller = TencentPlayerController.asset('static/tencent1.mp4')
//        _controller = TencentPlayerController.file('/storage/emulated/0/test.mp4')
      ..initialize().then((_) {
        setState(() {});
      });

//    _controller.addListener(listener);
    /// 下载目录  ios 的和android的不一致 注意在ios项目运行的时候传递ios的目录
    _downloadController = DownloadController(
        '/storage/emulated/0/tencentdownload',
        appId: 1252463788);
    _downloadController.addListener(downloadListener);
  }

  @override
  void dispose() {
    super.dispose();
//    _controller.removeListener(listener);
    _downloadController.removeListener(downloadListener);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Video Demo',
      home: ValueListenableBuilder(
        valueListenable: _controller,
        builder:
            (BuildContext context, TencentPlayerValue value, Widget child) {
          return Scaffold(
            body: Container(
              child: Column(
                children: <Widget>[
                  Container(
                    child: Stack(
                      alignment: AlignmentDirectional.center,
                      children: <Widget>[
//                        _controller.value.initialized ?
                        AspectRatio(
                          aspectRatio: _controller.value.aspectRatio,
                          child: TencentPlayer(_controller),
                        ),
                        Center(
                          child: _controller.value.isLoading
                              ? CircularProgressIndicator()
                              : SizedBox(),
                        ),
                      ],
                    ),
                  ),
                  Expanded(
                    child: ListView(
                      children: <Widget>[
                        Text(
                          "播放网速:" + _controller.value.netSpeed.toString(),
                          style: TextStyle(color: Colors.pink),
                        ),
                        Text(
                          "错误:" + _controller.value.errorDescription.toString(),
                          style: TextStyle(color: Colors.pink),
                        ),
                        Text(
                          "播放进度:" + _controller.value.position.toString(),
                          style: TextStyle(color: Colors.pink),
                        ),
                        Text(
                          "缓冲进度:" + _controller.value.playable.toString(),
                          style: TextStyle(color: Colors.pink),
                        ),
                        Text(
                          "总时长:" + _controller.value.duration.toString(),
                          style: TextStyle(color: Colors.pink),
                        ),
                        FlatButton(
                            onPressed: () {
                              _controller.seekTo(Duration(seconds: 5));
                            },
                            child: Text(
                              'seekTo 00:00:05',
                              style: TextStyle(color: Colors.blue),
                            )),
                        Row(
                          children: <Widget>[
                            FlatButton(
                                onPressed: () {
                                  _controller.setRate(1.0);
                                },
                                child: Text(
                                  'setRate 1.0',
                                  style: TextStyle(
                                      color: _controller.value.rate == 1.0
                                          ? Colors.red
                                          : Colors.blue),
                                )),
                            FlatButton(
                                onPressed: () {
                                  _controller.setRate(1.5);
                                },
                                child: Text(
                                  'setRate 1.5',
                                  style: TextStyle(
                                      color: _controller.value.rate == 1.5
                                          ? Colors.red
                                          : Colors.blue),
                                )),
                            FlatButton(
                                onPressed: () {
                                  _controller.setRate(2.0);
                                },
                                child: Text(
                                  'setRate 2.0',
                                  style: TextStyle(
                                      color: _controller.value.rate == 2.0
                                          ? Colors.red
                                          : Colors.blue),
                                )),
                          ],
                        ),
                        Row(
                          children: <Widget>[
                            FlatButton(
                                onPressed: () {
                                  _controller =
                                      TencentPlayerController.network(mu);
                                  _controller.initialize().then((_) {
                                    setState(() {});
                                  });
                                  //  _controller.addListener(listener);
                                },
                                child: Text(
                                  'm3u8点播',
                                  style: TextStyle(
                                      color:
                                          _controller.dataSource == videoUrlAAA
                                              ? Colors.red
                                              : Colors.blue),
                                )),
                            FlatButton(
                              onPressed: () {
                                _controller =
                                    TencentPlayerController.network(spe1);
                                _controller.initialize().then((_) {
                                  setState(() {});
                                });
                                // _controller.addListener(listener);
                              },
                              child: Text(
                                '普通点播',
                                style: TextStyle(
                                    color: _controller.dataSource == videoUrlBBB
                                        ? Colors.red
                                        : Colors.blue),
                              ),
                            ),
                          ],
                        ),
                        Row(
                          children: <Widget>[
                            Container(
                              margin: EdgeInsets.only(left: 15),
                              child: Text(
                                'm3u8点播 : ',
                                style: TextStyle(color: Colors.orange),
                              ),
                            ),
                            FlatButton(
                              child: Text(
                                '标',
                                style: TextStyle(
                                    color: _controller.value.bitrateIndex == 0
                                        ? Colors.yellow
                                        : Colors.green),
                              ),
                              onPressed: () {
                                _controller.setBitrateIndex(0);
                              },
                            ),
                            FlatButton(
                              child: Text(
                                '高',
                                style: TextStyle(
                                    color: _controller.value.bitrateIndex == 1
                                        ? Colors.yellow
                                        : Colors.green),
                              ),
                              onPressed: () {
                                _controller.setBitrateIndex(1);
                              },
                            ),
                            FlatButton(
                              child: Text(
                                '超',
                                style: TextStyle(
                                    color: _controller.value.bitrateIndex == 2
                                        ? Colors.yellow
                                        : Colors.green),
                              ),
                              onPressed: () {
                                _controller.setBitrateIndex(2);
                              },
                            ),
                          ],
                        ),
                        Row(
                          children: <Widget>[
                            Container(
                              margin: EdgeInsets.only(left: 15),
                              child: Text(
                                '普通点播 : ',
                                style: TextStyle(color: Colors.orange),
                              ),
                            ),
                            FlatButton(
                                onPressed: () {
                                  _controller = TencentPlayerController.network(
                                      spe1,
                                      playerConfig: PlayerConfig(
                                          startTime: _controller
                                              .value.position.inSeconds));
                                  _controller.initialize().then((_) {
                                    setState(() {});
                                  });
                                  //   _controller.addListener(listener);
                                },
                                child: Text(
                                  '标',
                                  style: TextStyle(
                                      color: _controller.dataSource == videoUrlB
                                          ? Colors.red
                                          : Colors.blue),
                                )),
                            FlatButton(
                                onPressed: () {
                                  _controller = TencentPlayerController.network(
                                      spe2,
                                      playerConfig: PlayerConfig(
                                          startTime: _controller
                                              .value.position.inSeconds));
                                  _controller.initialize().then((_) {
                                    setState(() {});
                                  });
                                  //    _controller.addListener(listener);
                                },
                                child: Text(
                                  '高',
                                  style: TextStyle(
                                      color: _controller.dataSource == videoUrlG
                                          ? Colors.red
                                          : Colors.blue),
                                )),
                            FlatButton(
                              onPressed: () {
                                _controller = TencentPlayerController.network(
                                    spe3,
                                    playerConfig: PlayerConfig(
                                        startTime: _controller
                                            .value.position.inSeconds));
                                _controller.initialize().then((_) {
                                  setState(() {});
                                });
                                //  _controller.addListener(listener);
                              },
                              child: Text(
                                '超',
                                style: TextStyle(
                                    color: _controller.dataSource == videoUrl
                                        ? Colors.red
                                        : Colors.blue),
                              ),
                            ),
                          ],
                        ),
                        Row(
                          children: <Widget>[
                            FlatButton(
                              onPressed: () {
                                _downloadController.dowload(
                                    "4564972819220421305",
                                    quanlity: 2);
                              },
                              child: Text(
                                'download1',
                                style: TextStyle(color: Colors.blue),
                              ),
                            ),
                            FlatButton(
                              onPressed: () {
                                _downloadController
                                    .pauseDownload("4564972819220421305");
                              },
                              child: Text(
                                'download1 - stop',
                                style: TextStyle(color: Colors.blue),
                              ),
                            ),
                          ],
                        ),
                        Row(
                          children: <Widget>[
                            FlatButton(
                              onPressed: () {
                                _downloadController.dowload(testDownload);
                              },
                              child: Text(
                                'download2',
                                style: TextStyle(color: Colors.blue),
                              ),
                            ),
                            FlatButton(
                              onPressed: () {
                                _downloadController.pauseDownload(testDownload);
                              },
                              child: Text(
                                'download2 - stop',
                                style: TextStyle(color: Colors.blue),
                              ),
                            ),
                          ],
                        ),
                        Text(_downloadController.value != null
                            ? _downloadController.value.toString()
                            : '')
                      ],
                    ),
                  )
                ],
              ),
            ),
            floatingActionButton: FloatingActionButton(
              onPressed: () {
                setState(() {
                  _controller.value.isPlaying
                      ? _controller.pause()
                      : _controller.play();
                });
              },
              child: Icon(
                _controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
              ),
            ),
          );
        },
      ),
    );
  }
}

Use this package as a library

1. Depend on it

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


dependencies:
  flutter_tencentplayer_plus: ^0.1.0

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:flutter_tencentplayer_plus/flutter_tencentplayer_plus.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
37
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
69
Learn more about scoring.

We analyzed this package on Apr 4, 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

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.1.0 <3.0.0
flutter 0.0.0
Transitive dependencies
collection 1.14.11 1.14.12
meta 1.1.8
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8
Dev dependencies
flutter_test