mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Use asynchronous thumbnail generation for round videos
This commit is contained in:
parent
bcfb9a969d
commit
2bbb9fd1f3
@ -1508,78 +1508,97 @@ public class VideoMessageCameraScreen: ViewController {
|
|||||||
|
|
||||||
let dimensions = PixelDimensions(width: 400, height: 400)
|
let dimensions = PixelDimensions(width: 400, height: 400)
|
||||||
|
|
||||||
var thumbnailImage = video.thumbnail
|
let thumbnailImage: Signal<UIImage, NoError>
|
||||||
if startTime > 0.0 {
|
if startTime > 0.0 {
|
||||||
let composition = composition(with: results)
|
thumbnailImage = Signal { subscriber in
|
||||||
let imageGenerator = AVAssetImageGenerator(asset: composition)
|
let composition = composition(with: results)
|
||||||
imageGenerator.maximumSize = dimensions.cgSize
|
let imageGenerator = AVAssetImageGenerator(asset: composition)
|
||||||
imageGenerator.appliesPreferredTrackTransform = true
|
imageGenerator.maximumSize = dimensions.cgSize
|
||||||
|
imageGenerator.appliesPreferredTrackTransform = true
|
||||||
|
|
||||||
if let cgImage = try? imageGenerator.copyCGImage(at: CMTime(seconds: startTime, preferredTimescale: composition.duration.timescale), actualTime: nil) {
|
imageGenerator.generateCGImagesAsynchronously(forTimes: [NSValue(time: CMTime(seconds: startTime, preferredTimescale: composition.duration.timescale))], completionHandler: { _, image, _, _, _ in
|
||||||
thumbnailImage = UIImage(cgImage: cgImage)
|
if let image {
|
||||||
|
subscriber.putNext(UIImage(cgImage: image))
|
||||||
|
} else {
|
||||||
|
subscriber.putNext(video.thumbnail)
|
||||||
|
}
|
||||||
|
subscriber.putCompletion()
|
||||||
|
})
|
||||||
|
|
||||||
|
return ActionDisposable {
|
||||||
|
imageGenerator.cancelAllCGImageGeneration()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
let values = MediaEditorValues(peerId: self.context.account.peerId, originalDimensions: dimensions, cropOffset: .zero, cropRect: CGRect(origin: .zero, size: dimensions.cgSize), cropScale: 1.0, cropRotation: 0.0, cropMirroring: false, cropOrientation: nil, gradientColors: nil, videoTrimRange: self.node.previewState?.trimRange, videoIsMuted: false, videoIsFullHd: false, videoIsMirrored: false, videoVolume: nil, additionalVideoPath: nil, additionalVideoIsDual: false, additionalVideoPosition: nil, additionalVideoScale: nil, additionalVideoRotation: nil, additionalVideoPositionChanges: [], additionalVideoTrimRange: nil, additionalVideoOffset: nil, additionalVideoVolume: nil, nightTheme: false, drawing: nil, entities: [], toolValues: [:], audioTrack: nil, audioTrackTrimRange: nil, audioTrackOffset: nil, audioTrackVolume: nil, audioTrackSamples: nil, qualityPreset: .videoMessage)
|
|
||||||
|
|
||||||
var resourceAdjustments: VideoMediaResourceAdjustments? = nil
|
|
||||||
if let valuesData = try? JSONEncoder().encode(values) {
|
|
||||||
let data = MemoryBuffer(data: valuesData)
|
|
||||||
let digest = MemoryBuffer(data: data.md5Digest())
|
|
||||||
resourceAdjustments = VideoMediaResourceAdjustments(data: data, digest: digest, isStory: false)
|
|
||||||
}
|
|
||||||
|
|
||||||
let resource: TelegramMediaResource
|
|
||||||
let liveUploadData: LegacyLiveUploadInterfaceResult?
|
|
||||||
if let current = self.node.currentLiveUploadData {
|
|
||||||
liveUploadData = current
|
|
||||||
} else {
|
} else {
|
||||||
liveUploadData = self.node.liveUploadInterface?.fileUpdated(true) as? LegacyLiveUploadInterfaceResult
|
thumbnailImage = .single(video.thumbnail)
|
||||||
}
|
|
||||||
if !hasAdjustments, let liveUploadData, let data = try? Data(contentsOf: URL(fileURLWithPath: video.videoPath)) {
|
|
||||||
resource = LocalFileMediaResource(fileId: liveUploadData.id)
|
|
||||||
self.context.account.postbox.mediaBox.storeResourceData(resource.id, data: data, synchronous: true)
|
|
||||||
} else {
|
|
||||||
resource = LocalFileVideoMediaResource(randomId: Int64.random(in: Int64.min ... Int64.max), paths: videoPaths, adjustments: resourceAdjustments)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var previewRepresentations: [TelegramMediaImageRepresentation] = []
|
let _ = (thumbnailImage
|
||||||
|
|> deliverOnMainQueue).startStandalone(next: { [weak self] thumbnailImage in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let values = MediaEditorValues(peerId: self.context.account.peerId, originalDimensions: dimensions, cropOffset: .zero, cropRect: CGRect(origin: .zero, size: dimensions.cgSize), cropScale: 1.0, cropRotation: 0.0, cropMirroring: false, cropOrientation: nil, gradientColors: nil, videoTrimRange: self.node.previewState?.trimRange, videoIsMuted: false, videoIsFullHd: false, videoIsMirrored: false, videoVolume: nil, additionalVideoPath: nil, additionalVideoIsDual: false, additionalVideoPosition: nil, additionalVideoScale: nil, additionalVideoRotation: nil, additionalVideoPositionChanges: [], additionalVideoTrimRange: nil, additionalVideoOffset: nil, additionalVideoVolume: nil, nightTheme: false, drawing: nil, entities: [], toolValues: [:], audioTrack: nil, audioTrackTrimRange: nil, audioTrackOffset: nil, audioTrackVolume: nil, audioTrackSamples: nil, qualityPreset: .videoMessage)
|
||||||
|
|
||||||
let thumbnailResource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
|
var resourceAdjustments: VideoMediaResourceAdjustments? = nil
|
||||||
let thumbnailSize = video.dimensions.cgSize.aspectFitted(CGSize(width: 320.0, height: 320.0))
|
if let valuesData = try? JSONEncoder().encode(values) {
|
||||||
if let thumbnailData = scaleImageToPixelSize(image: thumbnailImage, size: thumbnailSize)?.jpegData(compressionQuality: 0.4) {
|
let data = MemoryBuffer(data: valuesData)
|
||||||
self.context.account.postbox.mediaBox.storeResourceData(thumbnailResource.id, data: thumbnailData)
|
let digest = MemoryBuffer(data: data.md5Digest())
|
||||||
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailSize), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: false))
|
resourceAdjustments = VideoMediaResourceAdjustments(data: data, digest: digest, isStory: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
let tempFile = TempBox.shared.tempFile(fileName: "file")
|
let resource: TelegramMediaResource
|
||||||
defer {
|
let liveUploadData: LegacyLiveUploadInterfaceResult?
|
||||||
TempBox.shared.dispose(tempFile)
|
if let current = self.node.currentLiveUploadData {
|
||||||
}
|
liveUploadData = current
|
||||||
if let data = compressImageToJPEG(thumbnailImage, quality: 0.7, tempFilePath: tempFile.path) {
|
} else {
|
||||||
context.account.postbox.mediaBox.storeCachedResourceRepresentation(resource, representation: CachedVideoFirstFrameRepresentation(), data: data)
|
liveUploadData = self.node.liveUploadInterface?.fileUpdated(true) as? LegacyLiveUploadInterfaceResult
|
||||||
}
|
}
|
||||||
|
if !hasAdjustments, let liveUploadData, let data = try? Data(contentsOf: URL(fileURLWithPath: video.videoPath)) {
|
||||||
|
resource = LocalFileMediaResource(fileId: liveUploadData.id)
|
||||||
|
self.context.account.postbox.mediaBox.storeResourceData(resource.id, data: data, synchronous: true)
|
||||||
|
} else {
|
||||||
|
resource = LocalFileVideoMediaResource(randomId: Int64.random(in: Int64.min ... Int64.max), paths: videoPaths, adjustments: resourceAdjustments)
|
||||||
|
}
|
||||||
|
|
||||||
let media = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: Int64.random(in: Int64.min ... Int64.max)), partialReference: nil, resource: resource, previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: "video/mp4", size: nil, attributes: [.FileName(fileName: "video.mp4"), .Video(duration: finalDuration, size: video.dimensions, flags: [.instantRoundVideo], preloadSize: nil)])
|
var previewRepresentations: [TelegramMediaImageRepresentation] = []
|
||||||
|
|
||||||
|
let thumbnailResource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
|
||||||
|
let thumbnailSize = video.dimensions.cgSize.aspectFitted(CGSize(width: 320.0, height: 320.0))
|
||||||
|
if let thumbnailData = scaleImageToPixelSize(image: thumbnailImage, size: thumbnailSize)?.jpegData(compressionQuality: 0.4) {
|
||||||
|
self.context.account.postbox.mediaBox.storeResourceData(thumbnailResource.id, data: thumbnailData)
|
||||||
|
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailSize), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: false))
|
||||||
|
}
|
||||||
|
|
||||||
|
let tempFile = TempBox.shared.tempFile(fileName: "file")
|
||||||
|
defer {
|
||||||
|
TempBox.shared.dispose(tempFile)
|
||||||
|
}
|
||||||
|
if let data = compressImageToJPEG(thumbnailImage, quality: 0.7, tempFilePath: tempFile.path) {
|
||||||
|
context.account.postbox.mediaBox.storeCachedResourceRepresentation(resource, representation: CachedVideoFirstFrameRepresentation(), data: data)
|
||||||
|
}
|
||||||
|
|
||||||
|
let media = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: Int64.random(in: Int64.min ... Int64.max)), partialReference: nil, resource: resource, previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: "video/mp4", size: nil, attributes: [.FileName(fileName: "video.mp4"), .Video(duration: finalDuration, size: video.dimensions, flags: [.instantRoundVideo], preloadSize: nil)])
|
||||||
|
|
||||||
|
|
||||||
var attributes: [MessageAttribute] = []
|
var attributes: [MessageAttribute] = []
|
||||||
if self.cameraState.isViewOnceEnabled {
|
if self.cameraState.isViewOnceEnabled {
|
||||||
attributes.append(AutoremoveTimeoutMessageAttribute(timeout: viewOnceTimeout, countdownBeginTime: nil))
|
attributes.append(AutoremoveTimeoutMessageAttribute(timeout: viewOnceTimeout, countdownBeginTime: nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
self.completion(.message(
|
self.completion(.message(
|
||||||
text: "",
|
text: "",
|
||||||
attributes: attributes,
|
attributes: attributes,
|
||||||
inlineStickers: [:],
|
inlineStickers: [:],
|
||||||
mediaReference: .standalone(media: media),
|
mediaReference: .standalone(media: media),
|
||||||
threadId: nil,
|
threadId: nil,
|
||||||
replyToMessageId: nil,
|
replyToMessageId: nil,
|
||||||
replyToStoryId: nil,
|
replyToStoryId: nil,
|
||||||
localGroupingKey: nil,
|
localGroupingKey: nil,
|
||||||
correlationId: nil,
|
correlationId: nil,
|
||||||
bubbleUpEmojiOrStickersets: []
|
bubbleUpEmojiOrStickersets: []
|
||||||
), silentPosting, scheduleTime)
|
), silentPosting, scheduleTime)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user