Table of Contents
Video pikkukuvat ovat kulmakivi nykyaikaisissa media-rikas sovelluksissa, jotka tarjoavat käyttäjille nopean visuaalisen esikatselun tarvitsematta pelata koko videota. iOS-kehityksessä AVFounducation tarjoaa suorimmat ja joustavat työkalut peukalonkuvan poimimiseen. Tämä artikkeli kulkee läpi rakentamalla mukautetun videon peukalon generaattorin, joka pystyy käsittelemään tosimaailman skenaarioita. Mukaan lukien paikalliset ja etätiedostot, välimuisti, virheiden käsittely ja suorituskyky virittämällä.
AVFoundingation ...
AVFounding on Apple. Apple.Sen ensisijainen toimintakehys audiovisuaalisissa muodoissa on . Avainluokat ovat AVAsset ja AVAssetImageGenerator[.
- AVAsset[: Edustaa ajastettua audiovisuaalista aineistoa (paikallista tai etävideota). Se sisältää kappaletietoja, kestoa ja metatietoja.
- AVAssetImageGenerator[: Tarjoaa menetelmiä saada CGImageRefit omaisuuserän tiettynä ajan välein. Se kunnioittaa videon suuntautumista, soveltaa väritilan säätöjä, ja tukee asynkroninen irtotavarana generaation.
Käyttämällä näitä luokkia suoraan saat täyden hallinnan kuvan koon, ajan tarkkuuden ja muuntamisen suhteen, toisin kuin Uikit-pikakuvat, jotka usein piilottavat asetusvalinnat.
Projektin käynnistäminen
Aloita tuomalla AVFoundingation Swift-tiedostoosi:
import AVFoundation
Tarvitset myös UIKitin näyttämään luodut kuvat. Luo [ URL-osoitteesta. Paikallistiedostojen osalta käytä . Kaukovideoita varten käytä [ ja varmista, että kohde voidaan alustaa:
// 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)
Yhden peukalon luominen
Luodaksesi yhden pikkukuvan tiettynä aikana, luo [ ja soita . Tämä menetelmä on synkronoitu ja se on poistettava päälangasta, jotta vältetään käyttöliittymän estäminen.
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)")
}
Tärkeintä:[ Asettaen :lle varmistaa, että tuloksena oleva kuva kunnioittaa videon kiertometadataa (kuva vs. maisema). Ilman tätä pystysuora video saattaa näkyä sivuttain.
Oikean ajan valinta
Peukalot otetaan usein videon alussa, mutta harkitse käyttää aikaa, joka edustaa sisältöä. Esimerkiksi 10%:n verran duraatioon. Jotta saataisiin mielekäs aikapiste, kysy omaisuuserän duraatio:
let duration = asset.duration
let midTime = CMTimeMultiplyByFloat64(duration, multiplier: 0.1)
Virheiden ja sivuseikkatapausten käsittely
Peukalokäärme voi epäonnistua useista syistä. Käsittele virheet aina hienovaraisesti ja anna varakäyttöliittymä.
- Vähän käytetty ominaisuus:[ Video voi olla korruptoitunut tai URL-osoite on tavoittamaton.
- Kadonnut videoraita:[] Jotkut varat sisältävät vain äänen; tarkista .
- Aika, joka kuluu rajojen ulkopuolelle:[ Varmista, että pyydetty aika on ja omaisuuserän duraatio.
- Verkkovirheet:[ Etäistuotteet voivat olla ladattavia. Käytä ennen kuin luot pikkukuvia.
Esimerkki omaisuuden esilastauksesta:
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
}
}
Muokataan peukalon tulostus
AVASsetImageGenerator tarjoaa useita ominaisuuksia hienosäätää lähtökuvaa.
Enimmäiskoko
Rajoita luotu kuva tiettyyn rajauslaatikkoon käyttäen . Tämä vähentää muistin yläpintoja ja nopeuttaa suurten videoiden sukupolven nopeuttamista.
imageGenerator.maximumSize = CGSize(width: 640, height: 480)
Luotu kuva skaalataan sopimaan näihin mittoihin säilyttäen samalla kuvasuhteen.
Pyydetty aikatoleranssi
Oletuksena palauttaa tarkan kehyksen pyydettyyn aikaan (tai mahdollisimman lähelle). Nopeuden tarkkuutta voidaan vaihtaa asettamalla ja . Pikkukuvien osalta 0,5 sekunnin toleranssi on usein hyväksyttävä ja nopeampi:
imageGenerator.requestedTimeToleranceBefore = CMTime(seconds: 0.5, preferredTimescale: 600)
imageGenerator.requestedTimeToleranceAfter = CMTime(seconds: 0.5, preferredTimescale: 600)
Aukotila
valvoo, miten tuotettu kuva käsittelee puhdasta aukkoa vs. tuotantoaukko. Käytä reunapölyn poistamiseen ja puhtaamman pikkukuvan tuottamiseen:
imageGenerator.apertureMode = .cleanAperture
Muodonmuutosten soveltaminen
Jos haluat kääntää tai kääntää kuvaa (esim. tiettyä suuntaa varten), käytä Core Graphics -ohjelmistoa. Yksi lähestymistapa on ottaa raakakuva talteen ja sitten soveltaa CGAffineTransform -muotoa manuaalisesti. Vaihtoehtoisesti voit asettaa [] ]:een (kuten on esitetty) ja luottaa voimavaraan.
Useiden peukaloiden luominen tehokkaasti
Videoruudukoille, aikajanan pesulle tai tarinan esikatseluille tarvitaan usein kymmeniä pikkukuvia. Vältä soittamasta päälangan silmukaan . Sen sijaan käytä asynkronista menetelmää . Se käsittelee useita aikavaatimuksia tehokkaasti ja sisäistä rinnakkaisuutta tehokkaasti.
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")")
}
}
Tämä menetelmä asteikot hyvin ja voit päivittää käyttöliittymän asteittain. Muista soittaa , jos käyttäjä jättää näytön ilmaiseksi resursseja.
Työskentely etävideoiden kanssa
Kun videon URL-osoite osoittaa etäpalvelimelle, sinun on odotettava, että omaisuuserä on täysin ladattu tai ainakin sen ratatiedot ovat saatavilla. Käytä asianmukaisia välimuistiopaketteja toistuvien latausten välttämiseksi.
let urlAsset = AVURLAsset(url: remoteURL, options: [AVURLAssetPreferPreciseDurationAndTimingKey: true])
urlAsset.loadValuesAsynchronously(forKeys: ["tracks"]) {
// Then create image generator and proceed
}
Tuotannossa sovellukset, harkita välimuistia levyllä niin, että toistuva pääsy samaan videoon ei uudelleen hakemaan kuvaa. Käytä tai tiedostopohjainen välimuisti käyttäen videon URL avain.
Välimuististrategia esimerkki
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)
}
}
Yhdistä tämä kuvageneraattori välttää tarpeetonta työtä.
Suorituskyvyn huomioon ottaminen
Pienoiskuvien luominen on CPU-intensiivinen toiminto erityisesti korkean resoluution 4K-videoille.
- Soita aina synkronoituja puheluita taustajonossa (esim. ).
- Aseta kohtuullinen , jotta saadaan vähennettyä tulosteen kuvan mittoja. 320x240 koko riittää usein listan pikkukuviin.
- Käytä , jotta generaattori voi ohittaa lähimmän kehyksen eikä ratkaista tarkkaa koodinpurkua.
- Peru kaikki keskeneräiset analogiset sukupolvet, kun näkymä katoaa.
- Näyttöä varten kokoelmanäkymässä, luoda pikkukuvia tarkka solun koko ja välttää uudelleenkokoa päälangan.
Integrointi Swift Concurrency (Async/Await)
Jos sovelluksesi on iOS 15+, voit kääriä estopuhelun jatkoksi puhtaalle async/await-koodille:
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)
}
}
}
}
Kehittyneet muokkaukset
Esikatseluja videokoostumus
Jos videossasi käytetään (esim. vesileiman päällystys, värinsäätö), voit siirtää sen kuvageneraattorille:
imageGenerator.videoComposition = myVideoComposition
Luotu pikkukuva heijastaa yhdistettyä tulosta.
Luodaan peukalonnäkymiä live-kuville
Live-kuvia ovat videon ja kuvan yhdistelmä. Voit poimia peukalon videon taustasta, käyttää ja pyytää videon URL-osoitetta ennen sen syöttämistä AVFounducationiin.
Esteettömyys ja käyttäjäkokemus
Peukalot parantavat visuaalista skannausta, mutta tarjoavat aina tekstin vaihtoehdon VoiceOver-käyttäjille. Käytä kuvanäkymässä , jossa kuvataan videosisältöä, jos mahdollista.
imageView.isAccessibilityElement = true
imageView.accessibilityLabel = "Thumbnail of video: \(videoTitle)"
Ulkoiset resurssit
Syvemmät tiedot:
- AVAssetImageGenerator Virallinen dokumentaatio
- AVAsset-viite
- WWDC 2019: AVFounding Performance Vinkkejä
Päätelmät
Kun rakennat videon videon pienkuvageneraattorin AVFounducation-sovelluksella, saat täydellisen vapauden kuvan laadun, ajoituksen ja suorituskyvyn yli. Käyttämällä :a sekä synkronisesti että synkronoidusti, käsittelemällä virheitä ja välimuistin avulla voit tarjota saumattoman käyttäjäkokemuksen iOS-sovelluksessasi. Olitpa tekemisissä paikallisten tiedostojen tai etävideoiden kanssa, tässä käsitellyt tekniikat auttavat sinua tuottamaan teräviä, konteksti-ware-pikkukuvia nopeasti ja tehokkaasti.