Video başları modern medya zengin uygulamaları temel bir temel oluşturuyor, kullanıcıların gerçek dünya senaryolarını ele geçirebilecek hızlı bir görsel önizleme sunuyor. iOS geliştirmede, AVFoundation, çekail görüntüleri için en performansa ve esnek araçlar sağlar.Bu makale gerçek dünya senaryolarını ele alabilecek özel bir video başparmak jeneratörü sunuyor - yerel ve uzaktan dosyalar, caching, hata işleme ve performans ayarlayabiliyor - Swift ve AVFoundation.

AVFoundation'ın katnail Generationdaki rolünü anlamak

AVFoundation Apple'ın görsel medya ile çalışmak için birincil çerçevedir. Forparnail nesil, anahtar sınıflar israfı:0)AVAsset) ve [[Dönem:2AVAssetImageGenerator).

  • [FONT:0]AVAsset[[Dönetici: Bir zamanlayıcı görsel bir görsel varlık ( yerel veya uzaktan bir video). Bu, bilgi, süresi ve metadata içerir.
  • [FONT:0]AVAssetImageGenerator[DÜT:1): Belirli zaman aralıklarında CGImageRefs elde etmek için yöntemler sağlayın. Video yönelimine saygı duyar, renk uzay düzenlemeleri uygular ve asynchronous nesli destekler.

Bu sınıflar kullanarak doğrudan görüntü boyutunun, zaman doğruluğunun ve dönüşümün kontrolünü verirsiniz, UIKit kısayollarının aksine genellikle konfigürasyon seçeneklerini gizler.

Projeyi kurmak

Swift dosyasına AVFoundation tarafından başlayın:

import AVFoundation

Ayrıca oluşturulan görüntüleri görüntülemek için UIKit'e ihtiyacınız var. Bir URL'den bir URL'ye ait bir URL'ye ait bir URL oluşturun. Yerel dosyalar için, [[ŞUygun videolar için, kullanımdan yararlanın:2).

// Local
let localURL = Bundle.main.url(forResource: "sample", withExtension: "mp4")!
let asset = AVAsset(url: localURL)

// Remote
let remoteURL = URL(string: "https://example.com/video.mp4")!
let remoteAsset = AVAsset(url: remoteURL)

Tek bir vaftiz için Gening

Belirtilen bir zamanda bir başparmak oluşturmak için, aİLFLT:5 oluşturmak ve callETHFLT:6) denir ve bu yöntem senkronize edilir ve UI'yi engellemek için ana iplikden kaçınılmalıdır.

let imageGenerator = AVAssetImageGenerator(asset: asset)
imageGenerator.appliesPreferredTrackTransform = true

let time = CMTime(seconds: 2.0, preferredTimescale: 600) // 2 seconds into the video

do {
 let cgImage = try imageGenerator.copyCGImage(at: time, actualTime: nil)
 let thumbnail = UIImage(cgImage: cgImage)
 // Update UI on main thread
 DispatchQueue.main.async {
 imageView.image = thumbnail
 }
} catch {
 print("Thumbnail generation failed: \(error.localizedDescription)")
}

[FONT:0)İmportant:[Dönetici:[Dönetici: · 9) Bu, videonun dönüşü metadata (portrait vs. manzara) ile ilgili olarak, doğru bir video yan yollara görünebilir.

Doğru Zaman Seçin

Katalonlar genellikle bir videonun başında alınır, ancak içeriği temsil eden bir zaman kullanmayı düşünün - süresine% 10.

let duration = asset.duration
let midTime = CMTimeMultiplyByFloat64(duration, multiplier: 0.1)

Hataları ve Edge Vakalarını Kullanın

İvan üretimi birkaç nedenden dolayı başarısız olabilir. Her zaman hataları özenle halledin ve geri dönüş UI sağlayabilir.

  • [[Dönderlik:0)Invalid varlık:[Döntilmiş veya ulaşılamaz URL’ler olabilir.
  • [FONT:0)Missing video izle: Bazı varlıklar sadece ses içerir; checkurFLT:11).
  • [FONT:0) Sınırlardan Zaman:[Dönemli zaman, [[Dönemli zaman, [[Şerefli zaman, [[Üye Olmayanlar İçindir.
  • [FONT:0) Ağ hataları:[Döneticiler yükleyemez.UseurFLT:13) başparmaklar üretmeden önce.

Varlık özelliklerini önceden yükleme örneği:

let assetKeys = ["tracks", "duration", "playable"]
asset.loadValuesAsynchronously(forKeys: assetKeys) {
 var error: NSError?
 let status = asset.statusOfValue(forKey: "tracks", error: &error)
 if status == .loaded {
 // Safe to generate thumbnails
 } else {
 // Handle error
 }
}

Özelleştirmeli katnail Çıktı

AVAssetImageGenerator, çıktı imajını iyi almak için birkaç özellik sunar.

maksimum Boyut

Oluşturulan görüntüyü, büyük videolar için bellek yükünü ve hızlarını azaltır.

imageGenerator.maximumSize = CGSize(width: 640, height: 480)

Oluşturulan görüntü, yön oranını korurken bu boyutlarda sığacak.

İstekli Zaman Hoşgörü

Varsayılan olarak,FLEN: 5) Talep edilen zamanda tam çerçeveyi döndürür (veya mümkün olduğunca yakın).Süresel olarak hız için doğru ticaret doğruluk sağlayabilirsiniz.() ve [[Döneticiler için, 0,5 saniye toleransı genellikle kabul edilebilir ve daha hızlı:

imageGenerator.requestedTimeToleranceBefore = CMTime(seconds: 0.5, preferredTimescale: 600)
imageGenerator.requestedTimeToleranceAfter = CMTime(seconds: 0.5, preferredTimescale: 600)

Aperture Mode

[[Dönetici:) Oluşturulan görüntünün nasıl temiz bir aperture vs. üretim aperture. UseurFLT:22 kenar tozunu kaldırmak ve daha temiz bir başparmak üretmek için:

imageGenerator.apertureMode = .cleanAperture

Dönüşümleri uygulayın

Görüntüyü döndürmek veya çevirmek zorundasınız (örneğin, belirli bir yönelim için), Core Graphics dönüştürücüleri kullanmak ve sonra bir CGAffineTransform'u manuel olarak uygulamaktır.

Multitorinails verimli bir şekilde optimize etmek

Video ızgaralar, zaman çizelgesi ovuşturma veya hikaye dolabı önbellekleri için, genellikle düzinelerce başparmak gerekir.You callETHFLT:26), ana iplik üzerinde bir döngüde. yerine, asynchronous yöntemi kullanın.It processes multiple time requests efficiently, leveraging internal paralelism.

var times: [NSValue] = []
for i in 0..<10 {
 let time = CMTime(seconds: Double(i) * 2.0, preferredTimescale: 600)
 times.append(NSValue(time: time))
}

imageGenerator.generateCGImagesAsynchronously(forTimes: times) { requestedTime, cgImage, actualTime, result, error in
 if result == .succeeded, let cgImage = cgImage {
 let thumbnail = UIImage(cgImage: cgImage)
 DispatchQueue.main.async {
 // Append to array or update collection view cell
 }
 } else {
 print("Failed at \(requestedTime): \(error?.localizedDescription ?? "unknown")")
 }
}

Bu yöntem iyi ölçekler ve UI artışını güncellemenize izin verir.Kullanıcının ekrandan ücretsiz kaynaklara ayrıldığını unutmayın.

Uzaktan Videolarla Çalışmak

Video URL uzaktan bir sunucuya işaret ettiğinde, varlığın tamamen yüklenmesini veya en azından mevcut olan takip bilgilerini beklemeniz gerekir.UseENFLT:30). tekrarlanan indirmelerden kaçınmak için uygun kalibrasyon başlıkları ile kullanın.

let urlAsset = AVURLAsset(url: remoteURL, options: [AVURLAssetPreferPreciseDurationAndTimingKey: true])
urlAsset.loadValuesAsynchronously(forKeys: ["tracks"]) {
 // Then create image generator and proceed
}

Üretim uygulamaları için, disk üzerinde caching başları düşünün, böylece aynı videoya tekrar erişim görüntüyü yeniden değerlendirmez.UseENFLT:32) veya dosya bazlı önbellekleri kullanarak video URL'yi anahtar olarak kullanarak.

Caching Strateji Örnek

class ThumbnailCache {
 static let shared = ThumbnailCache()
 private let cache = NSCache<NSString, UIImage>()

 func thumbnail(for url: URL) -> UIImage? {
 return cache.object(forKey: url.absoluteString as NSString)
 }

 func setThumbnail(_ image: UIImage, for url: URL) {
 cache.setObject(image, forKey: url.absoluteString as NSString)
 }
}

Bunu redundant çalışmalarından kaçınmak için görüntü jeneratörü ile birleştirin.

Performansı Tahmin Ediyor

Gening başları, özellikle yüksek çözünürlüklü 4K videoları için bir CPU yoğun bir operasyondur: Bu en iyi uygulamaları takip edin:

  • Her zaman bir arka kuyrukta senkronizasyon çağrısı yapar (örneğin, [[Düzgün: 34).
  • Çıktı görüntü boyutunu azaltmak için makul birFLİLMİŞ'i ayarlayın. 320x240 boyutu genellikle liste için yeterlidir.
  • UseFLT:36, jeneratörün tam decode'u çözme yerine en yakın çerçeveyi atmasına izin vermek için.
  • Görme kaybolurken herhangi bir inprogress asynchronous nesil.
  • Bir koleksiyon görünümünde, tam hücre büyüklüğünde başparmaklar üretir ve ana iplik üzerinde yeniden şekillendirmekten kaçınır.

Swift Concurrency (Async/A Wait) ile bütünleşme

Uygulamanız iOS 15 +'a ulaştığında, temiz bir async /a bekleme kodu için devam eden bir blokta blok çağrısını kapatabilirsiniz:

func generateThumbnail(forVideoAt url: URL, at time: CMTime) async throws -> UIImage {
 let asset = AVAsset(url: url)
 let imageGenerator = AVAssetImageGenerator(asset: asset)
 imageGenerator.appliesPreferredTrackTransform = true
 imageGenerator.maximumSize = CGSize(width: 640, height: 480)

 return try await withCheckedThrowingContinuation { continuation in
 let times = [NSValue(time: time)]
 imageGenerator.generateCGImagesAsynchronously(forTimes: times) { _, cgImage, _, result, error in
 if let cgImage = cgImage, result == .succeeded {
 let image = UIImage(cgImage: cgImage)
 continuation.resume(returning: image)
 } else {
 continuation.resume(throwing: error ?? ThumbnailError.generationFailed)
 }
 }
 }
}

Gelişmiş özelleştirmeler

Video Kompozisyon ile dikkatleri

Videonuz anİLFLT:38 kullanırsa (örneğin, sumark overlay, renkli ayarlamalar), görüntü jeneratörüne geçebilirsiniz:

imageGenerator.videoComposition = myVideoComposition

Üretilen başparmak, kompozit çıktıyı yansıtacaktır.

Canlı Fotoğraflar için bebekleri Gening Thumbnails for Live Photos

Canlı Fotoğraflar bir video ve hala görüntü kombinasyonudur. Altta videodan bir başparmak çıkarmak, bunu AVFoundation'a beslemeden önce bir video URL'yi kullanın.

Accessability and User Experience

İvanlar görsel taramayı geliştirir, ancak her zaman VoiceOver kullanıcıları için bir metin alternatifi sağlar. görüntü görünümünde, video içeriğini mümkün olup olmadığını tanımlamak için.

imageView.isAccessibilityElement = true
imageView.accessibilityLabel = "Thumbnail of video: \(videoTitle)"

Dış Kaynaklar

Daha derin anlayış için, aşağıdakilere danışın:

  • [FONT:0)AVAssetImageGenerator Resmi Dokümantasyon[Döncüm:0)
  • [FONT:0)AVAsset Referans[DÜDÜT-1]
  • [0]WWWDC 2019: AVFoundation Performance Tips).

Sonuç Sonuç Sonuç Sonuç Sonuç Sonuç Sonuç Sonuç

AVFoundation ile özel bir video başparmak jeneratörü inşa etmek size görüntü kalitesi, zamanlama ve performans üzerinde tam bir özgürlük verir.Spektif olarak ve asynchronously, iletişim hataları ve caching sonuçları ile, iOS uygulamanızda sorunsuz bir kullanıcı deneyimi sunabilir. Buradaki teknikler krinailler, bağlamı hızlı ve verimli bir şekilde üretebilir.