wake-ios/wake/Utils/MediaUtils.swift
2025-08-22 18:58:08 +08:00

85 lines
3.4 KiB
Swift
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import AVFoundation
import UIKit
import os.log
///
enum MediaUtils {
private static let logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "com.example.app", category: "MediaUtils")
/// URL
/// - Parameters:
/// - videoURL: URL
/// - completion: UIImage
static func extractFirstFrame(from videoURL: URL, completion: @escaping (Result<UIImage, Error>) -> Void) {
let asset = AVURLAsset(url: videoURL)
let assetImgGenerate = AVAssetImageGenerator(asset: asset)
assetImgGenerate.appliesPreferredTrackTransform = true
//
let duration = asset.duration
let durationTime = CMTimeGetSeconds(duration)
// 0
guard durationTime > 0 else {
let error = NSError(domain: "com.yourapp.media", code: -1, userInfo: [NSLocalizedDescriptionKey: "Invalid video duration"])
completion(.failure(error))
return
}
// 0
let time = CMTime(seconds: 0, preferredTimescale: 600)
//
assetImgGenerate.generateCGImagesAsynchronously(forTimes: [NSValue(time: time)]) { (_, cgImage, _, result, error) in
if let error = error {
logger.error("Failed to generate image: \(error.localizedDescription)")
DispatchQueue.main.async {
completion(.failure(error))
}
return
}
guard result == .succeeded, let cgImage = cgImage else {
let error = NSError(domain: "com.yourapp.media", code: -2, userInfo: [NSLocalizedDescriptionKey: "Failed to generate image from video"])
logger.error("Failed to generate image: \(error.localizedDescription)")
DispatchQueue.main.async {
completion(.failure(error))
}
return
}
// UIImage
let image = UIImage(cgImage: cgImage)
DispatchQueue.main.async {
completion(.success(image))
}
}
}
///
/// - Parameters:
/// - videoData:
/// - completion: UIImage
static func extractFirstFrame(from videoData: Data, completion: @escaping (Result<UIImage, Error>) -> Void) {
// URL
let tempDirectoryURL = FileManager.default.temporaryDirectory
let fileName = "tempVideo_\(UUID().uuidString).mov"
let fileURL = tempDirectoryURL.appendingPathComponent(fileName)
do {
//
try videoData.write(to: fileURL)
// URL
extractFirstFrame(from: fileURL) { result in
//
try? FileManager.default.removeItem(at: fileURL)
completion(result)
}
} catch {
logger.error("Failed to write video data to temporary file: \(error.localizedDescription)")
completion(.failure(error))
}
}
}