الهندسة المدنية والهيكلية
إنشاء مولدات فيديو تومبنايل في إيوس مع إفتراض
Table of Contents
وتشكل اصابع الفيديو حجر الزاوية في التطبيقات الحديثة الغنية بوسائط الإعلام، وتوفر للمستعملين فرصة سريعة للتصوير البصري دون الحاجة إلى تشغيل الفيديو الكامل، وفي تطوير نظام المراقبة الجوية، توفر شبكة " AVFoundation " أكثر الأدوات أداء ومرنة لاستخراج صور الإبهام، وتسير هذه المادة من خلال بناء مولد للفيديو ذي الصوت العادي الذي يمكن أن يعالج سيناريوهات العالم الحقيقي - بما في ذلك الأخطاء المحلية والنائية.
فهم دور المؤسسة في توليد الإبهام
AVFoundation is Apple’s primary framework for working with audiovisual media. For thumbnail generation, the key classes are AVAsset] and ]AVAssetImageGenerator.
- AVAsset]: يمثل أصلاً سمعياً بصرياً موقوتاً (فيديو محلي أو عن بعد)، ويتضمن معلومات عن المسارات ومدتها وبيانات مائية.
- AVAssetImageGenerator: Provides methods to obtain CGImageRefs from the asset at specific time intervals. It respects video orientation, applies colour space adjustments, and supports asynchronous bulk generation.
استخدام هذه الفصول يعطيك التحكم الكامل في حجم الصور، دقة الوقت، والتحول، على عكس طرق اختصار UIKit التي كثيرا ما تخفي خيارات التشكيل.
وضع المشروع
ابدأ باستيراد اي فيوند الى ملفك سويفت
import AVFoundation
كما تحتاج إلى وحدة تسجيل المواقع لعرض الصور المولدة. () إنشاء جهاز () من وحدة URL. (E) للملفات المحلية، استخدام ) في الفيديو البعيد، استخدام وضمان إمكانية الاستدلال في الأصل:
// 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)
تولد إبهام واحد
To generate one thumbnail at a specified time, create an and call . This method is coincidehronous and should be run off the main thread to avoid blocking the 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)")
}
Important:] Setting to ensures the resulting image respects the video’s circulation metadata (portrait vs. landscape). Without this, an upright video might appear sideways.
اختيار الوقت المناسب
وكثيراً ما تؤخذ الإبهامات في بداية شريط فيديو، ولكنها تنظر في استخدام وقت يمثل المحتوى - أي بنسبة 10 في المائة على سبيل المثال - في المدة، ولتحديد نقطة زمنية معقولة، وتساءل عن مدة الموجودات:
let duration = asset.duration
let midTime = CMTimeMultiplyByFloat64(duration, multiplier: 0.1)
معالجة قضايا الإغراق والدج
توليد الإبهام يمكن أن يفشل لعدة أسباب، دائماً ما يتعامل مع الأخطاء بشكل جيد ويعطي اللوم الفوقية.
- Invalid asset:] The video may be corrupted or the URL unreachable.
- Missing video track:] Some assets contain only audio; check .
- Time out of bounds:] Ensure the requested time is between and the asset’s duration.
- Network errors:] Remote assets may fail to load. Use before generating thumbnails.
مثال على خصائص الأصول المُحمّلة مسبقاً:
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
}
}
الناتج المحلي الإجمالي
وتقدم شركة AVAssetImageGenerator عدة خصائص لضبط صورة الناتج.
الحد الأقصى للحجم
(ب) تقييد الصورة المولدة إلى صندوق محدد ملزِم باستخدام [(FLT:15]) مما يقلل من رأس الذاكرة ويسرع في توليد أشرطة فيديو كبيرة.
imageGenerator.maximumSize = CGSize(width: 640, height: 480)
وسيتم توسيع الصورة المولدة بحيث تناسب هذه الأبعاد مع الحفاظ على نسبة الجانب.
التسامح مع الوقت المطلوب
وبحسب التقصير، ] تعيد الإطار الدقيق في الوقت المطلوب (أو أقرب وقت ممكن) ويمكنك أن تتبادل الدقة من أجل تحديد السرعة و. وبالنسبة للإبهام، فإن التسامح لمدة 0.5 ثانية غالبا ما يكون مقبولا وسريعا:
imageGenerator.requestedTimeToleranceBefore = CMTime(seconds: 0.5, preferredTimescale: 600)
imageGenerator.requestedTimeToleranceAfter = CMTime(seconds: 0.5, preferredTimescale: 600)
طريقة الإنجاز
يتحكم في كيفية معالجة الصور المولدة للفتحات النظيفة ضد منشار الإنتاج.
imageGenerator.apertureMode = .cleanAperture
تطبيق التحولات
وإذا ما احتجتم إلى تناوب الصورة أو قلبها (مثلاً، لأغراض توجيه محدد)، استخدموا التحولات في الصور الفلكية الأساسية، ويتمثل أحد النهجين في استخلاص الصورة الخام ثم تطبيق نموذج CGAffineTransformly، وكبديل لذلك، يمكنكم وضع (على النحو المبين) والثقة في التوجه الطبيعي للأصول.
توليد الإبهام المتعددة الأصابع بكفاءة
وفيما يتعلق بشبكات الفيديو، أو بخطوط التسلسل الزمني، أو استعراضات المواهب، كثيرا ما تحتاج إلى عشرات من الإبهام، وتتجنب الاتصال في حلقة عن الخيط الرئيسي، بل تستخدم الطريقة المتناغمة ، وتعالج الطلبات المتعددة من الزمن بكفاءة، وترفع التوازي الداخلي.
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")")
}
}
وتُعد هذه الطريقة على نطاق واسع وتسمح لك بتحديث مذكرة التفاهم بصورة تدريجية، تذكر أن تتصل إذا ترك المستخدم الشاشة أمام الموارد الحرة.
العمل مع الفيديو اللوثري
وعندما يشير الفيديو إلى خادم نائي، يجب أن تنتظروا أن تكون هذه الأصول محمّلة بالكامل أو على الأقل معلوماتها عن المسار متاحة، وأن تستخدموا مع رؤساء التعبئة المناسبين لتجنب عمليات التنزيل المتكررة.
let urlAsset = AVURLAsset(url: remoteURL, options: [AVURLAssetPreferPreciseDurationAndTimingKey: true])
urlAsset.loadValuesAsynchronously(forKeys: ["tracks"]) {
// Then create image generator and proceed
}
For production apps, consider caching thumbnails on disk so that repeated access to the same video does not re-fetch the image. Use or file —based cache using the video URL as a key.
نموذج استراتيجية الاختطاف
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)
}
}
جهز هذا مع المولد للصور لتتجنب العمل الزائد
اعتبارات الأداء
إن إنتاج الإبهام عملية كثيفة للغاية في وحدة مكافحة الإرهاب، لا سيما بالنسبة للفيديو العالي الاستبانة 4K.
- () أن تقوم دائماً بإجراء نداءات متزامنة على أساس منعطف خلفي (مثلاً، ).
- (ب) تحديد معقول لخفض أبعاد صور النواتج، وكثيراً ما يكفي حجم 320x240 للقوائم.
- Use to allow the electricity to exceed the nearest frame instead of solving the exact decode.
- ألغي أي جيل من الجيل المُتَعَدّد عندما يختفي المنظر
- وللاطلاع على العرض في صورة جمع، يولد الإبهام بحجم الزنزانة بالضبط ويتجنب إعادة التثبيت على الخيط الرئيسي.
إدماج عملة سويفت (الدائرة/الانتظار)
إذا كان تطبيقك يستهدف "أي إس 15" بعد ذلك يمكنك أن تلف النداء المانع في الاستمرار في النسيج النظيف
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] وطلب شريط فيديو قبل إطعامه إلى محطة AVoundation.
إمكانية الوصول والخبرة في مجال المستعملين
ويعزز الإبهام المسح البصري، ولكنه يوفر دائماً بديلاً للمستعملين الصوتيين، ويستخدم على مشهد الصور، ويصف محتوى الفيديو إن أمكن.
imageView.isAccessibilityElement = true
imageView.accessibilityLabel = "Thumbnail of video: \(videoTitle)"
الموارد الخارجية
وللتوصل إلى فهم أعمق، يرجى الرجوع إلى ما يلي:
- AVAssetImageGenerator Official Documentation]
- AVAsset Reference]
- WDC 2019: AVFoundation Performance Tips]
خاتمة
وببناء مولد للفيديو مع شبكة AVFoundation، يمنحك الحرية الكاملة عن نوعية الصور وتوقيتها وأدائها، وبإطلاق النار بكل من المتزامنة والفظاعة، ومناولة الأخطاء ونتائج الماشية، يمكنك أن تقدم خبرة مستعملة لا تحصى في جهازك الإلكتروني، وسواء كنت تجهز الملفات المحلية أو أشرطة الفيديو النائية، فإن التقنيات المشمولة هنا ستساعدك على إنتاجها.