You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Flutter新手求助:如何从Amazon S3下载视频并保存至手机本地

Flutter从Amazon S3下载视频并保存到本地存储的方案

别担心经验不足,这个需求其实挺常见的,我给你拆解成几个简单的步骤,跟着来就行:

1. 准备必要的依赖包

首先需要两个核心pub包来帮我们完成任务:

  • dio:专门处理大文件下载的网络请求库,比原生http包更适合视频这类大资源
  • path_provider:帮我们获取手机上合法的存储路径,避免踩权限坑

在你的pubspec.yaml里添加这两个依赖:

dependencies:
  flutter:
    sdk: flutter
  dio: ^5.4.0  # 可以替换成最新稳定版本
  path_provider: ^2.1.2

然后运行flutter pub get完成安装。

2. 配置平台存储权限

不同系统的权限要求不一样,得提前配置好:

  • Android端:打开android/app/src/main/AndroidManifest.xml,添加对应权限:
<!-- Android 12及以下版本 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- Android 13+ 版本 -->
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
  • iOS端:打开ios/Runner/Info.plist,添加相册访问权限说明:
<key>NSPhotoLibraryAddUsageDescription</key>
<string>需要访问相册来保存下载的视频</string>

3. 核心下载逻辑实现

下面是完整的代码示例,我加了注释帮你理解每一步:

import 'dart:io';
import 'package:dio/dio.dart';
import 'package:path_provider/path_provider.dart';

Future<void> downloadS3Video() async {
  // 你的S3视频链接
  final String videoUrl = "https://s3-us-west-1.amazonaws.com/videos.ecuestre.digital/165-3745-40957-1.mp4";
  final Dio dio = Dio();

  try {
    // 优先获取外部存储目录(比如Android的Download文件夹、iOS的Documents)
    Directory? storageDir = await getExternalStorageDirectory();
    if (storageDir == null) {
      // 如果外部存储不可用, fallback到应用内部存储
      storageDir = await getApplicationDocumentsDirectory();
    }

    // 用原视频文件名生成保存路径
    final String fileName = videoUrl.split('/').last;
    final String savePath = "${storageDir.path}/$fileName";

    // 开始下载,支持实时显示进度
    await dio.download(
      videoUrl,
      savePath,
      onReceiveProgress: (receivedBytes, totalBytes) {
        if (totalBytes != -1) {
          // 这里可以把进度同步给UI,比如更新进度条
          print("下载进度: ${(receivedBytes / totalBytes * 100).toStringAsFixed(0)}%");
        }
      },
    );

    print("视频下载完成!保存路径:$savePath");
    // 这里可以加个Toast或者弹窗提示用户下载完成
  } catch (error) {
    print("下载出错了:$error");
    // 处理错误场景,比如网络断开、权限不足等
  }
}

4. 触发下载操作

你可以在按钮点击事件里调用这个下载方法,比如:

ElevatedButton(
  onPressed: () => downloadS3Video(),
  child: const Text("下载视频"),
)

额外注意点

  • 确保你的S3桶配置了正确的CORS规则,允许你的应用域名访问(测试阶段可以暂时放开所有来源,生产环境要严格限制)
  • 如果是超大视频,可以给dio加上断点续传逻辑,避免中途断网需要重新下载
  • 测试尽量用真机,模拟器的存储路径和权限逻辑可能和真机有差异

内容的提问来源于stack exchange,提问作者Mauricio Ramos

火山引擎 最新活动