Hình thu nhỏ phim là nền tảng của ứng dụng giàu phương tiện hiện đại, cung cấp cho người dùng một ô xem thử nhanh chóng mà không cần mở toàn bộ video. Trong phát triển iOS, khả năng phát triển AVFzzing cung cấp các công cụ dễ dàng và linh hoạt nhất để trích xuất ảnh mẫu ảnh. Bài này đi qua việc tạo ra một máy phát điện ảnh mẫu ảnh tự chọn mà có thể xử lý các kịch bản thực- bao gồm các tập tin cục bộ và từ xa, kéo dài, xử lý lỗi, xử lý và hiệu suất hiệu suất sử dụng (dùng hệ thống gỡ lỗi) và AFzzing (dùng hệ thống).

Hiểu vai trò của AVFzzation trong thế hệ mẫu ảnh

AVFzzation là cơ sở chính của Apple để làm việc với phương tiện truyền thông âm thanh. Đối với thế hệ mẫu ảnh, các hạng khóa là AVAT ) AVB đặt tên ).

  • AVAAAAVAAcset ): đại diện cho tài sản âm thanh có thời gian (một video địa phương hay từ xa). Nó chứa thông tin theo dõi, thời gian và siêu dữ liệu.
  • AVASsetImagegenator [FLT: 1]]: Cung cấp phương pháp để lấy CGIageRefs từ tài sản tại thời điểm cụ thể. Nó tôn trọng định hướng video, áp dụng các điều chỉnh không gian màu, và hỗ trợ thế hệ số đại diện arychiron.

Dùng trực tiếp những lớp này sẽ giúp bạn kiểm soát hoàn toàn kích thước ảnh, độ chính xác thời gian và sự chuyển đổi, không giống như cách gõ tắt UIKit thường ẩn các tùy chọn cấu hình.

Thiết lập dự án

Bắt đầu bằng việc nhập AVFzzation vào tập tin « Xoá » của bạn:

import AVFoundation

Bạn cũng cần UIKit để hiển thị các ảnh đã tạo. Tạo một [FLT: 1] từ địa phương. Để tìm tập tin . Để hiển thị các video ở xa, hãy dùng [[FLT:] để đảm bảo tài sản có thể khởi tạo:

// 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)

Tạo ra một mẫu ảnh đơn

Để tạo ra một mẫu ảnh vào lúc đã xác định, hãy tạo một và gọi . Phương pháp này đồng bộ hoá và nên chạy ra khỏi chỉ mục chính để tránh chặn 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)")
}

Người dịch:[FLT: 1] Thiết lập để đảm bảo kết quả là ảnh tôn trọng siêu dữ liệu quay của video (FLrait v. Bức tranh). Không có điều này, một video thẳng có thể xuất hiện sang một bên.

Chọn đúng lúc

Các mẫu ảnh thường được chụp ở đầu một video, nhưng hãy xem xét thời gian biểu thị nội dung của nội dung, 10% vào thời gian.

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

Lỗi xử lý và trường hợp cạnh

Thế hệ mẫu ảnh có thể thất bại vì một số lý do. Luôn luôn xử lý lỗi một cách duyên dáng và cung cấp uI sao lưu.

  • Tài sản invald:) video có thể bị hỏng hoặc không thể truy cập được.
  • Theo dõi video: một số tài sản chỉ chứa âm thanh; kiểm tra .
  • Thời gian ngoài giới hạn: ) Hãy chắc chắn thời gian đã yêu cầu là giữa và thời gian của tài sản.
  • lỗi mạng: tài sản từ xa có thể không tải. Hãy dùng trước khi tạo ra các mẫu ảnh.

Ví dụ về tài sản nạp trước:

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
 }
}

Tùy chỉnh kết xuất mẫu ảnh

AVAsesetImage Gentor đưa ra một số thuộc tính để tinh chỉnh hình ảnh xuất.

Cỡ tối đa

Giới hạn ảnh được tạo ra thành một hộp đặc biệt dùng . Tính năng này giảm bộ nhớ trên đầu và tăng tốc độ cho ảnh động lớn.

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

Những hình ảnh được tạo ra sẽ được co giãn để phù hợp với các chiều không gian trong khi bảo tồn tỷ lệ hình thể.

Yêu cầu thời gian khoan dung

Theo mặc định, trả lại khung chính xác vào thời gian đã yêu cầu (hoặc gần nhất có thể). Bạn có thể trao đổi độ chính xác để chạy và . Đối với mẫu ảnh, sự khoan dung của 0.5 giây thường được chấp nhận và nhanh hơn:

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

Chế độ mở rộng

kiểm soát cách mà hình ảnh được tạo ra xử lý sự mở rộng sạch sẽ chống lại các vết nứt. Hãy dùng để gỡ bỏ bụi rìa và tạo ra hình thu nhỏ sạch hơn:

imageGenerator.apertureMode = .cleanAperture

Áp dụng biến hình

Nếu bạn cần xoay hay lật ảnh (v. d. để có một hướng cụ thể), hãy dùng đồ họa lõi. Một cách là chụp ảnh thô, rồi dùng một hình ảnh kiểu CGAffineTransform (v. d., bạn có thể đặt để (như được hiển thị) và tin tưởng vào định hướng tự nhiên của tài sản.

Tạo ra nhiều mẫu ảnh dễ dàng

Để làm lưới phim, lau dọn dòng thời gian, hoặc xem thử bảng vẽ, bạn thường cần hàng chục mẫu ảnh. Tránh gọi trong vòng lặp chính. Thay vào đó, hãy dùng phương pháp asynnron . Nó xử lý nhiều yêu cầu thời gian một cách hiệu quả, điều khiển tính song song nội.

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")")
 }
}

Phương pháp này cân bằng và cho bạn cập nhật UI dần. Hãy nhớ gọi nếu người dùng để lại màn hình cho tài nguyên rảnh.

Làm việc với các video từ xa

Khi địa chỉ Mạng video chỉ tới máy phục vụ ở xa, bạn cần đợi tài sản được nạp đầy đủ hoặc ít nhất là thông tin theo dõi cần có. Hãy dùng với những tiêu đề thích hợp để tránh tải về.

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

Để dùng ứng dụng sản xuất, hãy xem xét các mẫu ảnh lưu tạm trên đĩa để truy cập nhiều lần vào cùng một video không được mở lại ảnh. Hãy dùng hoặc tập tin bên dưới tập tin dùng địa chỉ Mạng video như là một phím.

Gương mẫu chiến đấu khắc nghiệt

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)
 }
}

Kết hợp điều này với máy phát ảnh để tránh làm việc thừa.

Xem xét hiệu suất

Tạo ra mẫu ảnh là một thao tác CPU tăng cường, đặc biệt là cho các video có độ phân giải cao 4K. Hãy theo dõi các thực hành tốt nhất:

  • Luôn luôn thực hiện cuộc gọi đồng bộ trên hàng đợi nền (v. d., .
  • Đặt một hợp lý để giảm kích cỡ ảnh xuất. Kích cỡ 320x240 thường đủ cho danh sách các mẫu ảnh.
  • Dùng để cho phép máy phát điện bỏ qua khung gần nhất thay vì giải mã chính xác.
  • Hủy bỏ bất kỳ thế hệ tự do phóng túng nào khi khung cảnh biến mất.
  • Để hiển thị trong ô xem tập hợp, hãy tạo ra các mẫu ảnh ở đúng kích cỡ tế bào và tránh thay đổi kích cỡ của sợi chính.

Hợp nhất với cấu trúc của máy tính (Async/Awai)

Nếu mục tiêu ứng dụng của bạn iOS 15+, bạn có thể kết thúc cuộc gọi chặn trong một tiếp tục cho một mã số rõ ràng/chờ đợi:

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)
 }
 }
 }
}

Tùy chỉnh cấp cao

Mô phỏng phim ảnh độngName

Nếu video của bạn dùng (v. d., dấu thủy ấn bao gồm, điều chỉnh màu), bạn có thể truyền nó cho bộ tạo ảnh:

imageGenerator.videoComposition = myVideoComposition

Hình thu nhỏ được tạo ra sẽ phản ánh kết xuất đã được tổng hợp.

Đang tạo ra các mẫu ảnh cho các ảnh sống

Ảnh trực tiếp là sự kết hợp của một video và một ảnh vẫn còn. Để trích xuất một mẫu ảnh từ video ẩn, hãy dùng và yêu cầu một địa chỉ Mạng video trước khi đưa nó vào AVzzation.

Khả năng truy cập và kinh nghiệm người dùng

Hình thu nhỏ tô sáng hình ảnh, nhưng luôn luôn cung cấp một thay thế văn bản cho người dùng qua tiếng nói. Hãy dùng trên ô xem ảnh, miêu tả nội dung của đoạn phim nếu có thể.

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

Tài nguyên bên ngoài

Để hiểu biết sâu sắc hơn, hãy tham khảo những điều sau:

Kết luận

Xây dựng một máy phát ảnh mẫu tự chọn với khả năng đính kèm AVFS cho bạn sự tự do hoàn toàn qua chất lượng ảnh, thời gian và hiệu suất. Bằng cách sử dụng cả hai kỹ thuật được bao gồm ở đây sẽ giúp bạn tạo ra các hình thu nhỏ mảnh mai, xử lý các lỗi thời gian, và kết quả ngứa, bạn có thể cung cấp một kinh nghiệm không giới hạn cho người dùng trong ứng dụng iOS của bạn. Dù bạn đang xử lý tập tin hay từ xa, các kỹ thuật được bao gồm ở đây sẽ giúp bạn tạo ra hình thu nhỏ gọn gàng, cấu hình ngữ cảnh đơn giản và hiệu quả.