ภาพตัวอย่าง คือกรอบหลักของโปรแกรมที่อุดมไปด้วยสื่อสมัยใหม่ โดยให้ผู้ใช้แสดงตัวอย่างอย่างรวดเร็ว โดยไม่ต้องเล่นวิดีโอเต็ม ๆ การจัดการระบบ ISOS การขยายภาพ ISVFOD นี้จะให้เครื่องมือที่มีประสิทธิภาพมากที่สุดและยืดหยุ่นในการสกัดภาพต่าง ๆ บทความนี้เดินผ่านการสร้างวิดีโอภาพตัวอย่างที่กําหนดเอง ซึ่งสามารถจัดการสถานการณ์จริงได้ทั้งในท้องถิ่นและระยะไกล รวมถึงแฟ้มต่าง ๆ , การจับสัญญาณ, การจับสัญญาณ, และการทํางานแบบเร็ว — การใช้ภาพแบบเร็วและง่ายและง่าย

การ เข้าใจ บทบาท ของ ผู้ คน ใน การ สืบ พันธุ์ ของ ภาพตัวอย่าง

AVFOODE เป็นโครง คุณศัพท์หลักของแอปเปิล สําหรับการทํางานร่วมกับสื่อเกี่ยวกับเสียง สําหรับรุ่นของภาพตัวอย่าง คลาสหลักคือ [FLT: 0] AVASSets (FLT:1) และ ASESTIMEEGGEGEGEGE (FLT:3].

  • [FLT: 0] AVASet : เป็นตัวแทนของสินทรัพย์ทางเสียงแบบเวลา (วิดีโอท้องถิ่นหรือวิดีโอระยะไกล) มีข้อมูลเพลง, ช่วงเวลา และข้อมูลกํากับ (อังกฤษ: Augusty).
  • [FLT: 0] AVASEIGGEGEGEGEEGEEPEST [FLT: 1]: จัดหาวิธีการรับอาหารจากสินทรัพย์ในระยะเวลาเฉพาะตัว แสดงถึงการจัดอันดับวิดีโอ, ปรับใช้การปรับเปลี่ยนขอบเขตสี และรองรับการเรียงลําดับของกลุ่มย่อยที่มีขนาดใหญ่

การใช้คลาสเหล่านี้โดยตรง ช่วยให้คุณควบคุมขนาดภาพ, ความแม่นยําของเวลา, และการเปลี่ยนแปลงได้อย่างเต็มที่ ไม่เหมือนกับทางลัดยูไอคิตที่มักซ่อนตัวเลือกในการปรับแต่ง

กําลังตั้งค่าโครงการ

เริ่มจากการนําเข้าข้อมูล AVFOWDDDODDS เข้าแฟ้มของคุณ:

import AVFoundation

คุณยังต้องการ UIKit เพื่อแสดงภาพที่สร้างขึ้นมาด้วย สร้าง จากที่อยู่ URL สําหรับแฟ้มภายในระบบ ให้ใช้แฟ้ม สําหรับวิดีโอระยะไกล ให้ใช้ [FLT: 3] และแน่ใจว่าทรัพย์สินสามารถถูกเรียกใช้งานได้:

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

กําลังสร้างภาพตัวอย่างแบบเดี่ยว

เพื่อสร้างภาพตัวอย่างหนึ่งตัวในเวลาที่ระบุ ให้สร้าง [FLT: 5] และเรียก [FLT: 6] วิธีการนี้จะทําการปรับเทียบข้อมูล และควรจะเรียกปิดเธรดหลักเพื่อป้องกันการปิดกั้น 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)")
}

[FLT: 0] ) รองรับ การวาง [FLT: 8] [FLT: ⁇ มั่นใจภาพประกอบที่แสดงในภาพ กํากับการหมุนวิดีโอ (port vs) ถ้าไม่มีวิดีโอนี้ วีดีโอแบบตรงอาจปรากฎด้านข้าง

เลือก เวลา ที่ เหมาะ

ภาพตัวอย่างมักจะถ่ายจากตอนต้นวิดีโอ แต่ลองพิจารณาใช้เวลาที่แสดงถึงเนื้อหา -- เช่น 10% ในระยะยาว เพื่อค้นหาเวลาที่มีความหมาย ให้สอบถามช่วงเวลาของสินทรัพย์:

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

การ จัด การ กับ ข้อ ผิด พลาด และ กรณี ที่ ตรง ด้าน

คน รุ่น ภาพตัวอย่าง อาจ พลาด ได้ หลาย อย่าง.

  • [FLT: 0] สินทรัพย์ไร้ความสามารถ: วิดีโออาจเสียหาย หรือที่อยู่ URL ไม่สามารถติดต่อได้
  • [FLT: 0]. Missing มิวสิกแทร็ค: ทรัพย์สินบางอย่างมีเสียงอย่างเดียว; เช็ค .
  • [FLT: 0] เวลานอกขอบเขต : แน่ใจว่าเวลาที่ต้องการอยู่ระหว่าง [FLT: 12] กับระยะเวลาสินทรัพย์ (FT:12).
  • [FLT: 0] มีข้อผิดพลาด: ทรัพย์สินระยะไกลอาจจะล้มเหลวในการโหลด โปรดใช้[FLT: 13] ก่อนสร้างภาพตัวอย่าง

ตัวอย่างของสินทรัพย์ที่โหลดล่วงหน้า:

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

ปรับแต่งการแสดงผลการแสดงผลตัวอย่างของภาพตัวอย่าง

AVASetIGEGenerator มีคุณสมบัติหลาย ๆ อย่าง เพื่อปรับภาพผลลัพธ์ของภาพให้ดี

ขนาดสูงสุด

จํากัดการสร้างภาพเป็นกล่องขอบเฉพาะโดยใช้ [FLT: 15] ซึ่งจะช่วยลดค่าความจําและความเร็วของรุ่นสําหรับวิดีโอขนาดใหญ่

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

ภาพที่ถูกสร้างจะถูกปรับขนาดให้พอดีภายในมิติเหล่านี้ โดยยังคงรักษาสัดส่วนภาพไว้ด้วย

การ ยืดหยุ่น เวลา ที่ ต้องการ

โดยปริยายแล้ว [FLT: 17] จะคืนค่ากลับมาเป็นเฟรมที่ถูกต้องตามเวลาที่ต้องการ (หรือใกล้ที่สุด) คุณสามารถแลกเปลี่ยนความถูกต้องของความเร็วได้โดยตั้งค่า [FLT: 18] และ. สําหรับภาพตัวอย่าง, การยอมรับ 0.5 วินาทีนั้นมักเป็นที่ยอมรับและเร็วขึ้น:

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

โหมดการกระพุ้ง

[FLT: 21] ควบคุมวิธีการสร้างภาพ ด้วยการจัดการรูรับแสงแบบขาวสะอาด (failT: 22) ใช้ [FLT: 22] เพื่อกําจัดฝุ่นขอบและสร้างภาพตัวอย่างที่สะอาด:

imageGenerator.apertureMode = .cleanAperture

กําลังปรับใช้การแปลง

หากคุณต้องการหมุนภาพหรือพลิกภาพ (เช่น การจัดวาง) ใช้ภาพแบบ Core Photographics วิธีการหนึ่งคือการจับภาพดิบ และใช้ CGAFFFIFTransphorm ด้วยตัวเอง คุณสามารถตั้งค่า [FLT: 24] ให้ [FTT:25] และไว้วางใจการวางจําหน่ายโดยธรรมชาติของสินทรัพย์ได้โดยปกติ

การ ผนวก ตัว อย่าง หลาย ตัว อย่าง เป็น ไป ได้

สําหรับเส้นกริด, การปรับเส้นเวลา, หรือการปรับเส้นเวลา คุณมักต้องใช้ภาพตัวอย่างหลายสิบชิ้น หลีกเลี่ยงการเรียก ในวนรอบของเธรดหลัก แทนการใช้วิธีการแบบย่อ (FLT: 27) ซึ่งจะประมวลผลการขอแบบเส้นขนานภายในอย่างมีประสิทธิภาพหลายครั้ง

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

วิธีการนี้ จะทําการปรับปรุงข้อมูล UI ได้อย่างดี โปรดจํา[FLT: 29] หากผู้ใช้ออกจากหน้าจอไปยังทรัพยากรเสรี

ทํางานกับวิดีโอทางไกล

เมื่อที่อยู่ URL วิดีโอชี้ไปยังเซิร์ฟเวอร์ทางไกล คุณจะต้องรอให้มีการใช้งานข้อมูล สินทรัพย์อย่างเต็มที่ หรืออย่างน้อยก็โหลดข้อมูลเพลงของมันให้ใช้งานได้ ใช้ [FLT: 30] ด้วย cacking headers ที่เหมาะสมเพื่อหลีกเลี่ยงการดาวน์โหลดซ้ํา

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

สําหรับโปรแกรมผลิต โปรดพิจารณาการจับภาพตัวอย่างบนดิสก์ เพื่อให้การเข้าใช้วิดีโอซ้ําไม่ได้ทําให้ภาพกลับมาใช้ได้อีกครั้ง ใช้ หรือแคชแบบแฟ้มแบบแฟ้มแบบเติมข้อมูล โดยใช้ที่อยู่ URL ของวิดีโอเป็นกุญแจ

ตัวอย่างการจับเครื่อง

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

ผนวกนี่เข้ากับเครื่องกําเนิดภาพเพื่อหลีกเลี่ยงการทํางานซ้ําซ้อน

การพิจารณาผลงาน

การขยายภาพตัวอย่างเป็นปฏิบัติการของ CPU(CPU) กับปริมาณที่มาก โดยเฉพาะสําหรับวิดีโอ 4K ที่มีการปรับเปลี่ยนสูง

  • มักจะทําการโทรแบบประสานบนคิวหลัง (เช่น [FLT: 34].
  • ตั้งค่าความละเอียด [FLT: 35] เพื่อลดมิติของภาพที่ส่งออก ขนาด 320x240 มักเหมาะกับรายการภาพตัวอย่าง
  • ใช้ [FLT: 36] เพื่ออนุญาตให้เครื่องกําเนิดพลังงานข้ามเฟรมที่ใกล้ที่สุด แทนที่จะแก้รหัสที่แน่นอน
  • ยกเลิกรุ่นที่โตมากๆ เมื่อมุมมองหายไป
  • สําหรับแสดงผลในมุมมองคลังสื่อ ให้สร้างภาพตัวอย่างที่มีขนาดเซลล์ที่แม่นยํา และหลีกเลี่ยงการปรับขนาดบนเธรดหลัก

เข้าร่วมด้วยความไวต์คอนคอร์เรชัน (Asinc/Awank warn)

หากโปรแกรมของคุณกําหนด OS 15+ คุณสามารถตัดการโทรแบบบล็อกใน recurrent สําหรับรหัส Aync/ awaite ที่สะอาด:

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

การปรับแต่งขั้นสูง

ภาพตัวอย่างที่มีการจัดรูปแบบวิดีโอ

ถ้าวิดีโอของคุณใช้ (เช่น เคลือบด้วยน้ํา ปรับสี) คุณสามารถส่งต่อมันไปยังเครื่องกําเนิดภาพ:

imageGenerator.videoComposition = myVideoComposition

ภาพตัวอย่างที่ถูกสร้าง จะสะท้อนผลลัพธ์ที่ประกอบขึ้น

กําลังสร้างภาพตัวอย่างสําหรับภาพแบบมีชีวิต

ภาพแบบสดๆ คือ การรวมกันของวิดีโอและภาพ ภาพ เพื่อดึงภาพตัวอย่างออกมาจากวิดีโอหลัก ให้ใช้ [FLT: 40] และร้องขอที่อยู่ URL วิดีโอ ก่อนที่จะป้อนเข้าไปใน AVFOOD

การ ช่วย ให้ เข้า ถึง ได้ ง่าย และ ประสบการณ์ ของ ผู้ ใช้

ภาพตัวอย่างจะปรับปรุงการสแกนภาพ แต่มักจะให้ข้อความทางเลือกสําหรับผู้ใช้เสียงแบบ [FLT: 41] บนมุมมองภาพ โดยอธิบายเนื้อหาวิดีโอหากเป็นไปได้

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

ทรัพยากรภายนอก

เพื่อ จะ เข้าใจ ลึก ซึ้ง ยิ่ง ขึ้น ขอ พิจารณา สิ่ง ต่อ ไป นี้:

  • [FLT: 0] VAASESTIGEGEERAGEERatorator เอกสารอย่างเป็นทางการ
  • [FLT: 0] AVASet Tele [FLT: 1]
  • [FLT: 0] WWDC 2019: AVFOUNDDDODDS TIFE THE [FLT: 0]

รูปแบบการวน

การสร้างเครื่องสร้างภาพตัวอย่างที่กําหนดเองด้วย AVFOODDDIF ช่วยให้คุณมีเสรีภาพเต็มที่เหนือคุณภาพ, เวลา, และประสิทธิภาพ โดยการหมุน ทั้งแบบพร้อมเพรียงและแบบไวต่อเสียง, การจัดการข้อผิดพลาด, และผลการจับสัญญาณ คุณจะสามารถส่งมอบประสบการณ์ที่ไม่สามารถจัดการได้โดยผู้ใช้ไม่สามารถทํางานได้โดยสมบูรณ์ในโปรแกรม OS ของคุณ ไม่ว่าคุณจะกําลังประมวลผลแฟ้มหรือวิดีโอท้องถิ่นนี้ จะช่วยให้คุณสามารถผลิตภาพได้ง่ายขึ้น, แจ้งให้ทราบล่วงหน้า และมีประสิทธิภาพสูง