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;// 初始化@overridevoid initState() {super.initState();// 加载网络视频_controller = VideoPlayerController.networkUrl(Uri.parse('https://www.tujuyun.com/pixabay/video/VideoBig/1024927/4006.mp4'))..initialize().then((_) {setState(() {});});}@overridevoid dispose() {super.dispose();_controller.dispose();}@overrideWidget 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;@overrideState<MyHomePage> createState() => _MyHomePageState();
}class _MyHomePageState extends State<MyHomePage> {// 控制器late VideoPlayerController _controller;late ChewieController _chewieController;late PersistentBottomSheetController<dynamic> _bottomSheetController;// 初始化@overridevoid 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(),),],),);});},);});}@overridevoid dispose() {super.dispose();_controller.dispose();_chewieController.dispose();}@overrideWidget 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
}
其他功能略,可以自行查看官方文档
相关文章:
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…...
vim的使用
vim文本编辑器 vim介绍命令模式光标移动选中内容复制内容粘贴内容删除撤销/恢复字符转换 编辑模式末行模式保存/退出查找行号显示文件切换 扩展 vim介绍 vim是Linux自带的文本编辑器,具有命令模式、编辑模式、末行模式三种模式。 模式间的切换: 命令模…...
马氏杆法检查斜视
使用 检查水平向斜视时,使用水平向马氏杆检查;重直向斜视时,使用重直问马氏杆;检查旋转斜视时,使用双马氏杆. 检查水平向斜视 双眼屈光不正全矫 双眼同时打开,右眼前加水平向马氏杆,左眼前不加 双眼同时观察点光源&…...
Mac电脑怎么使用“磁盘工具”修复磁盘
我们可以使用“磁盘工具”的“急救”功能来查找和修复磁盘错误。 “磁盘工具”可以查找和修复与 Mac 磁盘的格式及目录结构有关的错误。使用 Mac 时,错误可能会导致意外行为,而重大错误甚至可能会导致 Mac 彻底无法启动。 继续之前,请确保您…...
c++画出分割图像,水平线和垂直线
1、pca 找到图像某个区域的垂直线,并画出来 // 1、 斑块的框 血管二值化图,pca 找到垂直血管壁的直线, 还是根据斑块找主轴方向吧// Step 1: 提取斑块左右范围内的血管像素点坐标,std::vector<cv::Point> points;for (int y 0; y <…...
Python 程序设计入门(015)—— enumerate() 函数的用法
Python 程序设计入门(015)—— enumerate() 函数的用法 目录 Python 程序设计入门(015)—— enumerate() 函数的用法一、enumerate() 函数的语法二、为可迭代对象创建索引三、将字符串、列表等转换为字典1、将字符串转换为字典2、…...
__dict__属性
__dict__ 是 Python 中的一个特殊属性,通常存在于大多数 Python 对象中,用于存储该对象的可变属性。 以下是关于 __dict__ 的一些关键点和详细信息: 存储属性:对于大多数自定义的 Python 对象,__dict__ 属性包含了这个…...
k8s之Pod控制器
目录 一、Pod控制器及其功用二、pod控制器的多种类型2.1 pod容器中的有状态和无状态的区别 三、Deployment 控制器四、SatefulSet 控制器4.1 StatefulSet由以下几个部分组成4.2 为什么要有headless?4.3 为什么要有volumeClaimTemplate?4.4 滚动更新4.5 扩…...
逆元(求乘法逆元的几种方法)
目录 逆元 加法逆元 乘法逆元 如何求 快速幂 扩展欧几里得 O(n)求1到n的乘法逆元 逆元 数学中,逆元素(英语:Inverse element)推广了加法中的加法逆元和乘法中的倒数。直观地说,它是一个可以取消另一给定元素运…...
没点本事,还真做不好数字化转型
数字化转型逐渐成为企业业务增长的利器 然而,在此过程中 企业最应该注重哪些? 效率?质量? 但还有一个至关重要的点不容忽视 那就是安全 有一家硬核企业通过技术与狠活 硬生生提升了应用安全性 保障了产业与数字化的安全融合…...
windows 10 远程桌面配置
1. 修改远程桌面端口(3389) 打开注册表(winr), 输入regedit 找到配置项【计算机\HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Terminal Server\Wds\rdpwd\Tds\tcp】 , 可以通过搜索“Wds”快速定位。 修改端口配…...
OpenStreetMap 上基于A*搜索算法的C ++路线规划项目
引言 在现代的地理信息系统(GIS)中,路线规划是一个重要的组成部分。它涉及到从一个地点到另一个地点的最优路径的确定。在这篇文章中,我们将探讨如何在OpenStreetMap数据上实现一个基于A*搜索算法的C路线规划项目。 OpenStreetM…...
java实现随机生成验证码
import java.util.concurrent.ThreadLocalRandom;/* 生成验证码的工具 可动态配置验证码长度*/ public class CodeUtils {public static void main(String[] args) {//随机生成5个长度为4的验证码for (int i 0; i < 5; i) {System.out.println(CodeUtils.getCode(4));}for …...
Positive证书是什么?
Positive SSL是全球著名CA Sectigo的子品牌, 也是目前全球签发量最高的商业SSL证书。价格低,安全性高,在个人网站和中小型企业网站中拥有极高的占有率。 Positive SSL证书包括DV SSL, EV SSL,也是唯一支持IP地址加密的…...
vulnhub靶场-y0usef笔记
vulnhub靶场-y0usef笔记 信息收集 首先fscan找到目标机器ip http://192.168.167.70/ nmap扫描端口 Host is up (0.00029s latency). Not shown: 998 closed tcp ports (reset) PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.13 (Ub…...
华为智选首款纯电轿跑“LUXEED”能大卖吗?
监制 | 何玺 排版 | 叶媛 华为智选纯电轿跑来袭! 8月7日,华为常务董事余承东在社交媒体上发文,宣布华为智选即将推出首款“突破想象”的纯电轿跑车。 01 华为智选首款纯电轿跑来袭 余承东的发文引起了极大关注,在各大媒体的报…...
ArcGIS API for JavaScript 3.44 地图Demo示例合集
ArcGIS API for JavaScript 3.44 demo合集 (一)创建地图(二)基准图库(三)编辑书签(四)主页按钮(五)LayerList小部件(六)测量小工具&am…...
RFID工业识别技术:供应链智能化的科技颠覆
RFID工业识别技术,作为物联网的先锋,正在供应链管理领域展现着前所未有的科技颠覆。从物料追踪到库存管理,再到物流配送,RFID技术以其高效的数据采集和智能的自动化处理,彻底改变着传统供应链的运营方式。 RFID在物料追…...
行列转换两例的思考
1、多行转成一列 (1)、建测试表及插入测试数据 create table t(i int,a varchar2(1)); insert into t(i,a) select 1,a from dual union all select 1,b from dual union all select 1,d from dual union all select 1,e from dual union all select 2,z from dual union all…...
高德地图 SDK 接口测试接入(AndroidTest 上手)
学习资料 官方文档 在 Android 平台上测试应用 | Android 开发者 | Android Developers 测试了解 【玩转Test】开篇-Android test 介绍 Android单元测试全解_android 单元测试_一代小强的博客-CSDN博客 Android单元测试-对Activity的测试_activitytestrule_许佳佳233的博客…...
XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
