Flutter 视频播放

作者: iwakevin | 来源:发表于2018-12-13 13:51 被阅读547次

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

    先安装依赖:

    dependencies:
      video_player: ^0.6.4
    

    基本使用

    class _VideoAppState extends State<VideoApp> {
        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,
                        ),
                    ),
                ),
            );
        }
    }
    

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


    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,
            ),
        ),
    ),
    

    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,
    ),
    

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

    // 在 build 里加一个 _buildHeader(),这个 header 需要自己定义。
    @override
    Widget build(BuildContext context) {
        return new Column(
            children: <Widget>[
                // 在全屏时才显示
                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: <Widget>[
                        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 视频播放

        本文链接:https://www.haomeiwen.com/subject/jmnvhqtx.html