Swift中.mov文件与JPEG转Data等效的格式转换方法
问题描述
我现有一段使用Amplify在AWS S3存储桶上传、拉取图片的代码,运行正常:
let uploadTask = Amplify.Storage.uploadData(key: imageKey, data: srcData, options: nil) Task { for await progress in await uploadTask.progress { print("Progress: \(progress)") } } do { let value = try await uploadTask.value print("Completed: \(value)") return true } catch { print("problem uploading \(error)") } return false
该代码可正常完成上传,对应的下载代码也能正常工作。但我的目标是在App内将.mov文件(或其他Mac兼容视频格式)上传至AWS,并从AWS拉取这类文件。我认为现有代码框架可行,但缺失以下关键步骤:
- 将.mov文件(或其他Mac兼容视频格式)转换为Data以用于上传
- 将拉取到的Data转换回.mov文件,用于缓存或本地播放(非流式播放)
这些视频文件较小(<15Mb),最多同时10个可播放,因此内存占用不成问题,最终会保存至Caches目录。我推测需借助AVAsset或AVURLAsset实现,但尚未找到等效于<UIImage>.jpegData(...)的时基媒体转换方法,特此求助。
解决方案
1. 本地.mov文件转Data并上传
无需借助AVAsset/AVURLAsset,视频文件本身就是二进制数据,直接读取本地文件的Data即可,步骤如下:
- 获取本地.mov文件的URL(比如通过文件选择器或沙盒路径获取)
- 直接从URL读取Data,再复用你现有的Amplify上传逻辑
示例代码:
// 假设已获取本地视频的URL(例如来自文件选择器) guard let videoURL = selectedVideoURL, let videoData = try? Data(contentsOf: videoURL) else { print("无法读取视频文件") return false } // 自定义S3存储的key let videoKey = "videos/user_uploaded_video.mov" let uploadTask = Amplify.Storage.uploadData(key: videoKey, data: videoData, options: nil) Task { for await progress in await uploadTask.progress { print("上传进度: \(progress)") } } do { let value = try await uploadTask.value print("上传完成: \(value)") return true } catch { print("上传失败: \(error)") } return false
如果需要统一视频格式或压缩,才需要用AVAssetExportSession做转码,你的场景下直接原文件上传更高效。
2. 下载Data并保存为本地.mov文件
从S3下载到Data后,将其写入Caches目录的文件中,即可得到可播放的本地视频文件:
示例代码:
let videoKey = "videos/user_uploaded_video.mov" do { // 从S3下载视频Data let videoData = try await Amplify.Storage.downloadData(key: videoKey, options: nil).value // 获取Caches目录路径 guard let cachesDir = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first else { print("无法获取Caches目录") return nil } // 生成本地保存的URL let localVideoURL = cachesDir.appendingPathComponent("cached_video.mov") // 将Data写入本地文件 try videoData.write(to: localVideoURL) // 此时localVideoURL可直接用于AVPlayer播放或缓存 return localVideoURL } catch { print("下载或保存失败: \(error)") return nil }
内容的提问来源于stack exchange,提问作者Dan Donaldson
相关产品推荐
相关产品推荐

