IOS SWIFT генерация миниатюр
Я занимаюсь разработкой видео триммера ios с помощью swift 4. Я пытаюсь отобразить горизонтальный список миниатюр видео, разбросанных по различным периодам, как из локальных видеофайлов, так и из удаленных URL-адресов. Когда я проверяю это в симуляторе, миниатюры генерируются менее чем за секунду, что нормально. Тем не менее, когда я тестирую этот код на реальном устройстве, генерация миниатюр происходит очень медленно и иногда дает сбой. Я попытался добавить фактическую генерацию изображения в фоновый поток, а затем обновить пользовательский интерфейс основного потока, когда он будет завершен, но, похоже, это работает не очень хорошо, и приложение несколько раз вылетает после рендеринга экрана. Я не уверен, что это потому, что я ухожу от экрана, пока задачи еще не завершены. Я пытаюсь решить эту проблему, и приложение генерирует эскизы быстрее и не вылетает. Вот код, который я использую ниже. Я был бы очень признателен за любую помощь в этом вопросе.
func renderThumbnails(view: UIView, videoURL: URL, duration: Float64) {
var offset: Float64 = 0
for i in 0..<self.IMAGE_COUNT{
DispatchQueue.global(qos: .userInitiated).async {
offset = Float64(i) * (duration / Float64(self.IMAGE_COUNT))
let thumbnail = thumbnailFromVideo(videoUrl: videoURL,
time: CMTimeMake(Int64(offset), 1))
DispatchQueue.main.async {
self.addImageToView(image: thumbnail, view: view, index: i)
}
}
}
}
static func thumbnailFromVideo(videoUrl: URL, time: CMTime) -> UIImage{
let asset: AVAsset = AVAsset(url: videoUrl) as AVAsset
let imgGenerator = AVAssetImageGenerator(asset: asset)
imgGenerator.appliesPreferredTrackTransform = true
do{
let cgImage = try imgGenerator.copyCGImage(at: time, actualTime: nil)
let uiImage = UIImage(cgImage: cgImage)
return uiImage
}catch{
}
return UIImage()
}
1 ответ
Первое предложение документации говорит не делать то, что вы делаете! И он даже говорит вам, что делать вместо этого.
Генерация одиночного изображения может потребовать декодирования большого количества видеокадров со сложными взаимозависимостями. Если вам требуется серия изображений, вы можете достичь гораздо большей эффективности, используя асинхронный метод,
generateCGImagesAsynchronously(forTimes:completionHandler:)
, который использует эффективности декодирования, аналогичные тем, которые используются во время воспроизведения.
(Курсив мой.)