Flutter 视频播放

在 Flutter 里官方提供了一个 video_player插件可以播放视频。

先安装依赖:

dependencies:
  video_player: ^0.6.4

基本使用

class _VideoAppState extends State {
    VideoPlayerController _controller;
    bool _isPlaying = false;
    String url = 'http://vd3.bdstatic.com/mda-ifvq' +
                'u9yp3eaqueep/mda-ifvqu9yp3eaqueep.mp4';

    @override
    void initState() {
        super.initState();
        _controller = VideoPlayerController.network(this.url)
        // 播放状态
        ..addListener(() {
            final bool isPlaying = _controller.value.isPlaying;
            if (isPlaying != _isPlaying) {
                setState(() { _isPlaying = isPlaying; });
            }
        })
        // 在初始化完成后必须更新界面
        ..initialize().then((_) {
            setState(() {});
        });
    }

    @override
    Widget build(BuildContext context) {
        return MaterialApp(
            title: 'Video Demo',
            home: new Scaffold(
                body: new Center(
                child: _controller.value.initialized
                    // 加载成功
                    ? new AspectRatio(
                        aspectRatio: _controller.value.aspectRatio,
                        child: VideoPlayer(_controller),
                    ) : new Container(),
                ),
                floatingActionButton: new FloatingActionButton(
                    onPressed: _controller.value.isPlaying
                        ? _controller.pause
                        : _controller.play,
                    child: new Icon(
                        _controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
                    ),
                ),
            ),
        );
    }
}

下面是在模拟器下看到的效果(略卡)。


Flutter 视频播放_第1张图片

video_player 的 controller 有以下方法可用:

  • initialize() - 初始化播放器。
  • dispose() - 释放播放器资源。
  • notifyListeners() - 监听播放消息。
  • addListener(listener) - 添加监听器。
  • removeListener(listener) - 移除监听器。
  • pause() - 暂停播放。
  • play() - 开始播放。
  • position - 播放位置。
  • seekTo(moment) - 指定到某个位置播放。
  • setLooping(looping) - 是否循环播放。
  • setVolume(volume) - 设置音量大小。

使用 chewie

chewie,是一个非官方的第三方视频播放组件,看起来好像是基于 HTML5 播放的组件。chewie 相对 video_player 来说,有控制栏和全屏的功能。Chewie 使用 video_player 引擎并将其包裹在友好的 Material 或 Cupertino UI 中!
安装依赖:

dependencies
  chewie: ^0.6.1

基本使用:

import 'package:chewie/chewie.dart';

new Center(
    child: new Chewie(
        new VideoPlayerController.network(this.url),
        aspectRatio: 16 / 9,
        autoPlay: !true,
        looping: true,
        showControls: true,
        // 占位图
        placeholder: new Container(
            color: Colors.grey,
        ),

        // 是否在 UI 构建的时候就加载视频
        autoInitialize: !true,

        // 拖动条样式颜色
        materialProgressColors: new ChewieProgressColors(
            playedColor: Colors.red,
            handleColor: Colors.blue,
            backgroundColor: Colors.grey,
            bufferedColor: Colors.lightGreen,
        ),
    ),
),

Flutter 视频播放_第2张图片

chewie 实际上就是为 video_player 做了一个 UI 上的封装,因为 UI 实在长得太像。

控制栏样式?

chewie 并不能自定义控制栏样式,那只能自己修改源码了(修改的版本是 v0.6.1)。

首先打开文件:chewie/lib/src/material_controls.dart,在里面定义两个变量。

const lightColor = Color.fromRGBO(255, 255, 255, 0.85);
const darkColor = Color.fromRGBO(1, 1, 1, 0.35);
接着添加颜色值。

// 在 _buildExpandButton 下,大约 127 行
child: new Icon(
    widget.fullScreen ? Icons.fullscreen_exit : Icons.fullscreen,
    color: lightColor,
),

// 在 _buildHitArea 下,大约 157 行
decoration: new BoxDecoration(
    color: Colors.black54,
    borderRadius: new BorderRadius.circular(48.0),
),
// 167 行
child: new Icon(
    Icons.play_arrow,
    size: 32.0,
    color: lightColor,
),

// 在 _buildMuteButton 下,大约 206 行
child: new Icon(
    color: lightColor,
),

// 在 _buildPlayPause 下,大约 228 行
child: new Icon(
    controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
    color: lightColor,
),

// 在 _buildPosition 下,大约 244 行
style: new TextStyle(
    fontSize: 14.0,
    color: lightColor,
),

// 在 _buildProgressBar 下,尾行
new ChewieProgressColors(
    playedColor: lightColor,
    handleColor: lightColor,
    bufferedColor: Colors.white30,
    backgroundColor: darkColor,
),
Flutter 视频播放_第3张图片

此外 chewie 在全屏时没有一个退出全屏的返回按钮和标题显示,接着改。

// 在 build 里加一个 _buildHeader(),这个 header 需要自己定义。
@override
Widget build(BuildContext context) {
    return new Column(
        children: [
            // 在全屏时才显示
            widget.fullScreen ? _buildHeader(context, _title) : new Container(),
            _buildHitArea(),
            _buildBottomBar(context, widget.controller),
        ],
    );
}

AnimatedOpacity _buildHeader(BuildContext context, String title) {
    return new AnimatedOpacity(
        opacity: _hideStuff ? 0.0 : 1.0,
        duration: new Duration(milliseconds: 300),
        child: new Container(
            color: darkColor,
            height: barHeight,
            child: new Row(
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                    new IconButton(
                        onPressed: _onExpandCollapse,
                        color: lightColor,
                        icon: new Icon(Icons.chevron_left),
                    ),
                    new Text(
                        '$title',
                        style: new TextStyle(
                            color: lightColor,
                            fontSize: 18.0,
                        ),
                    ),
                ],
            ),
        ),
    );
}

标题是从上下文获取的,因此要一级一级的传递下去。

// chewie/lib/src/chewie_player.dart 文件

// 标题
final String title;

// 在构造函数处
this.title = '',

// 在 92 行左右,PlayerWithControls 构造的时候(有两个位置,两个都要加)
title: widget.title,

// chewie/lib/src/player_with_controls.dart 文件

// 标题
final String title;

// 在构造函数处
this.title = '',

// 在 92 行左右,MaterialControls 构造的时候
title: widget.title,

// chewie/lib/src/material_controls.dart
final String title;
@required this.title,
Flutter 视频播放_第4张图片

你可能感兴趣的:(Flutter 视频播放)