diff --git a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Attachment/AttachmentViewModel+Compress.swift b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Attachment/AttachmentViewModel+Compress.swift new file mode 100644 index 000000000..e9c1df676 --- /dev/null +++ b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Attachment/AttachmentViewModel+Compress.swift @@ -0,0 +1,33 @@ +// +// AttachmentViewModel+Compress.swift +// +// +// Created by MainasuK on 2022/11/11. +// + +import UIKit +import AVKit + +extension AttachmentViewModel { + func comporessVideo(url: URL) async throws -> URL { + let task = Task { () -> URL in + let urlAsset = AVURLAsset(url: url) + guard let exportSession = AVAssetExportSession(asset: urlAsset, presetName: AVAssetExportPresetMediumQuality) else { + throw AttachmentError.invalidAttachmentType + } + let outputURL = try FileManager.default.createTemporaryFileURL( + filename: UUID().uuidString, + pathExtension: url.pathExtension + ) + exportSession.outputURL = outputURL + exportSession.outputFileType = AVFileType.mp4 + exportSession.shouldOptimizeForNetworkUse = true + await exportSession.export() + return outputURL + } + + self.compressVideoTask = task + + return try await task.value + } +} diff --git a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Attachment/AttachmentViewModel.swift b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Attachment/AttachmentViewModel.swift index 9409e7380..7bbaaefaf 100644 --- a/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Attachment/AttachmentViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/Scene/ComposeContent/Attachment/AttachmentViewModel.swift @@ -43,6 +43,8 @@ final public class AttachmentViewModel: NSObject, ObservableObject, Identifiable @Published var caption = "" @Published var sizeLimit = SizeLimit() + var compressVideoTask: Task? + // output @Published public private(set) var output: Output? @Published public private(set) var thumbnail: UIImage? // original size image thumbnail @@ -120,9 +122,20 @@ final public class AttachmentViewModel: NSObject, ObservableObject, Identifiable defer { Task { @MainActor in do { - let output = try await load(input: input) - self.output = output + var output = try await load(input: input) + + switch output { + case .video(let fileURL, let mimeType): + let compressedFileURL = try await comporessVideo(url: fileURL) + output = .video(compressedFileURL, mimeType: mimeType) + try? FileManager.default.removeItem(at: fileURL) // remove old file + default: + break + } + self.outputSizeInByte = output.asAttachment.sizeInByte.flatMap { Int64($0) } ?? 0 + self.output = output + self.update(uploadState: .ready) self.delegate?.attachmentViewModel(self, uploadStateValueDidChange: self.uploadState) } catch {