Use SignalAttachment logic in conversation view too

// FREEBIE
This commit is contained in:
Michael Kirk 2017-12-11 20:16:08 -05:00
parent 7d0acc94ff
commit 031e40d090
3 changed files with 62 additions and 42 deletions

View File

@ -62,6 +62,7 @@
#import <JSQSystemSoundPlayer/JSQSystemSoundPlayer.h>
#import <MediaPlayer/MediaPlayer.h>
#import <MobileCoreServices/UTCoreTypes.h>
#import <PromiseKit/AnyPromise.h>
#import <SignalMessaging/OWSContactOffersInteraction.h>
#import <SignalMessaging/OWSFormat.h>
#import <SignalMessaging/OWSUserProfile.h>
@ -2722,50 +2723,33 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) {
presentFromViewController:self
canCancel:YES
backgroundBlock:^(ModalActivityIndicatorViewController *modalActivityIndicator) {
AVAsset *video = [AVAsset assetWithURL:movieURL];
AVAssetExportSession *exportSession =
[AVAssetExportSession exportSessionWithAsset:video
presetName:AVAssetExportPresetMediumQuality];
exportSession.shouldOptimizeForNetworkUse = YES;
exportSession.outputFileType = AVFileTypeMPEG4;
NSURL *compressedVideoUrl = [[self videoTempFolder]
URLByAppendingPathComponent:[[[NSUUID UUID] UUIDString]
stringByAppendingPathExtension:@"mp4"]];
exportSession.outputURL = compressedVideoUrl;
[exportSession exportAsynchronouslyWithCompletionHandler:^{
dispatch_async(dispatch_get_main_queue(), ^{
OWSAssert([NSThread isMainThread]);
DataSource *dataSource = [DataSourcePath dataSourceWithURL:movieURL];
dataSource.sourceFilename = filename;
VideoCompressionResult *compressionResult =
[SignalAttachment compressVideoAsMp4WithDataSource:dataSource
dataUTI:(NSString *)kUTTypeMPEG4];
[compressionResult.attachmentPromise retainUntilComplete];
if (modalActivityIndicator.wasCancelled) {
return;
compressionResult.attachmentPromise.then(^(SignalAttachment *attachment) {
OWSAssert([NSThread isMainThread]);
OWSAssert([attachment isKindOfClass:[SignalAttachment class]]);
if (modalActivityIndicator.wasCancelled) {
return;
}
[modalActivityIndicator dismissWithCompletion:^{
if (!attachment || [attachment hasError]) {
DDLogError(@"%@ %s Invalid attachment: %@.",
self.logTag,
__PRETTY_FUNCTION__,
attachment ? [attachment errorName] : @"Missing data");
[self showErrorAlertForAttachment:attachment];
} else {
[self tryToSendAttachmentIfApproved:attachment skipApprovalDialog:skipApprovalDialog];
}
[modalActivityIndicator dismissWithCompletion:^{
NSString *baseFilename = filename.stringByDeletingPathExtension;
NSString *mp4Filename = [baseFilename stringByAppendingPathExtension:@"mp4"];
DataSource *_Nullable dataSource =
[DataSourcePath dataSourceWithURL:compressedVideoUrl];
[dataSource setSourceFilename:mp4Filename];
// Remove temporary file when complete.
[dataSource setShouldDeleteOnDeallocation];
SignalAttachment *attachment =
[SignalAttachment attachmentWithDataSource:dataSource
dataUTI:(NSString *)kUTTypeMPEG4];
if (!attachment || [attachment hasError]) {
DDLogError(@"%@ %s Invalid attachment: %@.",
self.logTag,
__PRETTY_FUNCTION__,
attachment ? [attachment errorName] : @"Missing data");
[self showErrorAlertForAttachment:attachment];
} else {
[self tryToSendAttachmentIfApproved:attachment
skipApprovalDialog:skipApprovalDialog];
}
}];
});
}];
}];
});
}];
}

View File

@ -866,6 +866,27 @@ public class SignalAttachment: NSObject {
return (promise, exportSession)
}
@objc
public class VideoCompressionResult: NSObject {
@objc
public let attachmentPromise: AnyPromise
@objc
public let exportSession: AVAssetExportSession?
fileprivate init(attachmentPromise: Promise<SignalAttachment>, exportSession: AVAssetExportSession?) {
self.attachmentPromise = AnyPromise(attachmentPromise)
self.exportSession = exportSession
super.init()
}
}
@objc
public class func compressVideoAsMp4(dataSource: DataSource, dataUTI: String) -> VideoCompressionResult {
let (attachmentPromise, exportSession) = compressVideoAsMp4(dataSource: dataSource, dataUTI: dataUTI)
return VideoCompressionResult(attachmentPromise: attachmentPromise, exportSession: exportSession)
}
public class func isInvalidVideo(dataSource: DataSource, dataUTI: String) -> Bool {
guard videoUTISet.contains(dataUTI) else {
// not a video

View File

@ -4,6 +4,21 @@
import PromiseKit
public extension AnyPromise {
/**
* Sometimes there isn't a straight forward candidate to retain a promise, in that case we tell the
* promise to self retain, until it completes to avoid the risk it's GC'd before completion.
*/
func retainUntilComplete() {
// Unfortunately, there is (currently) no way to surpress the
// compiler warning: "Variable 'retainCycle' was written to, but never read"
var retainCycle: AnyPromise? = self
self.always {
retainCycle = nil
}
}
}
public extension Promise {
/**
* Sometimes there isn't a straight forward candidate to retain a promise, in that case we tell the