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

iPhone应用录制视频无法获取问题求助(需上传至AWS存储桶)

解决iPhone端获取录制视频并上传至AWS S3的问题

看起来你是通过Photos框架创建了视频资产,但现在卡在了获取实际文件这一步——毕竟PHAsset只是Photos库中资源的引用,不是本地文件路径,直接访问目录肯定拿不到实际内容。下面从权限和正确获取文件的方法两方面帮你解决:

一、先排查权限问题

  • Photos库权限:确保你的APP已经获取了足够的Photos访问权限。在iOS 14及以上,用户可能授予了「受限访问」权限,这会导致你只能访问用户手动选择的资产。你需要:
    1. 在Info.plist中配置NSPhotoLibraryUsageDescription(必要时加上NSPhotoLibraryAddUsageDescription),清晰说明你需要访问相册的原因;
    2. 请求并检查权限状态,代码示例如下:
      PHPhotoLibrary.requestAuthorization { status in
          if status == .authorized || status == .limited {
              // 有权限,继续后续操作
          } else {
              // 提示用户前往设置开启权限
          }
      }
      
  • 文件系统权限:如果你的视频是保存在APP沙盒内(而非Photos库),要确保你有读取该目录的权限——不过从你提到的PHAssetResourceCreationOptions来看,大概率是存在Photos库中,所以重点还是Photos权限。

二、正确获取视频文件的方法

因为PHAsset不是实际文件,你需要用PHAssetResourceManager将视频导出到APP沙盒的临时目录,之后再上传这个临时文件到AWS S3。具体步骤如下:

  1. 定位目标PHAsset:先找到你录制并保存的那个PHAsset(比如通过本地标识、或者查询Photos库的方式获取)。
  2. 导出视频到临时路径:
    func exportVideo(asset: PHAsset, completion: @escaping (URL?) -> Void) {
        guard let resource = PHAssetResource.assetResources(for: asset).first else {
            completion(nil)
            return
        }
        
        let tempDir = FileManager.default.temporaryDirectory
        let tempFileURL = tempDir.appendingPathComponent("\(UUID().uuidString).mov")
        
        let options = PHAssetResourceRequestOptions()
        options.isNetworkAccessAllowed = true // 如果视频存于iCloud,必须开启此选项
        
        PHAssetResourceManager.default().writeData(for: resource, toFile: tempFileURL, options: options) { error in
            if let error = error {
                print("导出视频失败:\(error.localizedDescription)")
                completion(nil)
            } else {
                completion(tempFileURL)
            }
        }
    }
    
  3. 上传临时文件到AWS S3:拿到tempFileURL后,就可以用AWS SDK(比如AWSS3TransferUtility)完成上传,记得上传后清理临时文件:
    func uploadToS3(fileURL: URL, bucketName: String, key: String) {
        let transferUtility = AWSS3TransferUtility.default()
        transferUtility.uploadFile(fileURL, bucket: bucketName, key: key, contentType: "video/quicktime")
            .continueWith { task in
                defer {
                    // 无论成功失败,都删除临时文件释放空间
                    try? FileManager.default.removeItem(at: fileURL)
                }
                if let error = task.error {
                    print("上传失败:\(error.localizedDescription)")
                } else {
                    print("上传成功")
                }
                return nil
            }
    }
    

三、补充说明

  • 如果你是在APP内直接录制视频(未存入Photos库),那应该能直接拿到录制后的本地文件路径,这时候要检查保存视频的代码是否正确,确保路径无误且有读取权限。
  • 导出时如果视频存放在iCloud上,一定要设置options.isNetworkAccessAllowed = true,否则会因无法获取iCloud资源导致导出失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:11:36