Мое приложение аварийно завершает работу, когда я выбираю несколько видео (1+ минут каждое) из библиотеки фотографий из-за предупреждения о памяти. Я пытаюсь сжать видео, но все равно та же проблема, хотя код сжатия работает правильно. Я хочу, чтобы мое приложение выбирало 5 видео одновременно и отправляло их в чат. Whatsapp позволяет пользователю выбрать 30 видео и отправить их в чат, но мое приложение падает из-за проблем с памятью только после 3 видео. Я использую библиотеку AssetsPickerViewController для выбора нескольких изображений/видео.
func assetsPicker(controller: AssetsPickerViewController, selected assets: [PHAsset]) {
self.dismiss(animated: true, completion: nil)
var isImages = false
var mediaData: [Data] = []
let imageManager = PHCachingImageManager.default()
DispatchQueue.main.async {
self.appDelegate.helper.showHUD(withMessage: "Preparing media", withObject: self)
}
autoreleasepool {
for selectedAsset in assets {
if selectedAsset.mediaType == .image {
isImages = true
let option = PHImageRequestOptions()
option.isSynchronous = true
option.isNetworkAccessAllowed = true
imageManager.requestImageData(for: selectedAsset, options: option) { (assetData, assetDataUTI, assetOrientation, assetInfo) in
if let data = assetData {
if let image = UIImage(data: data)?.upOrientation(), let finalData = image.jpegData(compressionQuality: 0.5) {
if let newData = ImageHelper.removeExifData(data: finalData as NSData) {
mediaData.append(newData as Data)
self.checkFileStatus(mediaCount: mediaData.count, assetsCount: assets.count, data: mediaData, isImages: isImages)
} else {
mediaData.append(finalData)
self.checkFileStatus(mediaCount: mediaData.count, assetsCount: assets.count, data: mediaData, isImages: isImages)
}
} else {
mediaData.append(data)
self.checkFileStatus(mediaCount: mediaData.count, assetsCount: assets.count, data: mediaData, isImages: isImages)
}
}
}
} else if selectedAsset.mediaType == .video {
let options: PHVideoRequestOptions = PHVideoRequestOptions()
options.isNetworkAccessAllowed = true
options.deliveryMode = .fastFormat
self.convertVideo(phAsset: selectedAsset) { (data) in
if let finalData = data {
mediaData.append(finalData)
self.checkFileStatus(mediaCount: mediaData.count, assetsCount: assets.count, data: mediaData, isImages: isImages)
} else {
}
}
}
}
}
}
func compressVideo(inputURL: URL, outputURL: URL, handler:@escaping (_ exportSession: AVAssetExportSession?)-> Void) {
let urlAsset = AVURLAsset(url: inputURL, options: nil)
guard let exportSession = AVAssetExportSession(asset: urlAsset, presetName: AVAssetExportPresetMediumQuality) else {
handler(nil)
return
}
exportSession.outputURL = outputURL
exportSession.outputFileType = AVFileType.mp4
exportSession.shouldOptimizeForNetworkUse = true
exportSession.exportAsynchronously { () -> Void in
handler(exportSession)
}
}
autoreleasepool {
внутри вашего цикла. Поэтому изменитеautoreleasepool {
for selectedAsset in assets {
наfor selectedAsset in assets {
autoreleasepool {
- person Leo Dabus   schedule 21.12.2020mediaData.append(finalData)
. Вместо того, чтобы загружать все ваши видеоданные в память, вы должны создать для них временные файлы. - person Leo Dabus   schedule 21.12.2020mediaData.append(finalData)
, чтобы проверить, работает ли только выбор видео, но проблема с памятью все та же. - person Priyanka   schedule 21.12.2020mediaData
синхронизированным образом. Поскольку не гарантируется, что обработчики завершения будут вызываться в той же очереди, у вас могут возникнуть также проблемы с гонкой данных. То, как вы это делаете, то есть получение видео в виде объекта данных и сохранение их в массив, не рекомендуется, поскольку для этого требуется выделить огромный объем памяти. Вам лучше использовать файловые потоки и, следовательно, гораздо более сложный подход. - person CouchDeveloper   schedule 21.12.2020