Flutter如何查询Android/iOS设备存储的所有本地视频文件
Flutter 双端查询设备本地视频文件实现方案
Flutter 框架本身没有内置访问系统媒体库的API,要实现和Android原生MediaStore+ContentResolver一致的全量视频查询、属性获取能力,有两种成熟实现路径:
方案1:使用成熟插件快速实现(生产环境优先选择)
目前社区维护的photo_manager是双端媒体查询能力最完整的插件,底层直接对接Android原生MediaStore、iOS原生PhotoKit,不需要自己写原生代码就能拿到所有需要的媒体属性。
- 前置权限配置
- Android端:在项目
android/app/src/main/AndroidManifest.xml中添加对应权限<!-- Android 13+ 读取视频媒体权限 --> <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> <!-- Android 12及以下版本读取存储权限 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> - iOS端:在项目
ios/Runner/Info.plist中添加相册权限描述<key>NSPhotoLibraryUsageDescription</key> <string>需要访问本地视频文件用于播放</string>
- Android端:在项目
- 核心查询代码示例
import 'package:photo_manager/photo_manager.dart'; /// 获取设备所有本地视频文件 Future<List<AssetEntity>> getAllLocalVideos() async { // 申请媒体访问权限 final PermissionState permission = await PhotoManager.requestPermissionExtend(); if (!permission.hasAccess) return []; // 筛选仅视频类型,按创建时间倒序排列 final List<AssetPathEntity> videoDirs = await PhotoManager.getAssetPathList( type: RequestType.video, onlyAll: true, // 直接获取全量视频聚合目录,无需遍历零散文件夹 filterOption: FilterOptionGroup( orders: [const OrderOption(type: OrderOptionType.createDate, asc: false)], ), ); final List<AssetEntity> result = []; if (videoDirs.isEmpty) return result; // 分页拉取避免一次性加载过多数据卡顿 int pageIndex = 0; const int pageSize = 100; List<AssetEntity> pageData; do { pageData = await videoDirs.first.getAssetListPaged(page: pageIndex, size: pageSize); result.addAll(pageData); pageIndex++; } while (pageData.length == pageSize); return result; } - 可获取的媒体属性:通过返回的
AssetEntity对象,可以直接拿到视频的标题、时长、分辨率、创建/修改时间、文件大小、缩略图数据、可直接用于播放的本地文件路径,和原生MediaStore查询返回的字段完全对齐。
方案2:自定义MethodChannel对接原生逻辑(适合高度定制场景)
如果插件现有能力不满足特殊查询需求,可以自行编写跨端通道对接原生逻辑,实现逻辑和原生开发完全一致:
- Android端:在MethodChannel对应的原生方法中,使用
ContentResolver查询MediaStore.Video媒体库,将查询到的视频ID、标题、路径、时长、分辨率、文件大小等字段封装为结构化数据,回传给Dart层即可。注意Android 10及以上分区存储机制下,不要依赖旧版的DATA字段判断文件可访问性,优先使用Content Uri做后续操作。 - iOS端:在MethodChannel对应的原生方法中,使用PhotoKit框架查询所有
PHAssetMediaType.video类型的资源,封装对应属性后回传,注意处理相册权限申请、沙盒临时访问授权的逻辑。
避坑提示
- 不要使用纯目录遍历类的文件查询插件:这类插件只会遍历应用沙盒可见的文件目录,在Android高版本分区存储、iOS沙盒限制下会漏掉大量系统媒体库索引的视频,查询结果和原生MediaStore不一致。
- 全量查询视频时必须做分页加载,避免一次性加载上千条数据导致UI卡顿、内存溢出。
- 查询返回的视频路径可以直接传入
video_player、fijkplayer等主流Flutter播放器插件,不需要额外做路径转换。
内容的提问来源于stack exchange,提问作者Kenart
相关产品推荐
相关产品推荐

