Table of Contents
Video thumbnail adalah sebuah batu penjuru aplikasi kaya media modern, menawarkan pengguna pratinjau visual cepat tanpa perlu memainkan video penuh. Dalam pengembangan iOS, AVFoundation menyediakan alat yang paling pementas dan fleksibel untuk mengekstrak gambar thumbnail. Artikel ini berjalan melalui membangun generator thumbnail video gubahan yang dapat menangani skenario dunia nyata ⁇ termasuk berkas lokal dan remote, caching, penanganan kesalahan, dan tuning performance ⁇ menggunakan Swift dan AVFFoundation.
AVFoundation Peranan AVFoundation dalam Generasi Thumbnail
AVFoundation adalah kerangka utama Apple untuk bekerja dengan media audiovisual. Untuk pembuatan thumbnail, kelas kunci adalah AVAset dan AVAsetImageGenerator.
- [[GANDAFLT:0]]AVAsset: Mewakili aset audiovisual yang dikalikan (sebuah video lokal atau remote). Berisi informasi trek, durasi, dan data meta.
- OUGHFLT:0]]AVAsetImageGenerator: Menyediakan metode untuk mendapatkan CGIGImageRefs dari aset pada interval waktu tertentu. Ini menghormati orientasi video, menerapkan penyesuaian ruang warna, dan mendukung generasi massal yang tidak sinkron.
Menggunakan kelas-kelas ini secara langsung memberikan kontrol penuh atas ukuran gambar, ketepatan waktu, dan transformasi, tidak seperti pintasan UIKit yang sering menyembunyikan pilihan konfigurasi.
Membentuk Proyeknya dengan Bobot
Mulai dengan mengimpor AVFoundation ke dalam berkas Swift Anda:
import AVFoundation
Anda juga perlu UIKit untuk menampilkan gambar yang dihasilkan. Cipta sebuah dari sebuah URL. Untuk berkas lokal, gunakan . Untuk video jauh, gunakan dan pastikan aset dapat diinisialisasi:
// 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)
Mengeluarkan Satu Thumbnail
Untuk menghasilkan satu thumbnail pada waktu yang ditentukan, buatlah sebuah dan panggil . Metode ini adalah sinkron dan harus dijalankan dari thread utama untuk menghindari pemblokiran UI.
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)")
}
[[ZOZOFLT:0]]Penting: Menata ke memastikan gambar yang dihasilkan menghormati data meta rotasi video (portrait vs. lanskap). Tanpa ini, sebuah video tegak mungkin muncul menyamping.
Memikul Waktu yang Tepat
Thumbnail sering diambil di awal video, tetapi pertimbangkan menggunakan waktu yang mewakili isi ⁇ e.g., 10% ke dalam durasi. Untuk mendapatkan titik waktu yang berarti, kueri durasi aset:
let duration = asset.duration
let midTime = CMTimeMultiplyByFloat64(duration, multiplier: 0.1)
Kesalahan Penanganan dan Kasus Pinggiran
Generasi thumbnail thumbnail dapat gagal karena beberapa alasan. Selalu menangani kesalahan dengan anggun dan menyediakan UI fallback.
- Invalid asset: Video mungkin rusak atau URL tidak dapat dijangkau.
- [[Efrontha:0]]Missing video track: Beberapa aset hanya berisi audio; cek .
- [[CharfLT:0]]Waktu diluar batas: Pastikan waktu yang diminta adalah antara dan durasi aset.
- [[NOLNOLT:0]]Rerror jaringan: Aset jauh mungkin gagal untuk dimuat. Gunakan sebelum menghasilkan thumbnail.
Contoh properti aset preloading:
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
}
}
Kesuaian Kesuaian Thumbnail Output
AVAsetImageGenerator AVASset menawarkan beberapa properti untuk men-tabel-baik-baik gambar output.
Ukuran Maksimum Maksimum Maximum
Ini mengurangi memori overhead dan mempercepat generasi untuk video besar.
imageGenerator.maximumSize = CGSize(width: 640, height: 480)
Gambar yang dihasilkan oleh gondefin akan diskalakan untuk muat dalam dimensi ini sambil menjaga rasio aspek.
Permintaan Permintaan Waktu Toleransi
Secara default, mengembalikan bingkai tepat pada waktu yang diminta (atau sedekat mungkin). Anda dapat memperdagangkan ketepatan untuk kecepatan dengan menetapkan dan . Untuk thumbnail, toleransi sebesar 0.5 detik sering diterima dan lebih cepat:
imageGenerator.requestedTimeToleranceBefore = CMTime(seconds: 0.5, preferredTimescale: 600)
imageGenerator.requestedTimeToleranceAfter = CMTime(seconds: 0.5, preferredTimescale: 600)
Mode Bukaan
[[OGALT:21]] kontrol bagaimana gambar yang dihasilkan menangani aperture bersih vs aperture produksi. Gunakan untuk menghapus debu tepi dan menghasilkan thumbnail pembersih:
imageGenerator.apertureMode = .cleanAperture
Penjelmaan yang Memuakkan
Jika Anda perlu memutar atau membalik gambar (misalnya, untuk orientasi tertentu), gunakan transformasi Core Graphics. Salah satu pendekatan adalah menangkap gambar mentah dan kemudian menerapkan CGAffineTransform secara manual. Sebagai alternatif, Anda dapat mengatur ke (seperti yang ditunjukkan) dan mempercayai orientasi alami aset.
Menjana Multipel Thumbnails Efektif
Untuk kisi video, pengerukan garis waktu, atau pratinjau papan cerita, Anda sering membutuhkan puluhan thumbnail. Hindari pemanggilan dalam loop pada thread utama. Sebaliknya, gunakan metode asinkron . Ia memproses permintaan waktu berganda secara efisien, menyangga paralelisme internal.
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")")
}
}
Metode ini menskalakan dengan baik dan memungkinkan anda memperbarui UI secara bertokokan. Ingat untuk memanggil jika pengguna meninggalkan layar untuk membebaskan sumber daya.
Bekerja sama dengan Remote Video
Saat URL video menunjuk ke server jauh, anda harus menunggu aset dimuat penuh atau setidaknya informasi treknya tersedia. Gunakan dengan tajuk caching yang sesuai untuk menghindari pengunduhan berulang.
let urlAsset = AVURLAsset(url: remoteURL, options: [AVURLAssetPreferPreciseDurationAndTimingKey: true])
urlAsset.loadValuesAsynchronously(forKeys: ["tracks"]) {
// Then create image generator and proceed
}
Untuk aplikasi produksi , mempertimbangkan caching thumbnail pada disk sehingga akses berulang ke video yang sama tidak kembali ⁇ fetch gambar. Gunakan atau file ⁇ based cache menggunakan URL video sebagai kunci.
Contoh Steg Stematik Caching
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)
}
}
Dia akan menggabungkan ini dengan generator gambar untuk menghindari pekerjaan berlebihan.
Pertimbangan Kinerja Kinerja
Kothumbnail Generating adalah operasi CPU ⁇ intensif, terutama untuk video 4K resolusi tinggi. Ikuti praktik terbaik ini:
- ¡Ance selalu melakukan panggilan sinkron pada antrian latar belakang (misalnya, ).
- ¡Aturan [ untuk mengurangi dimensi gambar keluaran.Seukuran 320x240 sering mencukupi untuk thumbnail daftar.
- ifford Gunakan untuk memungkinkan generator untuk melewati frame terdekat daripada memecahkan decode yang tepat.
- Xauxéxon any dalam ⁇ progress asinkron generasi ketika pandangan menghilang.
- Untuk tampilan dalam tampilan koleksi, hasilkan thumbnail pada ukuran sel yang tepat dan hindari penjumlahan kembali pada benang utama.
Memutar dengan Konkurensi Swift (Async/Await)
iffandon Anda menargetkan aplikasi iOS 15+, Anda dapat membungkus panggilan blok dalam kelanjutan untuk kode async/await bersih:
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)
}
}
}
}
Kebiasaan Berkelanjutan
Thumbnails dengan Komposisi Video
Jika video Anda menggunakan (misalnya, watermark overlay, penyesuaian warna), Anda dapat memberikannya ke generator gambar:
imageGenerator.videoComposition = myVideoComposition
thumbnail yang dihasilkan akan mencerminkan output komposit.
Memuakkan Thumbnail untuk Foto Langsung
Foto Live Whats adalah kombinasi dari video dan gambar yang masih ada. Untuk mengekstrak thumbnail dari video yang mendasarinya, gunakan dan meminta URL video sebelum memberinya makan ke AVFoundation.
Kebolehcapaian dan Pengalaman Pengguna
Thumbnails meningkatkan pemindaian visual, tetapi selalu menyediakan alternatif teks untuk pengguna VoiceOver. Gunakan pada tampilan gambar, menggambarkan konten video jika memungkinkan.
imageView.isAccessibilityElement = true
imageView.accessibilityLabel = "Thumbnail of video: \(videoTitle)"
Sumber Daya Luaran LUAR
Untuk pengertian yang lebih dalam, berkonsultasilah dengan orang - orang berikut:
- [[GALALT:0]]AVAsetImageGenerator Dokumentasi resmi
- AVAsset Reference
- [[ELAFLT:0]]WWWDC 2019: AVFoundation Performance Tips
Kekecualian Kesimpulan
Membina sebuah generator thumbnail video yang suai dengan AVFoundation memberikan Anda kebebasan penuh atas kualitas gambar, waktu, dan kinerja. Dengan mengulsaging baik secara sinkron maupun asinkron, penanganan kesalahan, dan hasil caching, Anda dapat menyampaikan pengalaman pengguna tanpa jahitan dalam aplikasi iOS Anda. Apakah Anda sedang memproses berkas lokal atau video remote, teknik yang dicakup di sini akan membantu Anda menghasilkan thumbnail yang renyah, konteks ⁇ saware dengan cepat dan efisien.