You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用file_picker从Google Drive选择视频无法显示的问题求助

问题:使用file_picker从Google Drive选择视频无法显示,本地存储正常

我在用file_picker插件直接从Google Drive选视频文件,但选中的视频没法显示;从手机本地存储选视频就正常工作。有人遇到过这个问题吗?

我的代码如下:

void _pickPerformanceVideo() async {
  _fileSelectionNotifier.performanceVideoFileLoaderNotifier(true);
  try {
    _performanceVideoPath = (await FilePicker.platform.pickFiles(
      allowedExtensions: ['mp4', 'mov'],
      type: FileType.custom,
      allowMultiple: false,
      onFileLoading: (FilePickerStatus status) => print(status),
    ))
        ?.files;
    
    await Future.delayed(Duration(seconds: 2));

    if (_performanceVideoPath != null) {
      int sizeInBytes = _performanceVideoPath!.first.size;
      double sizeInMb = sizeInBytes / (1024 * 1024);
      if (sizeInMb <= 0) {
        _performanceVideoPath = null;
        final snackBar = showSnackBar(strVideoSizeError2, 3,
            duration: Duration(microseconds: 3000));
        ScaffoldMessenger.of(context).showSnackBar(snackBar);
      } else if (sizeInMb > 250) {
        _performanceVideoPath = null;
        final snackBar = showSnackBar(strVideoSizeError, 3,
            duration: Duration(microseconds: 3000));
        ScaffoldMessenger.of(context).showSnackBar(snackBar);
      } else {
        _fileSelectionNotifier.performanceFileNotifier(true);
        _fileSelectionNotifier
            .performanceFileNameNotifier(_performanceVideoPath!.first.name);
        _fileSelectionNotifier.setPerformanceValidationValue(false);
      }
      _fileSelectionNotifier.performanceVideoFileLoaderNotifier(false);
    }
    print(_performanceVideoPath!.single.path);
  } on PlatformException catch (e) {
    if (kDebugMode) {
      print('Unsupported operation' + e.toString());
    }
  } catch (e) {
    if (kDebugMode) {
      print(e.toString());
    }
  } finally {
    debugPrint("entered in finally block_performance vide");
    _fileSelectionNotifier.performanceVideoFileLoaderNotifier(false);
  }
}

原因分析

Google Drive这类云端存储的文件并没有本地文件系统的真实路径,file_picker返回的path字段会为空或无效,直接用这个路径加载视频自然失败。本地存储的文件因为有真实本地路径,所以能正常访问。

解决方案

不要依赖path字段,改用文件字节数据将云端文件复制到本地临时目录后再使用,具体修改如下:

1. 修改file_picker调用参数

开启withData: true,确保能获取到云端文件的字节数据:

final result = await FilePicker.platform.pickFiles(
  allowedExtensions: ['mp4', 'mov'],
  type: FileType.custom,
  allowMultiple: false,
  onFileLoading: (FilePickerStatus status) => print(status),
  withData: true, // 关键:开启后可获取云端文件字节
);

2. 处理空路径情况,复制文件到本地

如果path为空,就把字节数据写入本地临时文件,用临时路径加载视频:

// 处理云端文件:如果path为空,保存到本地临时目录
String? localPath;
if (pickedFile.path == null && pickedFile.bytes != null) {
  // 创建临时文件
  final tempDir = await getTemporaryDirectory();
  final tempFile = File('${tempDir.path}/${pickedFile.name}');
  await tempFile.writeAsBytes(pickedFile.bytes!);
  localPath = tempFile.path;
} else {
  localPath = pickedFile.path;
}

3. 完整修改后的代码

void _pickPerformanceVideo() async {
  _fileSelectionNotifier.performanceVideoFileLoaderNotifier(true);
  try {
    final result = await FilePicker.platform.pickFiles(
      allowedExtensions: ['mp4', 'mov'],
      type: FileType.custom,
      allowMultiple: false,
      onFileLoading: (FilePickerStatus status) => print(status),
      withData: true,
    );
    
    if (result == null) {
      _fileSelectionNotifier.performanceVideoFileLoaderNotifier(false);
      return;
    }

    _performanceVideoPath = result.files;
    await Future.delayed(Duration(seconds: 2));

    if (_performanceVideoPath != null) {
      final pickedFile = _performanceVideoPath!.first;
      int sizeInBytes = pickedFile.size;
      double sizeInMb = sizeInBytes / (1024 * 1024);
      
      if (sizeInBytes <= 0) {
        _performanceVideoPath = null;
        final snackBar = showSnackBar(strVideoSizeError2, 3,
            duration: Duration(seconds: 3)); // 修复时间单位错误
        ScaffoldMessenger.of(context).showSnackBar(snackBar);
      } else if (sizeInMb > 250) {
        _performanceVideoPath = null;
        final snackBar = showSnackBar(strVideoSizeError, 3,
            duration: Duration(seconds: 3)); // 修复时间单位错误
        ScaffoldMessenger.of(context).showSnackBar(snackBar);
      } else {
        // 处理云端文件:如果path为空,保存到本地临时目录
        String? localPath;
        if (pickedFile.path == null && pickedFile.bytes != null) {
          final tempDir = await getTemporaryDirectory();
          final tempFile = File('${tempDir.path}/${pickedFile.name}');
          await tempFile.writeAsBytes(pickedFile.bytes!);
          localPath = tempFile.path;
        } else {
          localPath = pickedFile.path;
        }

        // 用localPath加载视频
        _fileSelectionNotifier.performanceFileNotifier(true);
        _fileSelectionNotifier.performanceFileNameNotifier(pickedFile.name);
        _fileSelectionNotifier.setPerformanceValidationValue(false);
        
        print('本地路径:$localPath');
      }
      _fileSelectionNotifier.performanceVideoFileLoaderNotifier(false);
    }
  } on PlatformException catch (e) {
    if (kDebugMode) {
      print('Unsupported operation: ${e.toString()}');
    }
    _fileSelectionNotifier.performanceVideoFileLoaderNotifier(false);
  } catch (e) {
    if (kDebugMode) {
      print(e.toString());
    }
    _fileSelectionNotifier.performanceVideoFileLoaderNotifier(false);
  } finally {
    debugPrint("entered in finally block_performance vide");
    _fileSelectionNotifier.performanceVideoFileLoaderNotifier(false);
  }
}

4. 添加依赖

需要path_provider来获取临时目录,在pubspec.yaml中添加:

dependencies:
  path_provider: ^2.1.1

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 16:45:36