Deliberate handling of MIME types for video, audio, and images.

• rejects unhandled media with unsupported attachment message
• for supported media, handling of MIME type/file extension conversion in a single place
• groundwork for future handling of additional types via e.g. conversion
This commit is contained in:
Christine Corbett 2015-01-28 17:50:41 -10:00 committed by Frederic Jacobs
parent 994c9d1c50
commit f5848365f7
11 changed files with 292 additions and 87 deletions

View File

@ -281,6 +281,7 @@
A5578C721A646E5300704A25 /* VersionMigrationsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = A5578C711A646E5300704A25 /* VersionMigrationsTests.m */; };
A56977911A351BC400173BF2 /* ScanIdentityBarcodeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = A569778E1A351BC400173BF2 /* ScanIdentityBarcodeViewController.m */; };
A56977921A351BC400173BF2 /* PresentIdentityQRCodeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = A569778F1A351BC400173BF2 /* PresentIdentityQRCodeViewController.m */; };
A59E6D721A79E5D100D98E2E /* MIMETypeUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = A59E6D711A79E5D100D98E2E /* MIMETypeUtil.m */; };
A5D0699B1A50E9CB004CB540 /* ShowGroupMembersViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = A5D069991A50E9CB004CB540 /* ShowGroupMembersViewController.m */; };
A5E9D4BB1A65FAD800E4481C /* TSVideoAttachmentAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = A5E9D4B91A65FAD800E4481C /* TSVideoAttachmentAdapter.m */; };
AA0C8E498E2046B0B81EEE6E /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8313AE91B4954215858A5662 /* libPods.a */; };
@ -889,6 +890,8 @@
A569778E1A351BC400173BF2 /* ScanIdentityBarcodeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ScanIdentityBarcodeViewController.m; sourceTree = "<group>"; };
A569778F1A351BC400173BF2 /* PresentIdentityQRCodeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PresentIdentityQRCodeViewController.m; sourceTree = "<group>"; };
A56977901A351BC400173BF2 /* PresentIdentityQRCodeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PresentIdentityQRCodeViewController.h; sourceTree = "<group>"; };
A59E6D701A79E5D100D98E2E /* MIMETypeUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MIMETypeUtil.h; sourceTree = "<group>"; };
A59E6D711A79E5D100D98E2E /* MIMETypeUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MIMETypeUtil.m; sourceTree = "<group>"; };
A5D069991A50E9CB004CB540 /* ShowGroupMembersViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = ShowGroupMembersViewController.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
A5D0699A1A50E9CB004CB540 /* ShowGroupMembersViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShowGroupMembersViewController.h; sourceTree = "<group>"; };
A5E9D4B91A65FAD800E4481C /* TSVideoAttachmentAdapter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSVideoAttachmentAdapter.m; sourceTree = "<group>"; };
@ -1806,6 +1809,8 @@
76EB04C818170B33006006FC /* util */ = {
isa = PBXGroup;
children = (
A59E6D701A79E5D100D98E2E /* MIMETypeUtil.h */,
A59E6D711A79E5D100D98E2E /* MIMETypeUtil.m */,
FCFA64B11A24F29E0007FB87 /* UI Categories */,
76EB04C918170B33006006FC /* ArrayUtil.h */,
76EB04CA18170B33006006FC /* ArrayUtil.m */,
@ -3277,6 +3282,7 @@
E197B60F18BBEC1A00F073E5 /* EncodedAudioFrame.m in Sources */,
B6B0966C1A1D25ED008BFAA6 /* TSCall.m in Sources */,
76EB061818170B33006006FC /* AnonymousValueLogger.m in Sources */,
A59E6D721A79E5D100D98E2E /* MIMETypeUtil.m in Sources */,
76EB05E618170B33006006FC /* CallController.m in Sources */,
FC31962A1A067D8F0094C78E /* MessageComposeTableViewController.m in Sources */,
E16E5BEE18AAC40200B7C403 /* EC25KeyAgreementParticipant.m in Sources */,

View File

@ -20,6 +20,7 @@
#import "VersionMigrations.h"
#import "UIColor+OWS.h"
#import "CodeVerificationViewController.h"
#import "MIMETypeUtil.h"
#import <PastelogKit/Pastelog.h>
@ -65,7 +66,6 @@ static NSString* const kCallSegue = @"2.0_6.0_Call_Segue";
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
BOOL loggingIsEnabled;
[self setupAppearance];
#ifdef DEBUG
@ -129,6 +129,7 @@ static NSString* const kCallSegue = @"2.0_6.0_Call_Segue";
[self refreshContacts];
[TSPreKeyManager refreshPreKeys];
}
[MIMETypeUtil initialize];
return YES;
}

View File

@ -7,9 +7,8 @@
//
#import "TSAttachmentStream.h"
#import "UIImage+contentTypes.h"
#import <AVFoundation/AVFoundation.h>
#import "MIMETypeUtil.h"
NSString * const TSAttachementFileRelationshipEdge = @"TSAttachementFileEdge";
@implementation TSAttachmentStream
@ -53,17 +52,7 @@ NSString * const TSAttachementFileRelationshipEdge = @"TSAttachementFileEdge";
}
- (NSString*)filePath {
if ([self isVideo] || [self isAudio]) {
NSString *path = [[[[self class] attachmentsFolder] stringByAppendingFormat:@"/%@", self.uniqueId] stringByAppendingPathExtension:[self mediaExtension]];
NSURL *pathURL = [NSURL URLWithString:path];
NSString *mp3String = [NSString stringWithFormat:@"%@.mp3", [[pathURL URLByDeletingPathExtension] absoluteString]];
if ([[NSFileManager defaultManager] fileExistsAtPath:mp3String]) {
return mp3String;
} else return path;
}
else {
return [[[self class] attachmentsFolder] stringByAppendingFormat:@"/%@", self.uniqueId];
}
return [MIMETypeUtil filePathForAttachment:self.uniqueId ofMIMEType:self.contentType inFolder:[[self class] attachmentsFolder]];
}
-(NSURL*) mediaURL {
@ -71,19 +60,17 @@ NSString * const TSAttachementFileRelationshipEdge = @"TSAttachementFileEdge";
}
- (BOOL)isImage {
return [self.contentType containsString:@"image/"];
return [MIMETypeUtil isImage:self.contentType];
}
-(NSString*)mediaExtension {
return [[self.contentType stringByReplacingOccurrencesOfString:@"video/" withString:@""] stringByReplacingOccurrencesOfString:@"audio/" withString:@""];
}
- (BOOL)isVideo {
return [self.contentType containsString:@"video/"];
return [MIMETypeUtil isVideo:self.contentType];
}
-(BOOL)isAudio {
return [self.contentType containsString:@"audio/"];
return [MIMETypeUtil isAudio:self.contentType];
}
- (UIImage*)image {

View File

@ -21,6 +21,7 @@
#import "TSMessagesManager+attachments.h"
#import "TSMessagesManager+sendMessages.h"
#import "TSNetworkManager.h"
#import "MIMETypeUtil.h"
@interface TSMessagesManager ()
@ -48,9 +49,8 @@ dispatch_queue_t attachmentsQueue() {
for (PushMessageContentAttachmentPointer *pointer in attachmentsToRetrieve) {
TSAttachmentPointer *attachmentPointer = (content.group != nil && (content.group.type == PushMessageContentGroupContextTypeUpdate)) ? [[TSAttachmentPointer alloc] initWithIdentifier:pointer.id key:pointer.key contentType:pointer.contentType relay:message.relay avatarOfGroupId:content.group.id] : [[TSAttachmentPointer alloc] initWithIdentifier:pointer.id key:pointer.key contentType:pointer.contentType relay:message.relay];
if ([attachmentPointer.contentType hasPrefix:@"image/"]||[attachmentPointer.contentType hasPrefix:@"video/"] || [attachmentPointer.contentType hasPrefix:@"audio/"]) {
if ([MIMETypeUtil isSupportedMIMEType:attachmentPointer.contentType]) {
[attachmentPointer saveWithTransaction:transaction];
[retrievedAttachments addObject:attachmentPointer.uniqueId];
shouldProcessMessage = YES;
}

View File

@ -0,0 +1,38 @@
#import <Foundation/Foundation.h>
@interface MIMETypeUtil : NSObject
+(void) initialize;
+(BOOL)isSupportedMIMEType:(NSString*)contentType;
+(BOOL)isSupportedVideoMIMEType:(NSString*)contentType;
+(BOOL)isSupportedAudioMIMEType:(NSString*)contentType;
+(BOOL)isSupportedImageMIMEType:(NSString*)contentType;
+(BOOL)isSupportedVideoFile:(NSString*)filePath;
+(BOOL)isSupportedAudioFile:(NSString*)filePath;
+(BOOL)isSupportedImageFile:(NSString*)filePath;
+(NSString*)getSupportedExtensionFromVideoMIMEType:(NSString*)supportedMIMEType;
+(NSString*)getSupportedExtensionFromAudioMIMEType:(NSString*)supportedMIMEType;
+(NSString*)getSupportedExtensionFromImageMIMEType:(NSString*)supportedMIMEType;
+(NSString*)getSupportedMIMETypeFromVideoFile:(NSString*)supportedVideoFile;
+(NSString*)getSupportedMIMETypeFromAudioFile:(NSString*)supportedAudioFile;
+(NSString*)getSupportedMIMETypeFromImageFile:(NSString*)supportedImageFile;
+(NSString*)getSupportedImageMIMETypeFromImage:(UIImage*)image;
+(BOOL)getIsSupportedTypeFromImage:(UIImage*)image;
+(BOOL)isImage:(NSString*)contentType;
+(BOOL)isVideo:(NSString*)contentType;
+(BOOL)isAudio:(NSString*)contentType;
+(NSString*)filePathForAttachment:(NSString*)uniqueId ofMIMEType:(NSString*)contentType inFolder:(NSString*)folder;
+(NSString*)filePathForImage:(NSString*)uniqueId ofMIMEType:(NSString*)contentType inFolder:(NSString*)folder;
+(NSString*)filePathForVideo:(NSString*)uniqueId ofMIMEType:(NSString*)contentType inFolder:(NSString*)folder;
+(NSString*)filePathForAudio:(NSString*)uniqueId ofMIMEType:(NSString*)contentType inFolder:(NSString*)folder;
+(NSURL*)simLinkCorrectExtensionOfFile:(NSURL*)mediaURL ofMIMEType:(NSString*)contentType;
@end

View File

@ -0,0 +1,218 @@
#import "MIMETypeUtil.h"
#import "UIImage+contentTypes.h"
@implementation MIMETypeUtil
static NSDictionary *supportedVideoMIMETypesToExtensionTypes;
static NSDictionary *supportedAudioMIMETypesToExtensionTypes;
static NSDictionary *supportedImageMIMETypesToExtensionTypes;
static NSDictionary *supportedVideoExtensionTypesToMIMETypes;
static NSDictionary *supportedAudioExtensionTypesToMIMETypes;
static NSDictionary *supportedImageExtensionTypesToMIMETypes;
#pragma mark uses file extensions or MIME types only
+(void) initialize {
// Initialize must be called before this class is used. Could later be in e.g. a .plist
supportedVideoMIMETypesToExtensionTypes =@{@"video/3gpp":@"3gp",
@"video/3gpp2":@"3g2",
@"video/mp4":@"mp4",
@"video/quicktime":@"mov",
@"video/x-m4v":@"m4v"
};
supportedAudioMIMETypesToExtensionTypes = @{@"audio/x-m4p":@"m4p",
@"audio/x-m4b":@"m4b",
@"audio/x-m4a":@"m4a",
@"audio/wav":@"wav",
@"audio/x-wav":@"wav",
@"audio/x-mpeg":@"mp3",
@"audio/mpeg":@"mp3",
@"audio/mp4":@"mp4",
@"audio/mp3":@"mp3",
@"audio/mpeg3":@"mp3",
@"audio/x-mp3":@"mp3",
@"audio/x-mpeg3":@"mp3",
@"audio/amr":@"amr",
@"audio/aiff":@"aiff",
@"audio/x-aiff":@"aiff",
@"audio/3gpp2":@"3g2",
@"audio/3gpp":@"3gp"
};
supportedImageMIMETypesToExtensionTypes = @{@"image/jpeg":@"jpeg",
@"image/pjpeg":@"jpeg",
@"image/png":@"png",
@"image/gif":@"gif",
@"image/tiff":@"tif",
@"image/x-tiff":@"tif",
@"image/bmp":@"bmp",
@"image/x-windows-bmp":@"bmp"
};
supportedVideoExtensionTypesToMIMETypes = @{@"3gp":@"video/3gpp",
@"3gpp":@"video/3gpp",
@"3gp2":@"video/3gpp2",
@"3gpp2":@"video/3gpp2",
@"mp4":@"video/mp4",
@"mov":@"video/quicktime",
@"mqv":@"video/quicktime",
@"m4v":@"video/x-m4v"
};
supportedAudioExtensionTypesToMIMETypes = @{@"3gp":@"audio/3gpp",
@"3gpp":@"@audio/3gpp",
@"3g2":@"audio/3gpp2",
@"3gp2":@"audio/3gpp2",
@"aiff":@"audio/aiff",
@"aif":@"audio/aiff",
@"aifc":@"audio/aiff",
@"cdda":@"audio/aiff",
@"amr":@"audio/amr",
@"mp3":@"audio/mp3",
@"swa":@"audio/mp3",
@"mp4":@"audio/mp4",
@"mpeg":@"audio/mpeg",
@"mpg":@"audio/mpeg",
@"wav":@"audio/wav",
@"bwf":@"audio/wav",
@"m4a":@"audio/x-m4a",
@"m4b":@"audio/x-m4b",
@"m4p":@"audio/x-m4p"
};
supportedImageExtensionTypesToMIMETypes = @{@"png":@"image/png",
@"x-png":@"image/png",
@"jfif":@"image/jpeg",
@"jfif":@"image/pjpeg",
@"jfif-tbnl":@"image/jpeg",
@"jpe":@"image/jpeg",
@"jpe":@"image/pjpeg",
@"jpeg":@"image/jpeg",
@"jpg":@"image/jpeg",
@"gif":@"image/gif",
@".tif":@"image/tiff",
@".tiff":@"image/tiff"
};
}
+(BOOL) isSupportedVideoMIMEType:(NSString*)contentType {
return [supportedVideoMIMETypesToExtensionTypes objectForKey:contentType]!=nil;
}
+(BOOL) isSupportedAudioMIMEType:(NSString*)contentType {
return [supportedAudioMIMETypesToExtensionTypes objectForKey:contentType]!=nil;
}
+(BOOL) isSupportedImageMIMEType:(NSString*)contentType {
return [supportedImageMIMETypesToExtensionTypes objectForKey:contentType]!=nil;
}
+(BOOL) isSupportedMIMEType:(NSString*)contentType {
return [self isSupportedImageMIMEType:contentType] || [self isSupportedAudioMIMEType:contentType] || [self isSupportedVideoMIMEType:contentType];
}
+(BOOL) isSupportedVideoFile:(NSString*) filePath {
return [supportedVideoExtensionTypesToMIMETypes objectForKey:[filePath pathExtension]]!=nil;
}
+(BOOL) isSupportedAudioFile:(NSString*) filePath {
return [supportedAudioExtensionTypesToMIMETypes objectForKey:[filePath pathExtension]]!=nil;
}
+(BOOL) isSupportedImageFile:(NSString*) filePath {
return [supportedImageExtensionTypesToMIMETypes objectForKey:[filePath pathExtension]]!=nil;
}
+(NSString*) getSupportedExtensionFromVideoMIMEType:(NSString*)supportedMIMEType {
return [supportedVideoMIMETypesToExtensionTypes objectForKey:supportedMIMEType];
}
+(NSString*) getSupportedExtensionFromAudioMIMEType:(NSString*)supportedMIMEType {
return [supportedAudioMIMETypesToExtensionTypes objectForKey:supportedMIMEType];
}
+(NSString*) getSupportedExtensionFromImageMIMEType:(NSString*)supportedMIMEType {
return [supportedImageMIMETypesToExtensionTypes objectForKey:supportedMIMEType];
}
+(NSString*) getSupportedMIMETypeFromVideoFile:(NSString*)supportedVideoFile {
return [supportedVideoExtensionTypesToMIMETypes objectForKey:[supportedVideoFile pathExtension]];
}
+(NSString*) getSupportedMIMETypeFromAudioFile:(NSString*)supportedAudioFile {
return [supportedAudioExtensionTypesToMIMETypes objectForKey:[supportedAudioFile pathExtension]];
}
+(NSString*) getSupportedMIMETypeFromImageFile:(NSString*)supportedImageFile {
return [supportedImageExtensionTypesToMIMETypes objectForKey:[supportedImageFile pathExtension]];
}
#pragma mark uses bytes
+(NSString*) getSupportedImageMIMETypeFromImage:(UIImage*)image {
return [image contentType];
}
+(BOOL) getIsSupportedTypeFromImage:(UIImage*)image {
return [image isSupportedImageType];
}
#pragma mark full attachment utilities
+ (BOOL)isImage:(NSString*)contentType {
return [MIMETypeUtil isSupportedImageMIMEType:contentType];
}
+ (BOOL)isVideo:(NSString*)contentType {
return [MIMETypeUtil isSupportedVideoMIMEType:contentType];
}
+(BOOL)isAudio:(NSString*)contentType {
return [MIMETypeUtil isSupportedAudioMIMEType:contentType];
}
+ (NSString*)filePathForAttachment:(NSString*)uniqueId ofMIMEType:(NSString*)contentType inFolder:(NSString*)folder {
if ([self isVideo:contentType]){
return [MIMETypeUtil filePathForVideo:uniqueId ofMIMEType:contentType inFolder:folder];
}
else if([self isAudio:contentType]) {
return [MIMETypeUtil filePathForAudio:uniqueId ofMIMEType:contentType inFolder:folder];
}
else {
return [MIMETypeUtil filePathForImage:uniqueId ofMIMEType:contentType inFolder:folder];
}
}
+(NSURL*) simLinkCorrectExtensionOfFile:(NSURL*)mediaURL ofMIMEType:(NSString*)contentType {
if([self isAudio:contentType]) {
// Audio files in current framework require changing to have extension for player
return [self changeFile:mediaURL toHaveExtension:[supportedAudioMIMETypesToExtensionTypes objectForKey:contentType]];
}
return mediaURL;
}
+(NSURL*) changeFile:(NSURL*)originalFile toHaveExtension:(NSString*)extension {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString* newPath = [originalFile.URLByDeletingPathExtension.absoluteString stringByAppendingPathExtension:extension];
if (![fileManager fileExistsAtPath:newPath]) {
NSError *error = nil;
[fileManager createSymbolicLinkAtPath:newPath withDestinationPath:[originalFile path] error: &error];
return [NSURL URLWithString:newPath];
}
return originalFile;
}
+ (NSString*)filePathForImage:(NSString*)uniqueId ofMIMEType:(NSString*)contentType inFolder:(NSString*)folder{
return [folder stringByAppendingFormat:@"/%@",uniqueId];
}
+ (NSString*)filePathForVideo:(NSString*)uniqueId ofMIMEType:(NSString*)contentType inFolder:(NSString*)folder{
return [[folder stringByAppendingFormat:@"/%@",uniqueId] stringByAppendingPathExtension:[self getSupportedExtensionFromVideoMIMEType:contentType]];
}
+ (NSString*)filePathForAudio:(NSString*)uniqueId ofMIMEType:(NSString*)contentType inFolder:(NSString*)folder{
return [[folder stringByAppendingFormat:@"/%@",uniqueId] stringByAppendingPathExtension:[self getSupportedExtensionFromAudioMIMEType:contentType]];
}
@end

View File

@ -4,6 +4,7 @@
#import "UIFont+OWS.h"
#import "UIImage+normalizeImage.h"
#import "UIImage+contentTypes.h"
#import "MIMETypeUtil.h"
/**
*

View File

@ -840,16 +840,7 @@ typedef enum : NSUInteger {
}
}
-(NSURL*) changeFile:(NSURL*)originalFile toHaveExtension:(NSString*)extension {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString* newPath = [[originalFile path] stringByAppendingPathExtension:extension];
if (![fileManager fileExistsAtPath:newPath]) {
NSError *error = nil;
[fileManager createSymbolicLinkAtPath:newPath withDestinationPath:[originalFile path] error: &error];
return [NSURL URLWithString:newPath];
}
return originalFile;
}
-(void)moviePlayBackDidFinish:(id)sender {
DDLogDebug(@"playback finished");
}
@ -1093,7 +1084,7 @@ typedef enum : NSUInteger {
}
-(void)sendQualityAdjustedAttachment:(NSURL*)movieURL {
// TODO: should support anything that is in the videos directory
AVAsset *video = [AVAsset assetWithURL:movieURL];
AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:video presetName:AVAssetExportPresetMediumQuality];
exportSession.shouldOptimizeForNetworkUse = YES;
@ -1115,55 +1106,12 @@ typedef enum : NSUInteger {
[exportSession exportAsynchronouslyWithCompletionHandler:^{
}];
//SHOULD PROBABLY REMOVE THIS
while(exportSession.progress!=1){
}
[self sendMessageAttachment:[NSData dataWithContentsOfURL:compressedVideoUrl] ofType:@"video/mp4"];
#if 0
return [NSData dataWithContentsOfURL:movieURL];
#endif
#if 0
NSString *serializationQueueDescription = [NSString stringWithFormat:@"%@ serialization queue", self];
// Create the main serialization queue.
self.mainSerializationQueue = dispatch_queue_create([serializationQueueDescription UTF8String], NULL);
NSString *rwAudioSerializationQueueDescription = [NSString stringWithFormat:@"%@ rw audio serialization queue", self];
// Create the serialization queue to use for reading and writing the audio data.
self.rwAudioSerializationQueue = dispatch_queue_create([rwAudioSerializationQueueDescription UTF8String], NULL);
NSString *rwVideoSerializationQueueDescription = [NSString stringWithFormat:@"%@ rw video serialization queue", self];
// Create the serialization queue to use for reading and writing the video data.
self.rwVideoSerializationQueue = dispatch_queue_create([rwVideoSerializationQueueDescription UTF8String], NULL);
int videoWidth = 1920;
int videoHeight = 1920;
int desiredKeyframeInterval = 2;
int desiredBitrate = 3000;
NSError *error = nil;
AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:
[NSURL fileURLWithPath:@"hello"]
fileType:AVFileTypeQuickTimeMovie
error:&error];
NSParameterAssert(videoWriter);
NSDictionary* settings = @{AVVideoCodecKey:AVVideoCodecH264,
AVVideoCompressionPropertiesKey:@{AVVideoAverageBitRateKey:[NSNumber numberWithInt:desiredBitrate],AVVideoProfileLevelKey:AVVideoProfileLevelH264Main31},
AVVideoWidthKey: [NSNumber numberWithInt:videoWidth],
AVVideoHeightKey:[NSNumber numberWithInt:videoHeight]};
AVAssetWriterInput* writerInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:settings];
NSParameterAssert(writerInput);
NSParameterAssert([videoWriter canAddInput:writerInput]);
[videoWriter addInput:writerInput];
#endif
}
-(NSData*)qualityAdjustedAttachmentForImage:(UIImage*)image

View File

@ -15,7 +15,8 @@
- (instancetype)initWithAttachment:(TSAttachmentStream*)attachment;
- (BOOL)isImage;
- (BOOL)isAudio;
- (BOOL)isVideo;
@property NSString *attachmentId;
@end

View File

@ -75,6 +75,16 @@
return YES;
}
-(BOOL) isAudio {
return NO;
}
-(BOOL) isVideo {
return NO;
}
#pragma mark - Utility
-(CGSize)getBubbleSizeForImage:(UIImage*)image

View File

@ -16,7 +16,7 @@
#import "TSNetworkManager.h"
#import "UIColor+OWS.h"
#import "SCWaveformView.h"
#import "MIMETypeUtil.h"
#define AUDIO_BAR_HEIGHT 36
@interface TSVideoAttachmentAdapter ()
@ -58,12 +58,12 @@
}
-(BOOL) isAudio {
return [_contentType containsString:@"audio/"];
return [MIMETypeUtil isSupportedAudioMIMEType:_contentType];
}
-(BOOL) isVideo {
return [_contentType containsString:@"video/"];
return [MIMETypeUtil isSupportedVideoMIMEType:_contentType];
}
-(NSString*)formatDuration:(NSTimeInterval)duration {
@ -141,14 +141,9 @@
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(attachmentUploadProgress:) name:@"attachmentUploadProgress" object:nil];
}
} else if ([self isAudio]) {
//aac files like from android don't play, gotta convert
NSString *convertedFile = [NSString stringWithFormat:@"%@.mp3", _attachment.mediaURL.URLByDeletingPathExtension.absoluteString];
NSError * err = NULL;
NSFileManager *fm = [NSFileManager defaultManager];
[fm moveItemAtURL:_attachment.mediaURL toURL:[NSURL URLWithString:convertedFile] error:&err];
NSURL* url = [MIMETypeUtil simLinkCorrectExtensionOfFile:_attachment.mediaURL ofMIMEType:_attachment.contentType];
NSURL *url = [NSURL URLWithString:convertedFile];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:url options:nil];
_waveform = [[SCWaveformView alloc] init];
_waveform.frame = CGRectMake(42.0, 0.0, size.width-84, size.height);