Flutter:文件读取—— video_player、chewie、image_picker、file_picker

前言

简单学习一下几个比较好用的文件读取库

video_player

简介
用于视频播放

官方文档
https://pub-web.flutter-io.cn/packages/video_player

安装

flutter pub add video_player

加载网络视频

class _MyHomePageState extends State<MyHomePage> {
  // 控制器
  late VideoPlayerController _controller;

  // 初始化
  @override
  void initState() {
    super.initState();
    // 加载网络视频
    _controller = VideoPlayerController.networkUrl(
        Uri.parse('https://www.tujuyun.com/pixabay/video/VideoBig/1024927/4006.mp4'))
      ..initialize().then((_) {
        setState(() {});
      });
  }

  @override
  void dispose() {
    super.dispose();
    _controller.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: _controller.value.isInitialized // 判断是否已经加载完成
            ? AspectRatio(
                // 设置视频播放的宽高比
                aspectRatio: _controller.value.aspectRatio,
                child: VideoPlayer(_controller),
              )
            : Container(),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            _controller.value.isPlaying // 判断是否是在播放中
                ? _controller.pause() //暂停
                : _controller.play(); // 播放
          });
        },
        child: Icon(
          _controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
        ),
      ),
    );
  }
}

在这里插入图片描述
加载本地视频

   _controller = VideoPlayerController.asset('lib/assets/video/3998.mp4')
      ..initialize().then((_) {
        setState(() {});
      });

设置倍速和进度条

Center(
   child: _controller.value.isInitialized // 判断是否已经加载完成
       ? AspectRatio(
           // 设置视频播放的宽高比
           aspectRatio: _controller.value.aspectRatio,
           child: Stack(
             alignment: Alignment.bottomCenter,
             children: <Widget>[
               // 视频播放器
               VideoPlayer(_controller),
               // 设置倍速
               Row(
                 children: [
                   ElevatedButton(
                       onPressed: () {
                         _controller.setPlaybackSpeed(1);
                       },
                       child: const Text("1倍速")),
                   ElevatedButton(
                       onPressed: () {
                         _controller.setPlaybackSpeed(5);
                       },
                       child: const Text("5倍速"))
                 ],
               ),
               // 视频的进度条
               VideoProgressIndicator(_controller, allowScrubbing: true),
             ],
           ),
         )
       : Container(),
 )

在这里插入图片描述

chewie

video_player虽然是官方提供的插件,但是很明显它只适合拿来简单的播放视频,就比如前端的video标签功能也很少。在这里推荐一下chewie

简介

chewie是基于video_player实现的,它额外提供了很多功能,比如:倍速、进度条、全屏以及其他的功能

官方文档
https://pub-web.flutter-io.cn/packages/chewie

安装

flutter pub add chewie

默认的弹出菜单是这样的
在这里插入图片描述

可以通过设置optionsBuilder来进行自定义显示

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  // 控制器
  late VideoPlayerController _controller;
  late ChewieController _chewieController;
  late PersistentBottomSheetController<dynamic> _bottomSheetController;

  // 初始化
  @override
  void initState() {
    super.initState();
    // 加载网络视频
    _controller = VideoPlayerController.networkUrl(Uri.parse(
        'https://www.tujuyun.com/pixabay/video/VideoBig/1024927/4006.mp4'))
      ..initialize().then((_) {
        setState(() {});
        _chewieController = ChewieController(
          videoPlayerController: _controller,
          autoPlay: true,
          looping: true,
          optionsBuilder: (context, defaultOptions) async {
            // 这里面现在是只有一个设置倍速的,我们把它拿出来
            // for (int i = 0; i < defaultOptions.length; i++) {
            //   print("默认选项:${defaultOptions[i]}");
            // }
            // await showDialog<void>(
            //   context: context,
            //   builder: (ctx) {
            //     // return AlertDialog(
            //     //   content: ListView.builder(
            //     //     itemCount: defaultOptions.length,
            //     //     itemBuilder: (_, i) => ActionChip(
            //     //       label: Text(defaultOptions[i].title),
            //     //       onPressed: () => defaultOptions[i].onTap!(),
            //     //     ),
            //     //   ),
            //     // );
            //   },
            // );
            _bottomSheetController =
                Scaffold.of(context).showBottomSheet((BuildContext context) {
              return SizedBox(
                height: 200,
                child: ListView(
                  children: <Widget>[
                    ListTile(
                      leading: const Icon(Icons.speed),
                      title: const Text('倍速'),
                      onTap: () => defaultOptions[0].onTap!(),
                    ),
                    const Divider(
                      color: Colors.grey,
                      thickness: 1.0,
                    ),
                    ListTile(
                      leading: const Icon(Icons.download),
                      title: const Text('下载'),
                      onTap: () => print("下载中.."),
                    ),
                    const Divider(
                      color: Colors.grey,
                      thickness: 1.0,
                    ),
                    ListTile(
                      leading: const Icon(Icons.close),
                      title: const Text('关闭'),
                      onTap: () => _bottomSheetController.close(),
                    ),
                  ],
                ),
              );
            });
          },
        );
      });
  }

  @override
  void dispose() {
    super.dispose();
    _controller.dispose();
    _chewieController.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: _controller.value.isInitialized // 判断是否已经加载完成
            ? AspectRatio(
                // 设置视频播放的宽高比
                aspectRatio: _controller.value.aspectRatio,
                child: Chewie(
                  controller: _chewieController,
                ),
              )
            : Container(),
      ),
    );
  }
}

在这里插入图片描述

注: chewie 还有很多其他高级功能,比如自定义UI界面、设置弹幕等。需要好好看一下官方文档,才能实现高级功能,不过上面那个例子已经可以满足基本的使用了。

image_picker

简介
用于从相册中挑选图片、视频、使用相机拍摄照片。

官方文档
https://pub-web.flutter-io.cn/packages/image_picker

安装

flutter pub add image_picker

示例:读取单张图片

class _MyHomePageState extends State<MyHomePage> {
  // 图片文件
  File? _image;
  // 错误信息
  String _error = '';

  // 图片选择函数
  Future<void> _pickImage() async {
    // 从相册中选择图片
    try {
      final pickedImage =
          await ImagePicker().pickImage(source: ImageSource.gallery);
      if (pickedImage != null) {
        setState(() {
          _image = File(pickedImage.path);
        });
      }
    } catch (e) {
      setState(() {
        _error = e.toString();
      });
    }
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            // 图片存在则显示
            if (_image != null)
              Image.file(
                _image!,
                width: 200,
                height: 200,
              ),
            // 如果错误信息存在
            if (_error.isNotEmpty) Text("错误:$_error"),
            const SizedBox(
              height: 20,
            ),
            ElevatedButton(onPressed: _pickImage, child: const Text("从相册里选取图片"))
          ],
        ),
      ),
    );
  }
}

在这里插入图片描述
看了一下好像不能设置选择的图片格式,只能设置大小、质量
在这里插入图片描述
如果设置为ImagePicker().pickImage(source: ImageSource.camera) ,这是调用摄像头来进行获取图片

示例:读取多张图片

class _MyHomePageState extends State<MyHomePage> {
  // 图片文件列表
  final List<File> _pickedFileList = [];
  // 错误信息
  String _error = '';

  // 图片选择函数
  Future<void> _pickImage() async {
    // 从相册中选择图片
    try {
      final pickedImageList = await ImagePicker().pickMultiImage();
      if (pickedImageList.isNotEmpty) {
        for (XFile image in pickedImageList) {
          _pickedFileList.add(File(image.path));
        }
        setState(() {});
      }
    } catch (e) {
      setState(() {
        _error = e.toString();
      });
    }
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Expanded(
                child: ListView.builder(
                    itemCount: _pickedFileList.length,
                    itemBuilder: (context, index) {
                      return Image.file(
                        _pickedFileList[index],
                        width: 200,
                        height: 200,
                      );
                    })),
            // 如果错误信息存在
            if (_error.isNotEmpty) Text("错误:$_error"),
            const SizedBox(
              height: 20,
            ),
            ElevatedButton(onPressed: _pickImage, child: const Text("从相册里选取图片"))
          ],
        ),
      ),
    );
  }
}

要长按图片,才能够一次选择多个,最后在点击右上角的选择。轻触会直接选中图片。另外看了下pickMultiImage里的入参好像不支持限制图片的个数
在这里插入图片描述

示例:选择单个视频

选择视频稍微复杂一点,还需要借助video_player等插件才能更进行预览。

class _MyHomePageState extends State<MyHomePage> {
  // 错误信息
  String _error = '';
  // 视频信息
  late File _video;
  // 视频播放器
  VideoPlayerController? _videoPlayerController;
  Future<void>? _videoPlayerInitializer;

  // 选择视频
  Future<void> _pickVideo() async {
    // 从相册中选择视频
    try {
      final pickedVideo =
          await ImagePicker().pickVideo(source: ImageSource.gallery);
      if (pickedVideo != null) {
        setState(() {
          _video = File(pickedVideo.path);
          _videoPlayerController = VideoPlayerController.file(_video);
          _videoPlayerInitializer = _videoPlayerController!.initialize();
           // 播放视频
          _videoPlayerController!.play();
        });
      }
    } catch (e) {
      setState(() {
        _error = e.toString();
      });
    }
  }

  
  void dispose() {
    _videoPlayerController?.dispose();
    super.dispose();
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            if (_videoPlayerController != null)
              FutureBuilder(
                future: _videoPlayerInitializer,
                builder: (BuildContext context, AsyncSnapshot<void> snapshot) {
                  if (snapshot.connectionState == ConnectionState.done) {
                    return SizedBox(
                      width: 300,
                      height: 200,
                      child: AspectRatio(
                        aspectRatio:1.5,
                        child: VideoPlayer(_videoPlayerController!),
                      ),
                    );
                  } else {
                    return const CircularProgressIndicator();
                  }
                },
              ),
            // 如果错误信息存在
            if (_error.isNotEmpty) Text("错误:$_error"),
            const SizedBox(
              height: 20,
            ),
            ElevatedButton(onPressed: _pickVideo, child: const Text("从相册里选取视频"))
          ],
        ),
      ),
    );
  }
}

在这里插入图片描述

file_picker

简介
一个包,允许您使用本机文件资源管理器来选择单个或多个文件,具有扩展筛选支持。

官方文档
https://pub-web.flutter-io.cn/packages/file_picker

安装

flutter pub add file_picker

示例:选择单个文件

class _MyHomePageState extends State<MyHomePage> {
  // 错误信息
  String _error = '';
  // 文件路径
  String _filePath = '';

  // 选择文件
  Future _pickFile() async {
    try {
      FilePickerResult? result = await FilePicker.platform.pickFiles(
          dialogTitle: "选择图片",
          type: FileType.image, // 设置文件的类型
          );
      if (result != null) {
        setState(() {
          _filePath = result.files.single.path!;
        });
      }
    } catch (e) {
      setState(() {
        _error = e.toString();
      });
    }
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            // File 是 io包下的
            _filePath == '' ? const Text("未选择文件") : Image.file(File(_filePath)),
            // 如果错误信息存在
            if (_error.isNotEmpty) Text("错误:$_error"),
            const SizedBox(
              height: 20,
            ),
            ElevatedButton(onPressed: _pickFile, child: const Text("选择一个图片"))
          ],
        ),
      ),
    );
  }
}

在这里插入图片描述

示例:选择多个文件

FilePickerResult? result = await FilePicker.platform.pickFiles(allowMultiple: true);

if (result != null) {
  List<File> files = result.paths.map((path) => File(path)).toList();
} else {
  // User canceled the picker
}

其他功能略,可以自行查看官方文档

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/66384.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

瑞数系列及顶像二次验证LOGS

瑞数商标局药监局专利局及顶像二次验证 日期&#xff1a;20230808 瑞数信息安全是一个专注于信息安全领域的公司&#xff0c;致力于为企业和个人提供全面的信息安全解决方案。他们的主要业务包括网络安全、数据安全、应用安全、云安全等方面的服务和产品。瑞数信息安全拥有一支…

测试经理应该怎么写测试部门年终总结报告?

年终总结一般对季度、半年度或年度总结的一个整理&#xff0c;我们需要定期对工作中的内容进行定期总结和复盘。将每一次复盘中总结出来的一些收获叠加起来&#xff0c;在针对性地调整一下&#xff0c;就是一份合格的年终总结。具体可以分为如下几个步骤&#xff1a; 1.先把这…

《Zookeeper》源码分析(五)之 ServerCnxnFactory的工作原理(上)

目录 AcceptThread数据结构构造函数run() SelectorThread数据结构processAcceptedConnections()select()processInterestOpsUpdateRequests() 本文开始分析 ServerCnxnFactory的工作原理&#xff0c;按照顺序我们这样分析&#xff1a; 建立连接监听读写事件处理读写就绪的事件…

Jenkins+Docker+SpringCloud微服务持续集成

JenkinsDockerSpringCloud微服务持续集成 JenkinsDockerSpringCloud持续集成流程说明SpringCloud微服务源码概述本地运行微服务本地部署微服务 Docker安装和Dockerfile制作微服务镜像Harbor镜像仓库安装及使用在Harbor创建用户和项目上传镜像到Harbor从Harbor下载镜像 微服务持…

Java中ArrayList常用方法的学习

Java中ArrayList常用方法的学习 需求分析代码实现小结Time 需求分析 ArrayList集合的常用方法学习 代码实现 java.util.ArrayList;/*** Author:LQ* Description:* Date:Created in 16:45 2023/8/9*/ public class ListTest {public static void main(String[] args) {ArrayLis…

QT QLCDNumber 使用详解

本文详细的介绍了QLCDNumber控件的各种操作&#xff0c;例如&#xff1a;新建界面、源文件、设置显示位数、设置进制、设置外观、设置小数点、设置溢出、显示事件、其它文章等等操作。 实际开发中&#xff0c;一个界面上可能包含十几个控件&#xff0c;手动调整它们的位置既费时…

【源码编译并安装RocketMQ Dashboard】

【源码编译并安装RocketMQ Dashboard】 一、环境说明二、源码编译并执行三、小结 一、环境说明 安装环境&#xff1a;虚拟机VMWare Centos7.6 Maven3.6.3 JDK1.8已经安装了RocketMQ-5.1.3 单Master集群&#xff0c;且使用Local模式部署&#xff0c;即Broker和Proxy同进程部署…

springcloud3 bus+springconfig 实现配置文件的动态刷新(了解)

一 springcloud Bus的作用 1.1 springcloud的作用 spring cloud bus是用来将分布式系统的节点与轻量级消息系统链接起来的框架。 它整合了java的事件处理机制和消息中间件的功能。其中目前支持RabbitMQ和kafka 简介&#xff1a; bus实现多个服务的配置文件动态刷新。 1.2 …

Pytorch Tutorial【Chapter 3. Simple Neural Network】

Pytorch Tutorial【Chapter 3. Simple Neural Network】 文章目录 Pytorch Tutorial【Chapter 3. Simple Neural Network】Chapter 3. Simple Neural Network3.1 Train Neural Network Procedure训练神经网络流程3.2 Build Neural Network Procedure 搭建神经网络3.3 Use Loss …

网络基本概念

目录 一、IP地址 1. 概念 2. 格式 3. 特殊IP 二、端口号 1.概念 2. 格式 3.注意事项 三、 协议 1. 概念 2. 作用 四、协议分层 1. 网络设备所在分层 五、封装与分用 六、客户端和服务器 1. 客户端与服务器通信的过程 一、IP地址 1. 概念 IP地址主要用于标识网络主机.其他网络…

linux系统虚拟主机开启支持Swoole Loader扩展

特别说明&#xff1a;只是安装支持Swoole扩展&#xff0c;主机并没有安装服务端。目前支持版本php5.4-php7.2。 1、登陆主机控制面板&#xff0c;找到【远程文件下载】这个功能。 2、远程下载文件填写http://download.myhostadmin.net/vps/SwooleLoader_linux.zip 下载保存的路…

跳表与Redis

跳表原理 跳表是Redis有序集合ZSet底层的数据结构 首先有一个头结点 这个头结点里面的数据是null 就是他就是这个链表的最小值 就算是Math.Min也比它大 然后我们新建一个节点的时候是怎么操作的呢 先根据参数(假如说是5)创建一个节点 然后把它放在对应位置 就是找到小于他的最…

web安全漏洞

1.什么是Web漏洞 WEB漏洞通常是指网站程序上的漏洞&#xff0c;可能是由于代码编写者在编写代码时考虑不周全等原因而造成的漏洞。如果网站存在WEB漏洞并被黑客攻击者利用&#xff0c;攻击者可以轻易控制整个网站&#xff0c;并可进一步提前获取网站服务器权限&#xff0c;控制…

【Winform学习笔记(五)】引用自定义控件库(dll文件)

引用自定义控件库dll文件 前言正文1、生成dll文件2、选择工具箱项3、选择需要导入的dll文件4、确定需要导入的控件5、导入及使用 前言 在本文中主要介绍 如何引用自定义控件库(dll文件)。 正文 1、生成dll文件 通过生成解决方案 或 重新生成解决方案 生成 dll 文件 生成的…

探索ES高可用:滴滴自研跨数据中心复制技术详解

Elasticsearch 是一个基于Lucene构建的开源、分布式、RESTful接口的全文搜索引擎&#xff0c;其每个字段均可被索引&#xff0c;且能够横向扩展至数以百计的服务器存储以及处理TB级的数据&#xff0c;其可以在极短的时间内存储、搜索和分析大量的数据。 滴滴ES发展至今&#xf…

element-ui 表格el-table的列内容溢出省略显示,鼠标移上显示全部和定制样式

1、在对应列加上省略显示show-overflow-tooltip属性&#xff0c;如果加上这属性&#xff0c;鼠标移上还是没效果&#xff0c;要考滤是不是层级的原因&#xff0c;被其他挡住了。 :deep(.el-tooltip){position: relative;z-index:9; } <el-table-column label"用款渠…

java静默打印PDF(可实现生产环境下服务器写入PDF模板,然后调用客户端打印机打印)

java静默打印PDF可实现生产环境下服务器写入PDF模板&#xff0c;然后调用客户端打印机打印 一、简需求实现步骤 二、代码实现0、打印模板1、服务器部分 &#xff08;端口&#xff1a;8090&#xff09;1.1、maven依赖1.2、实体1.2.1、接口返回类1.2.2、标签纸页面参数类1.2.3、P…

Spring集成Web

目录 1、简介 2、监听器 3、Spring提供的listener 3.1、xml 3.2、配置类 3.3、WebApplicationContextUtils 3.4、说明 4、自己复现的listener 4.1、ContextLoaderListener 4.2、WebApplicationContextUtils 4.3、Web调用 ⭐作者介绍&#xff1a;大二本科网络工程专业…

《Linux运维实战:Docker基础总结》

一、简介 1、docker的基本结构是什么&#xff0c;包含哪些组件&#xff1f; docker的基本机构是c/s模式&#xff0c;即客户端/服务端模式。 由docker客户端和docker守护进程组成。docker客户端通过命令行或其它工具使用docker sdk与docker守护进程通信&#xff0c;发送容器管理…

Add-in Express for Microsoft Office and Delphi Crack

Add-in Express for Microsoft Office and Delphi Crack 适用于Microsoft Office和Delphi VCL的Add-in Express使您能够在几次点击中为Microsoft Office开发专业插件。它生成基于COM的项目&#xff0c;这些项目包含Microsoft Office外接程序或智能标记的所有必要功能&#xff0…