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的博客…...
别再只删node_modules了!npm run serve报错‘There is likely additional logging output above’的完整排查与修复手册
从日志溯源到根治:npm run serve报错的系统性排查指南 当你满怀期待地敲下npm run serve,却迎面撞上那句"There is likely additional logging output above"时,是否感到一阵无力?删除node_modules重装就像重启电脑——…...
解决Redroid安卓12串流黑屏:修改SurfaceFlinger绕过Secure Flag的实战记录
解决Redroid安卓12串流黑屏:修改SurfaceFlinger绕过Secure Flag的实战记录 在RK3588开发板上运行Redroid容器时,许多开发者会遇到一个棘手问题:使用scrcpy等工具串流显示某些应用界面时,屏幕突然变黑。这并非硬件故障,…...
体验Taotoken官方折扣与Token Plan带来的实际费用节省
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 体验Taotoken官方折扣与Token Plan带来的实际费用节省 对于开发者个人或小团队而言,在项目开发或日常工作中使用大模型…...
YOLOv8无人机红外识别检测系统(项目源码+YOLO数据集+模型权重+UI界面+python+深度学习+环境配置)
摘要 面向无人机平台的红外目标检测在夜间及低能见度环境下具有重要应用价值。本文基于YOLOv8构建了一套针对车辆与行人的红外检测系统,数据集包含4类目标(Car、DontCare、OtherVehicle、Person),共计10128张训练图像、715张验证…...
盒子不同定位的解说!
目录 一、相对定位 二、绝对定位 三、固定定位 一、相对定位 【概念】:简单来说,就是让一个元素相对于它自己原本应该在的位置进行移动。 【核心特点】:1.不脱离文档流:这是相对定位最关键的特点。元素虽然移动了,…...
获 800 万美元融资,MAU 超 40 万!「shapes」AI 社交能否成下一代聊天应用?
《「shapes」获 800 万美元种子轮融资,AI 助力社交“入场”,能否成下一代聊天应用?》这几天,我在「shapes」随机进了个陌生群聊,发了句 "hello",三秒内就有 AI 角色接上,回了串热情有…...
STM32F407用HAL库驱动42步进电机,从CubeMX配置到代码调试的完整避坑指南
STM32F407 HAL库驱动42步进电机实战:从CubeMX配置到高效调试的完整指南 第一次用STM32F407的HAL库驱动42步进电机时,我花了整整三天时间才让电机转起来。最让我抓狂的是明明CubeMX配置看起来一切正常,TIM1通道就是死活不出PWM波形。后来才发现…...
紧急更新!Midjourney v6.6对洛可可风格支持突降37%?立即启用这5个兼容性补丁prompt,保住你的商业项目交付期
更多请点击: https://intelliparadigm.com 第一章:Midjourney v6.6洛可可风格兼容性危机全景速览 Midjourney v6.6 发布后,大量用户在生成洛可可(Rococo)风格图像时遭遇显著退化:繁复卷曲的藤蔓纹样被简化…...
为什么说Ohook重新定义了Office激活的技术边界?
为什么说Ohook重新定义了Office激活的技术边界? 【免费下载链接】ohook An universal Office "activation" hook with main focus of enabling full functionality of subscription editions 项目地址: https://gitcode.com/gh_mirrors/oh/ohook 当…...
Audio Slicer:智能音频切片工具终极指南,告别手动剪辑烦恼
Audio Slicer:智能音频切片工具终极指南,告别手动剪辑烦恼 【免费下载链接】audio-slicer A simple GUI application that slices audio with silence detection 项目地址: https://gitcode.com/gh_mirrors/aud/audio-slicer 还在为繁琐的音频剪辑…...
