diff --git a/FFmpegKit b/FFmpegKit index 93b7d1622..dc81e11b2 160000 --- a/FFmpegKit +++ b/FFmpegKit @@ -1 +1 @@ -Subproject commit 93b7d1622a62481c5dae62b1f4f2f361cda76b9f +Subproject commit dc81e11b22d993f6dea1fc9f105d1f0a1e2baa62 diff --git a/Sources/KSPlayer/AVPlayer/PlayerDefines.swift b/Sources/KSPlayer/AVPlayer/PlayerDefines.swift index 7d9abf760..2a77d3e24 100644 --- a/Sources/KSPlayer/AVPlayer/PlayerDefines.swift +++ b/Sources/KSPlayer/AVPlayer/PlayerDefines.swift @@ -273,6 +273,12 @@ extension NSError { userInfo[NSLocalizedDescriptionKey] = errorCode.description self.init(domain: KSPlayerErrorDomain, code: errorCode.rawValue, userInfo: userInfo) } + + convenience init(description: String) { + var userInfo = [String: Any]() + userInfo[NSLocalizedDescriptionKey] = description + self.init(domain: KSPlayerErrorDomain, code: 0, userInfo: userInfo) + } } extension CMTime { diff --git a/Sources/KSPlayer/MEPlayer/ThumbnailController.swift b/Sources/KSPlayer/MEPlayer/ThumbnailController.swift index f5de351ed..8afb78066 100644 --- a/Sources/KSPlayer/MEPlayer/ThumbnailController.swift +++ b/Sources/KSPlayer/MEPlayer/ThumbnailController.swift @@ -28,14 +28,14 @@ public class ThumbnailController { self.thumbnailCount = thumbnailCount } - public func generateThumbnail(for url: URL, thumbWidth: Int32 = 240) async -> [FFThumbnail] { + public func generateThumbnail(for url: URL, thumbWidth: Int32 = 240) async throws -> [FFThumbnail] { let task = Task { - getPeeks(for: url, thumbWidth: thumbWidth) + try getPeeks(for: url, thumbWidth: thumbWidth) } - return await task.value + return try await task.value } - private func getPeeks(for url: URL, thumbWidth: Int32 = 240) -> [FFThumbnail] { + private func getPeeks(for url: URL, thumbWidth: Int32 = 240) throws -> [FFThumbnail] { let urlString: String if url.isFileURL { urlString = url.path @@ -49,11 +49,11 @@ public class ThumbnailController { } var result = avformat_open_input(&formatCtx, urlString, nil, nil) guard result == 0, let formatCtx else { - return [] + throw NSError(errorCode: .formatOpenInput, avErrorCode: result) } result = avformat_find_stream_info(formatCtx, nil) guard result == 0 else { - return [] + throw NSError(errorCode: .formatFindStreamInfo, avErrorCode: result) } var videoStreamIndex = -1 for i in 0 ..< Int32(formatCtx.pointee.nb_streams) { @@ -63,22 +63,19 @@ public class ThumbnailController { } } guard videoStreamIndex >= 0, let videoStream = formatCtx.pointee.streams[videoStreamIndex] else { - return [] + throw NSError(description: "No video stream") } let videoAvgFrameRate = videoStream.pointee.avg_frame_rate if videoAvgFrameRate.den == 0 || av_q2d(videoAvgFrameRate) == 0 { - print("Avg frame rate = 0, ignore") - return [] + throw NSError(description: "Avg frame rate = 0, ignore") } - var codecContext = try? videoStream.pointee.codecpar.pointee.createContext(options: nil) + var codecContext = try videoStream.pointee.codecpar.pointee.createContext(options: nil) defer { avcodec_close(codecContext) + var codecContext: UnsafeMutablePointer? = codecContext avcodec_free_context(&codecContext) } - guard let codecContext else { - return [] - } let thumbHeight = thumbWidth * codecContext.pointee.height / codecContext.pointee.width let reScale = VideoSwresample(dstWidth: thumbWidth, dstHeight: thumbHeight, isDovi: false) // let duration = formatCtx.pointee.duration @@ -93,7 +90,7 @@ public class ThumbnailController { av_frame_free(&frame) } guard let frame else { - return [] + throw NSError(description: "can not av_frame_alloc") } for i in 0 ... thumbnailCount { let seek_pos = interval * Int64(i) + videoStream.pointee.start_time