Swift视频体积过大问题:AssetsPickerViewController上传时assetsd报错
我之前也碰到过一模一样的问题,这个错误本质上是因为你直接处理原始视频数据时占用了过多内存,导致iOS系统不得不终止assetsd进程——毕竟iOS对内存管控极其严格,当某个后台进程(这里负责资源管理的assetsd)占用资源过高时,系统会优先杀掉它来保障整体稳定性。30秒就50MB的视频属于未压缩的原始素材,直接读取上传肯定会触发内存预警。
下面是几个亲测有效的解决方案:
1. 先对视频进行压缩处理
这是最核心的解决办法,通过AVFoundation框架把原始视频压缩成体积更小的版本,再上传压缩后的文件。推荐用AVAssetExportSession来实现,它能帮你调整视频的分辨率、比特率、编码格式,大幅降低文件大小的同时尽量保留画质。
给你一段Swift的示例代码:
import AVFoundation func compressVideo(inputURL: URL, outputURL: URL, completion: @escaping (URL?, Error?) -> Void) { let asset = AVAsset(url: inputURL) guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetMediumQuality) else { completion(nil, NSError(domain: "VideoCompression", code: -1, userInfo: [NSLocalizedDescriptionKey: "无法创建视频导出会话"])) return } exportSession.outputURL = outputURL exportSession.outputFileType = .mp4 exportSession.shouldOptimizeForNetworkUse = true // 开启网络传输优化 exportSession.exportAsynchronously { switch exportSession.status { case .completed: completion(outputURL, nil) case .failed, .cancelled: completion(nil, exportSession.error) default: break } } }
你可以根据需求选择不同的presetName:比如AVAssetExportPresetLowQuality体积最小,AVAssetExportPresetHighestQuality画质最优但压缩比低。
2. 避免一次性加载整个视频到内存
别直接用Data(contentsOf: videoURL)这种方式把整个视频读进内存,瞬间的高内存占用是触发assetsd崩溃的关键。建议用文件流上传或者直接传递本地文件路径,让网络库(比如Alamofire、AFNetworking)去处理分段读取,这样内存占用会平稳很多。
比如用Alamofire上传文件的示例:
import Alamofire func uploadCompressedVideo(videoURL: URL) { AF.upload(multipartFormData: { multipartFormData in multipartFormData.append(videoURL, withName: "video", fileName: "compressed_video.mp4", mimeType: "video/mp4") }, to: "你的服务器上传接口URL") .responseJSON { response in // 处理上传结果 } }
3. 优化AssetsPicker的资源获取配置
检查一下AssetsPickerViewController的设置,看看是否有选项可以直接获取经过压缩的视频,而非原始素材。有些相册选择器会提供“选择压缩版”的开关,或者允许你指定获取视频的最大分辨率,这样能从源头减少数据量。
总结一下:核心思路就是降低内存峰值占用,通过压缩减小文件体积,再用流式上传的方式处理,就能彻底避免assetsd被系统强制终止的问题。
内容的提问来源于stack exchange,提问作者Angel

