flutter视频播放插件chewie的使用

# 因为使用flutter_html已经包含以下插件了
  flutter_html: 1.0.2
# Plugins for rendering the <video> tag.
  video_player: ^0.10.11+2
  chewie: ^0.9.10
  • 预览(半屏截图)

rTgJv4.gif

  • 主要代码 (aspectRatio视频比例很重要)

import 'package:flutter/material.dart';
import 'package:flutter_tk/common.dart';
import 'package:logger/logger.dart';
import 'package:video_player/video_player.dart';
import 'package:chewie/chewie.dart';
import 'package:flutter_tk/widgets/Dialog.dart';

/// 视频播放组件
class VideoWidFull extends StatefulWidget {
  /// 视频地址
  final String url;
  // 外部缩略图
  final String thumbUse;

  /// 点击播放的事件
  final Function onplayFunction;

  /// 视频比例
  final double aspectRatio;
  final bool autoPlay;

  /// 是否弹窗播放
  final bool useModel;
  final bool looping;
  final bool showControls;
  const VideoWidFull(
    this.url, {
    Key key,
    this.onplayFunction,
    this.thumbUse,
    this.aspectRatio = 19 / 8,
    this.useModel = false,
    this.looping = false,
    this.autoPlay = false,
    this.showControls = true,
  }) : super(key: key);
  @override
  _VideoWidFullState createState() => _VideoWidFullState();
}

class _VideoWidFullState extends State<VideoWidFull> {
  /// 播放组件
  Widget playerWidget;
  ChewieController chewieController;
  VideoPlayerController videoPlayerController;
  @override
  void initState() {
    initData();
  }

  @override
  void dispose() {
    super.dispose();
    videoPlayerController?.pause();
    chewieController?.pause();
    chewieController?.dispose();
    videoPlayerController?.dispose();
  }

  Future initData() async {
    videoPlayerController = VideoPlayerController.network('${widget.url}');
    await videoPlayerController.initialize();
    chewieController = ChewieController(
      videoPlayerController: videoPlayerController,
      autoPlay: widget.autoPlay,
      looping: widget.looping,
      aspectRatio: widget.aspectRatio == null ? 18 / 9 : 9 / 18,
      showControls: widget.showControls,
    );
    playerWidget = Chewie(
      controller: chewieController,
    );
    if (mounted) {
      setState(() {});
    }
    if (widget.autoPlay && widget?.onplayFunction != null) {
      widget.onplayFunction();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        child: playerWidget == null
            ? Container()
            : Container(
                child: Stack(
                  children: [
                    videoPlayerController.value.isPlaying
                        ? playerWidget
                        : (widget?.thumbUse != null
                            ? Positioned(
                                child: Image(
                                width: double.infinity,
                                height: double.infinity,
                                image: NetworkImage(
                                  widget.thumbUse,
                                ),
                                fit: BoxFit.fill,
                              ))
                            : playerWidget),
                    if (videoPlayerController.value.isPlaying == false)
                      GestureDetector(
                        behavior: HitTestBehavior.translucent,
                        onTap: () {
                          widget.onplayFunction();
                          if (widget.useModel) {
                            Logger().d('弹窗播放');
                            // 弹窗播放
                            screenDialogWid(
                              context: context,
                              child: Container(
                                  child: VideoWidFull(
                                '${widget.url}',
                                autoPlay: true,
                                useModel: false,
                                aspectRatio: widget.aspectRatio,
                              )),
                              url: widget.url,
                              close: () {},
                            );
                          } else {
                            Logger().d('直接播放');
                            // 直接播放
                            chewieController?.play();
                            setState(() {});
                          }
                        },
                        child: Container(
                          child: Center(
                            child: Container(
                              width: Common.width(120),
                              height: Common.width(120),
                              decoration: BoxDecoration(
                                color: Color.fromRGBO(0, 0, 0, 0.3),
                                borderRadius: BorderRadius.all(
                                    Radius.circular(Common.width(120))),
                              ),
                              child: Center(
                                child: Image.asset(
                                  'asset/images/res/play_48x48.png',
                                  width: Common.width(48),
                                  height: Common.width(48),
                                  fit: BoxFit.contain,
                                ),
                              ),
                            ),
                          ),
                        ),
                      )
                  ],
                ),
              ));
  }
}
  • 全屏弹窗组件 (核心是showGeneralDialog)

import 'package:flutter/material.dart';
import 'package:flutter_custom_dialog/flutter_custom_dialog.dart';
import 'package:flutter_tk/common.dart';
import 'package:flutter_tk/lib/download.dart';
import 'package:flutter_tk/widgets/GestureDetectorWid.dart';
import 'package:flutter_tk/widgets/PageLayout.dart';
import 'package:logger/logger.dart';

typedef void HandleClose();

Future<void> screenDialogWid<T>(
    {BuildContext context,
    Widget child,
    String url,
    HandleClose close,
    Function fullScreen,

    /// 是否是横屏
    bool isHoScreen: false}) async {
  await showGeneralDialog(
    context: context,
    barrierLabel: "",
    barrierDismissible: true,
    transitionDuration: Duration(milliseconds: 300),
    pageBuilder: (BuildContext context, Animation<double> animation,
        Animation<double> secondaryAnimation) {
      return Material(
        color: Colors.black,
        child: GestureDetectorWid(
          onTap: () async {
            if (close != null) {
              close();
            }
            Common.toJumpPage(context: context);
          },
          child: Stack(
            children: [
              Positioned(
                left: 0,
                right: 0,
                bottom: Common.width(120),
                top: 0,
                child: Center(
                  child: child,
                ),
              ),
              Positioned(
                right: Common.width(40),
                bottom: Common.width(40),
                child: GestureDetectorWid(
                  child: Image.asset(
                    'asset/images/res/download_64x64.png',
                    width: Common.width(64),
                    height: Common.width(64),
                  ),
                  onTap: () async {
                    await Download.download(
                      [url],
                      onDone: (String text) {
                        Common.toast(text);
                      },
                      onError: (String text) {
                        Common.toast(text);
                      },
                      onReceiveProgress: (String text) {
                        Common.loading(
                          msg: text,
                          context: context,
                        );
                      },
                    );
                  },
                ),
              ),
            ],
          ),
        ),
      );
    },
  );
}