Media Manager: refactoring (download video/image with a unique API)

This commit is contained in:
giomfo 2015-01-12 11:00:53 +01:00
parent b88e85daf6
commit 05062121a0
10 changed files with 132 additions and 217 deletions

View file

@ -20,6 +20,7 @@
F021FBEF1A5EF57300EA3AE6 /* MediaLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = F021FBEE1A5EF57300EA3AE6 /* MediaLoader.m */; };
F021FBF21A5F1F8E00EA3AE6 /* MediaManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F021FBF11A5F1F8E00EA3AE6 /* MediaManager.m */; };
F024098219E7D177006E741B /* tab_recents@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F024098119E7D177006E741B /* tab_recents@2x.png */; };
F02900BB1A63C71E00356F7D /* ConsoleTools.m in Sources */ = {isa = PBXBuildFile; fileRef = F02900BA1A63C71E00356F7D /* ConsoleTools.m */; };
F02BCE231A1A5A2B00543B47 /* play.png in Resources */ = {isa = PBXBuildFile; fileRef = F02BCE221A1A5A2B00543B47 /* play.png */; };
F02D707619F1DC9E007B47D3 /* RoomMemberTableCell.m in Sources */ = {isa = PBXBuildFile; fileRef = F02D707519F1DC9E007B47D3 /* RoomMemberTableCell.m */; };
F03C47111A02952800E445AB /* CustomAlert.m in Sources */ = {isa = PBXBuildFile; fileRef = F03C47101A02952800E445AB /* CustomAlert.m */; };
@ -89,6 +90,8 @@
F021FBF01A5F1F8E00EA3AE6 /* MediaManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaManager.h; sourceTree = "<group>"; };
F021FBF11A5F1F8E00EA3AE6 /* MediaManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MediaManager.m; sourceTree = "<group>"; };
F024098119E7D177006E741B /* tab_recents@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tab_recents@2x.png"; sourceTree = "<group>"; };
F02900B91A63C71E00356F7D /* ConsoleTools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConsoleTools.h; sourceTree = "<group>"; };
F02900BA1A63C71E00356F7D /* ConsoleTools.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ConsoleTools.m; sourceTree = "<group>"; };
F02BCE221A1A5A2B00543B47 /* play.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = play.png; sourceTree = "<group>"; };
F02D707419F1DC9E007B47D3 /* RoomMemberTableCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RoomMemberTableCell.h; sourceTree = "<group>"; };
F02D707519F1DC9E007B47D3 /* RoomMemberTableCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RoomMemberTableCell.m; sourceTree = "<group>"; };
@ -206,6 +209,8 @@
F021FBEC1A5EF57300EA3AE6 /* API */ = {
isa = PBXGroup;
children = (
F02900B91A63C71E00356F7D /* ConsoleTools.h */,
F02900BA1A63C71E00356F7D /* ConsoleTools.m */,
F021FBED1A5EF57300EA3AE6 /* MediaLoader.h */,
F021FBEE1A5EF57300EA3AE6 /* MediaLoader.m */,
F021FBF01A5F1F8E00EA3AE6 /* MediaManager.h */,
@ -501,6 +506,7 @@
F05B955F19DEED8A008761B0 /* MatrixHandler.m in Sources */,
F021FBEF1A5EF57300EA3AE6 /* MediaLoader.m in Sources */,
F03EF5FB19F171EB00A0EE52 /* SettingsViewController.m in Sources */,
F02900BB1A63C71E00356F7D /* ConsoleTools.m in Sources */,
F01A0FF31A27314B009FAE2F /* RoomMessageComponent.m in Sources */,
F03EF5FA19F171EB00A0EE52 /* RoomViewController.m in Sources */,
F03EF5F819F171EB00A0EE52 /* MasterTabBarController.m in Sources */,

View file

@ -16,6 +16,7 @@
#import "MediaManager.h"
#import "MatrixHandler.h"
#import "ConsoleTools.h"
NSString *const kMediaDownloadProgressNotification = @"kMediaDownloadProgressNotification";
NSString *const kMediaUploadProgressNotification = @"kMediaUploadProgressNotification";
@ -144,7 +145,7 @@ NSString *const kMediaLoaderProgressDownloadRateKey = @"kMediaLoaderProgressDown
NSString* progressString = [NSString stringWithFormat:@"%@ / %@", [NSByteCountFormatter stringFromByteCount:downloadData.length countStyle:NSByteCountFormatterCountStyleFile], [NSByteCountFormatter stringFromByteCount:expectedSize countStyle:NSByteCountFormatterCountStyleFile]];
[dict setValue:progressString forKey:kMediaLoaderProgressStringKey];
[dict setValue:[MediaManager formatSecondsInterval:dataRemainingTime] forKey:kMediaLoaderProgressRemaingTimeKey];
[dict setValue:[ConsoleTools formatSecondsInterval:dataRemainingTime] forKey:kMediaLoaderProgressRemaingTimeKey];
NSString* downloadRateStr = [NSString stringWithFormat:@"%@/s", [NSByteCountFormatter stringFromByteCount:meanRate * 1024 countStyle:NSByteCountFormatterCountStyleFile]];
[dict setValue:downloadRateStr forKey:kMediaLoaderProgressDownloadRateKey];
@ -180,7 +181,7 @@ NSString *const kMediaLoaderProgressDownloadRateKey = @"kMediaLoaderProgressDown
if (downloadData.length) {
// Cache the downloaded data
NSString *cacheFilePath = [MediaManager cacheMediaData:downloadData forURL:mediaURL mimeType:mimeType];
NSString *cacheFilePath = [MediaManager cacheMediaData:downloadData forURL:mediaURL andType:mimeType];
// Call registered block
if (onMediaReady) {
onMediaReady(cacheFilePath);

View file

@ -28,28 +28,17 @@ extern NSString *const kMediaDownloadDidFailNotification;
+ (id)sharedInstance;
+ (NSString*)formatSecondsInterval:(CGFloat)secondsInterval;
+ (UIImage *)resize:(UIImage *)image toFitInSize:(CGSize)size;
// Launch data download from the provided URL. Return a mediaLoader reference in order to let the user cancel this action.
+ (MediaLoader*)downloadMedia:(NSString*)mediaURL mimeType:(NSString *)mimeType;
// Check whether a download is already running for this media url. Return loader if any
+ (MediaLoader*)existingDownloaderForURL:(NSString*)url;
// Load a picture from the local cache (Do not start any remote requests)
+ (UIImage*)loadCachePicture:(NSString*)pictureURL;
// Launch picture downloading. Return a mediaLoader reference in order to let the user cancel this action.
+ (MediaLoader*)downloadPicture:(NSString*)pictureURL;
// Prepare a media from the local cache or download it if it is not available yet.
// In this second case a mediaLoader reference is returned in order to let the user cancel this action.
+ (MediaLoader*)prepareMedia:(NSString *)mediaURL
mimeType:(NSString *)mimeType
success:(blockMediaLoader_onMediaReady)success
failure:(blockMediaLoader_onError)failure;
// Check whether a media loader is already running for this media url. Return loader if any
+ (MediaLoader*)mediaLoaderForURL:(NSString*)url;
+ (NSString *)cacheMediaData:(NSData *)mediaData forURL:(NSString *)mediaURL mimeType:(NSString *)mimeType;
+ (UIImage*)loadCachePictureForURL:(NSString*)pictureURL;
// Store in cache the provided data for the media URL, return the path of the resulting file
+ (NSString*)cacheMediaData:(NSData *)mediaData forURL:(NSString *)mediaURL andType:(NSString *)mimeType;
// Return the cache path deduced from media URL and type
+ (NSString*)cachePathForMediaURL:(NSString*)mediaURL andType:(NSString *)mimeType;
+ (NSUInteger)cacheSize;
+ (void)clearCache;

View file

@ -29,155 +29,69 @@ static MediaManager *sharedMediaManager = nil;
@implementation MediaManager
// Table of mediaLoaders in progress
static NSMutableDictionary* pendingMediaLoadersByURL = nil;
static NSMutableDictionary* downloadTableByURL = nil;
+ (id)sharedInstance {
@synchronized(self) {
if(sharedMediaManager == nil)
if(sharedMediaManager == nil) {
sharedMediaManager = [[self alloc] init];
// Create download table here
downloadTableByURL = [[NSMutableDictionary alloc] init];
}
}
return sharedMediaManager;
}
+ (NSString*)formatSecondsInterval:(CGFloat)secondsInterval {
NSMutableString* formattedString = [[NSMutableString alloc] init];
if (secondsInterval < 1) {
[formattedString appendString:@"< 1s"];
} else if (secondsInterval < 60)
{
[formattedString appendFormat:@"%ds", (int)secondsInterval];
}
else if (secondsInterval < 3600)
{
[formattedString appendFormat:@"%dm %2ds", (int)(secondsInterval/60), ((int)secondsInterval) % 60];
}
else if (secondsInterval >= 3600)
{
[formattedString appendFormat:@"%dh %dm %ds", (int)(secondsInterval / 3600),
((int)(secondsInterval) % 3600) / 60,
(int)(secondsInterval) % 60];
}
[formattedString appendString:@" left"];
return formattedString;
}
#pragma mark - Media Download
+ (UIImage *)resize:(UIImage *)image toFitInSize:(CGSize)size {
UIImage *resizedImage = image;
// Check whether resize is required
if (size.width && size.height) {
CGFloat width = image.size.width;
CGFloat height = image.size.height;
if (width > size.width) {
height = (height * size.width) / width;
height = floorf(height / 2) * 2;
width = size.width;
}
if (height > size.height) {
width = (width * size.height) / height;
width = floorf(width / 2) * 2;
height = size.height;
}
if (width != image.size.width || height != image.size.height) {
// Create the thumbnail
CGSize imageSize = CGSizeMake(width, height);
UIGraphicsBeginImageContext(imageSize);
// // set to the top quality
// CGContextRef context = UIGraphicsGetCurrentContext();
// CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
CGRect thumbnailRect = CGRectMake(0, 0, 0, 0);
thumbnailRect.origin = CGPointMake(0.0,0.0);
thumbnailRect.size.width = imageSize.width;
thumbnailRect.size.height = imageSize.height;
[image drawInRect:thumbnailRect];
resizedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
}
return resizedImage;
}
+ (id)downloadPicture:(NSString*)pictureURL {
if ([pictureURL hasPrefix:kMediaManagerPrefixForDummyURL] == NO) {
// Create a media loader to download picture
+ (MediaLoader*)downloadMedia:(NSString*)mediaURL mimeType:(NSString *)mimeType {
if ([mediaURL hasPrefix:kMediaManagerPrefixForDummyURL] == NO) {
// Create a media loader to download data
MediaLoader *mediaLoader = [[MediaLoader alloc] init];
[self setMediaLoader:mediaLoader forURL:pictureURL];
[mediaLoader downloadMedia:pictureURL mimeType:@"image/jpeg" success:^(NSString *cacheFilePath) {
[self removeMediaLoaderWithUrl:pictureURL];
[[NSNotificationCenter defaultCenter] postNotificationName:kMediaDownloadDidFinishNotification object:pictureURL userInfo:nil];
// Report this loader
[downloadTableByURL setValue:mediaLoader forKey:mediaURL];
// Launch download
[mediaLoader downloadMedia:mediaURL mimeType:mimeType success:^(NSString *cacheFilePath) {
[downloadTableByURL removeObjectForKey:mediaURL];
[[NSNotificationCenter defaultCenter] postNotificationName:kMediaDownloadDidFinishNotification object:mediaURL userInfo:nil];
} failure:^(NSError *error) {
[self removeMediaLoaderWithUrl:pictureURL];
NSLog(@"Failed to download image (%@): %@", pictureURL, error);
[[NSNotificationCenter defaultCenter] postNotificationName:kMediaDownloadDidFailNotification object:pictureURL userInfo:nil];
[downloadTableByURL removeObjectForKey:mediaURL];
NSLog(@"Failed to download image (%@): %@", mediaURL, error);
[[NSNotificationCenter defaultCenter] postNotificationName:kMediaDownloadDidFailNotification object:mediaURL userInfo:nil];
}];
return mediaLoader;
}
[[NSNotificationCenter defaultCenter] postNotificationName:kMediaDownloadDidFailNotification object:pictureURL userInfo:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:kMediaDownloadDidFailNotification object:mediaURL userInfo:nil];
return nil;
}
+ (id)prepareMedia:(NSString *)mediaURL
mimeType:(NSString *)mimeType
success:(blockMediaLoader_onMediaReady)success
failure:(blockMediaLoader_onError)failure {
id ret = nil;
// Check cache
NSString* filename = [MediaManager getCacheFileNameFor:mediaURL mimeType:mimeType];
if ([[NSFileManager defaultManager] fileExistsAtPath:filename]) {
if (success) {
// Reply synchronously
success (filename);
}
}
else if ([mediaURL hasPrefix:kMediaManagerPrefixForDummyURL] == NO) {
// Create a media loader to download media content
MediaLoader *mediaLoader = [[MediaLoader alloc] init];
[mediaLoader downloadMedia:mediaURL mimeType:mimeType success:success failure:failure];
ret = mediaLoader;
} else {
NSLog(@"Load tmp media from cache failed: %@", mediaURL);
if (failure){
failure(nil);
}
}
return ret;
}
// try to find out a media loader from a media URL
+ (id)mediaLoaderForURL:(NSString*)url {
if (pendingMediaLoadersByURL && url) {
return [pendingMediaLoadersByURL valueForKey:url];
+ (id)existingDownloaderForURL:(NSString*)url {
if (downloadTableByURL && url) {
return [downloadTableByURL valueForKey:url];
}
return nil;
}
+ (void)setMediaLoader:(MediaLoader*)mediaLoader forURL:(NSString*)url {
if (!pendingMediaLoadersByURL) {
pendingMediaLoadersByURL = [[NSMutableDictionary alloc] init];
#pragma mark - Cache Handling
+ (UIImage*)loadCachePictureForURL:(NSString*)pictureURL {
UIImage* res = nil;
NSString* filename = [MediaManager cachePathForMediaURL:pictureURL andType:@"image/jpeg"];
if ([[NSFileManager defaultManager] fileExistsAtPath:filename]) {
NSData* imageContent = [NSData dataWithContentsOfFile:filename options:(NSDataReadingMappedAlways | NSDataReadingUncached) error:nil];
if (imageContent) {
res = [[UIImage alloc] initWithData:imageContent];
}
}
// sanity check
if (mediaLoader && url) {
[pendingMediaLoadersByURL setValue:mediaLoader forKey:url];
}
return res;
}
+ (void)removeMediaLoaderWithUrl:(NSString*)url {
if (url) {
[pendingMediaLoadersByURL removeObjectForKey:url];
}
}
+ (NSString*)cacheMediaData:(NSData*)mediaData forURL:(NSString *)mediaURL mimeType:(NSString *)mimeType {
NSString* filename = [MediaManager getCacheFileNameFor:mediaURL mimeType:mimeType];
+ (NSString*)cacheMediaData:(NSData*)mediaData forURL:(NSString *)mediaURL andType:(NSString *)mimeType {
NSString* filename = [MediaManager cachePathForMediaURL:mediaURL andType:mimeType];
if ([mediaData writeToFile:filename atomically:YES]) {
return filename;
@ -186,6 +100,26 @@ static NSMutableDictionary* pendingMediaLoadersByURL = nil;
}
}
+ (NSString*)cachePathForMediaURL:(NSString*)mediaURL andType:(NSString *)mimeType {
NSString *fileName;
if ([mimeType isEqualToString:@"image/jpeg"]) {
fileName = [NSString stringWithFormat:@"ima%lu.jpg", (unsigned long)mediaURL.hash];
} else if ([mimeType isEqualToString:@"video/mp4"]) {
fileName = [NSString stringWithFormat:@"video%lu.mp4", (unsigned long)mediaURL.hash];
} else if ([mimeType isEqualToString:@"video/quicktime"]) {
fileName = [NSString stringWithFormat:@"video%lu.mov", (unsigned long)mediaURL.hash];
} else {
NSString *extension = @"";
NSArray *components = [mediaURL componentsSeparatedByString:@"."];
if (components && components.count > 1) {
extension = [components lastObject];
}
fileName = [NSString stringWithFormat:@"%lu.%@", (unsigned long)mediaURL.hash, extension];
}
return [[MediaManager getCachePath] stringByAppendingPathComponent:fileName];
}
+ (void)clearCache {
NSError *error = nil;
@ -246,22 +180,6 @@ static NSMutableDictionary* pendingMediaLoadersByURL = nil;
return (NSUInteger)[MediaManager folderSize:mediaCachePath];
}
#pragma mark - Cache handling
+ (UIImage*)loadCachePicture:(NSString*)pictureURL {
UIImage* res = nil;
NSString* filename = [MediaManager getCacheFileNameFor:pictureURL mimeType:@"image/jpeg"];
if ([[NSFileManager defaultManager] fileExistsAtPath:filename]) {
NSData* imageContent = [NSData dataWithContentsOfFile:filename options:(NSDataReadingMappedAlways | NSDataReadingUncached) error:nil];
if (imageContent) {
res = [[UIImage alloc] initWithData:imageContent];
}
}
return res;
}
+ (NSString*)getCachePath {
NSString *cachePath = nil;
@ -280,24 +198,4 @@ static NSMutableDictionary* pendingMediaLoadersByURL = nil;
return cachePath;
}
+ (NSString*)getCacheFileNameFor:(NSString*)mediaURL mimeType:(NSString *)mimeType {
NSString *fileName;
if ([mimeType isEqualToString:@"image/jpeg"]) {
fileName = [NSString stringWithFormat:@"ima%lu.jpg", (unsigned long)mediaURL.hash];
} else if ([mimeType isEqualToString:@"video/mp4"]) {
fileName = [NSString stringWithFormat:@"video%lu.mp4", (unsigned long)mediaURL.hash];
} else if ([mimeType isEqualToString:@"video/quicktime"]) {
fileName = [NSString stringWithFormat:@"video%lu.mov", (unsigned long)mediaURL.hash];
} else {
NSString *extension = @"";
NSArray *components = [mediaURL componentsSeparatedByString:@"."];
if (components && components.count > 1) {
extension = [components lastObject];
}
fileName = [NSString stringWithFormat:@"%lu.%@", (unsigned long)mediaURL.hash, extension];
}
return [[MediaManager getCachePath] stringByAppendingPathComponent:fileName];
}
@end

View file

@ -16,6 +16,7 @@
#import "UploadManager.h"
#import "MediaManager.h"
#import "ConsoleTools.h"
NSString *const kUploadManagerUploadStartTimeKey = @"kUploadManagerUploadStartTimeKey";
NSString *const kUploadManagerStatsStartTimeKey = @"kUploadManagerUploadStartTimeKey";
@ -85,7 +86,7 @@ static NSMutableDictionary* statsByURL = nil;
NSString* progressString = [NSString stringWithFormat:@"%@ / %@", [NSByteCountFormatter stringFromByteCount:totalBytesWritten countStyle:NSByteCountFormatterCountStyleFile], [NSByteCountFormatter stringFromByteCount:totalBytesExpectedToWrite countStyle:NSByteCountFormatterCountStyleFile]];
[dict setValue:progressString forKey:kMediaLoaderProgressStringKey];
[dict setValue:[MediaManager formatSecondsInterval:dataRemainingTime] forKey:kMediaLoaderProgressRemaingTimeKey];
[dict setValue:[ConsoleTools formatSecondsInterval:dataRemainingTime] forKey:kMediaLoaderProgressRemaingTimeKey];
NSString* downloadRateStr = [NSString stringWithFormat:@"%@/s", [NSByteCountFormatter stringFromByteCount:dataRate * 1024 countStyle:NSByteCountFormatterCountStyleFile]];
[dict setValue:downloadRateStr forKey:kMediaLoaderProgressDownloadRateKey];

View file

@ -403,7 +403,7 @@
_hideActivityIndicator = hideActivityIndicator;
if (hideActivityIndicator) {
[self stopActivityIndicator];
} else if ([MediaManager mediaLoaderForURL:imageURL]) {
} else if ([MediaManager existingDownloaderForURL:imageURL]) {
// Loading is in progress, start activity indicator
[self startActivityIndicator];
}
@ -421,7 +421,7 @@
}
// Check whether the image download is in progress
MediaLoader* loader = [MediaManager mediaLoaderForURL:imageURL];
MediaLoader* loader = [MediaManager existingDownloaderForURL:imageURL];
if (loader) {
// Set preview until the image is loaded
self.image = previewImage;
@ -434,7 +434,7 @@
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMediaDownloadEnd:) name:kMediaDownloadDidFailNotification object:nil];
} else {
// Retrieve the image from cache
UIImage* image = [MediaManager loadCachePicture:imageURL];
UIImage* image = [MediaManager loadCachePictureForURL:imageURL];
if (image) {
self.image = image;
[self stopActivityIndicator];
@ -449,7 +449,7 @@
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMediaDownloadProgress:) name:kMediaDownloadProgressNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMediaDownloadEnd:) name:kMediaDownloadDidFinishNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMediaDownloadEnd:) name:kMediaDownloadDidFailNotification object:nil];
[MediaManager downloadPicture:imageURL];
[MediaManager downloadMedia:imageURL mimeType:@"image/jpeg"];
}
}
}
@ -462,7 +462,7 @@
if ([url isEqualToString:imageURL]) {
[self stopActivityIndicator];
// update the image
UIImage* image = [MediaManager loadCachePicture:imageURL];
UIImage* image = [MediaManager loadCachePictureForURL:imageURL];
if (image) {
self.image = image;
}

View file

@ -95,7 +95,7 @@
if (self.message.attachmentURL) {
// check if there is a downlad in progress
MediaLoader *loader = [MediaManager mediaLoaderForURL:self.message.attachmentURL];
MediaLoader *loader = [MediaManager existingDownloaderForURL:self.message.attachmentURL];
NSDictionary *dict = loader.downloadStatsDict;
@ -124,7 +124,7 @@
- (void)cancelDownload {
// get the linked medida loader
MediaLoader *loader = [MediaManager mediaLoaderForURL:self.message.attachmentURL];
MediaLoader *loader = [MediaManager existingDownloaderForURL:self.message.attachmentURL];
if (loader) {
[loader cancel];
}

View file

@ -165,14 +165,14 @@
if (_mxRoomMember.avatarUrl) {
// Check whether the image download is in progress
id loader = [MediaManager mediaLoaderForURL:_mxRoomMember.avatarUrl];
id loader = [MediaManager existingDownloaderForURL:_mxRoomMember.avatarUrl];
if (loader) {
// Add observers
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMediaDownloadEnd:) name:kMediaDownloadDidFinishNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMediaDownloadEnd:) name:kMediaDownloadDidFailNotification object:nil];
} else {
// Retrieve the image from cache
UIImage* image = [MediaManager loadCachePicture:_mxRoomMember.avatarUrl];
UIImage* image = [MediaManager loadCachePictureForURL:_mxRoomMember.avatarUrl];
if (image) {
[self.memberThumbnailButton setImage:image forState:UIControlStateNormal];
[self.memberThumbnailButton setImage:image forState:UIControlStateHighlighted];
@ -184,7 +184,7 @@
// Add observers
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMediaDownloadEnd:) name:kMediaDownloadDidFinishNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMediaDownloadEnd:) name:kMediaDownloadDidFailNotification object:nil];
imageLoader = [MediaManager downloadPicture:_mxRoomMember.avatarUrl];
imageLoader = [MediaManager downloadMedia:_mxRoomMember.avatarUrl mimeType:@"image/jpeg"];
}
}
} else {
@ -205,7 +205,7 @@
if ([url isEqualToString:_mxRoomMember.avatarUrl]) {
// update the image
UIImage* image = [MediaManager loadCachePicture:_mxRoomMember.avatarUrl];
UIImage* image = [MediaManager loadCachePictureForURL:_mxRoomMember.avatarUrl];
if (image == nil) {
image = [UIImage imageNamed:@"default-profile"];
}

View file

@ -30,6 +30,7 @@
#import "MediaManager.h"
#import "UploadManager.h"
#import "ConsoleTools.h"
#define ROOMVIEWCONTROLLER_TYPING_TIMEOUT_MS 20000
@ -78,6 +79,8 @@ NSString *const kCmdResetUserPowerLevel = @"/deop";
NSString *AVAudioSessionCategory;
MPMoviePlayerController *videoPlayer;
MPMoviePlayerController *tmpVideoPlayer;
NSString *selectedVideoURL;
NSString *selectedVideoCachePath;
// used to trap the slide to close the keyboard
UIView* inputAccessoryView;
@ -344,7 +347,7 @@ NSString *const kCmdResetUserPowerLevel = @"/deop";
__weak typeof(self) weakSelf = self;
NSString* url = ((RoomMessageTableCell*)view).message.attachmentURL;
MediaLoader *loader = [MediaManager mediaLoaderForURL:url];
MediaLoader *loader = [MediaManager existingDownloaderForURL:url];
// offer to cancel a download only if there is a pending one
if (loader) {
@ -355,7 +358,7 @@ NSString *const kCmdResetUserPowerLevel = @"/deop";
self.actionMenu.cancelButtonIndex = [self.actionMenu addActionWithTitle:@"OK" style:CustomAlertActionStyleDefault handler:^(CustomAlert *alert) {
// get again the loader, the cell could have been reused.
MediaLoader *loader = [MediaManager mediaLoaderForURL:url];
MediaLoader *loader = [MediaManager existingDownloaderForURL:url];
if (loader) {
[loader cancel];
}
@ -915,22 +918,16 @@ NSString *const kCmdResetUserPowerLevel = @"/deop";
selector:@selector(moviePlayerWillExitFullscreen:)
name:MPMoviePlayerWillExitFullscreenNotification
object:videoPlayer];
[MediaManager prepareMedia:url mimeType:mimetype success:^(NSString *cacheFilePath) {
if (cacheFilePath) {
if (tmpCachedAttachments == nil) {
tmpCachedAttachments = [NSMutableArray array];
}
if ([tmpCachedAttachments indexOfObject:cacheFilePath]) {
[tmpCachedAttachments addObject:cacheFilePath];
}
}
videoPlayer.contentURL = [NSURL fileURLWithPath:cacheFilePath];
selectedVideoURL = url;
selectedVideoCachePath = [MediaManager cachePathForMediaURL:selectedVideoURL andType:mimetype];
if ([[NSFileManager defaultManager] fileExistsAtPath:selectedVideoCachePath]) {
videoPlayer.contentURL = [NSURL fileURLWithPath:selectedVideoCachePath];
[videoPlayer play];
} failure:^(NSError *error) {
[self hideAttachmentView];
//Alert user
[[AppDelegate theDelegate] showErrorAsAlert:error];
}];
} else {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMediaDownloadEnd:) name:kMediaDownloadDidFinishNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMediaDownloadEnd:) name:kMediaDownloadDidFailNotification object:nil];
[MediaManager downloadMedia:selectedVideoURL mimeType:mimetype];
}
}
}
} else if (msgtype == RoomMessageTypeAudio) {
@ -938,9 +935,32 @@ NSString *const kCmdResetUserPowerLevel = @"/deop";
}
}
- (void)onMediaDownloadEnd:(NSNotification *)notif {
if ([notif.object isKindOfClass:[NSString class]]) {
NSString* url = notif.object;
if ([url isEqualToString:selectedVideoURL]) {
// remove the observers
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMediaDownloadDidFinishNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMediaDownloadDidFailNotification object:nil];
if ([[NSFileManager defaultManager] fileExistsAtPath:selectedVideoCachePath]) {
videoPlayer.contentURL = [NSURL fileURLWithPath:selectedVideoCachePath];
[videoPlayer play];
} else {
NSLog(@"Video Download failed"); // TODO we should notify user
[self hideAttachmentView];
}
}
}
}
- (void)hideAttachmentView {
selectedVideoURL = nil;
selectedVideoCachePath = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerWillExitFullscreenNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMediaDownloadDidFinishNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMediaDownloadDidFailNotification object:nil];
[self dismissCustomImageView];
@ -989,7 +1009,7 @@ NSString *const kCmdResetUserPowerLevel = @"/deop";
if (videoThumbnail && selectedVideo) {
// Prepare video thumbnail description
NSUInteger thumbnailSize = ROOM_MESSAGE_MAX_ATTACHMENTVIEW_WIDTH;
UIImage *thumbnail = [MediaManager resize:videoThumbnail toFitInSize:CGSizeMake(thumbnailSize, thumbnailSize)];
UIImage *thumbnail = [ConsoleTools resize:videoThumbnail toFitInSize:CGSizeMake(thumbnailSize, thumbnailSize)];
NSMutableDictionary *thumbnailInfo = [[NSMutableDictionary alloc] init];
[thumbnailInfo setValue:@"image/jpeg" forKey:@"mimetype"];
[thumbnailInfo setValue:[NSNumber numberWithUnsignedInteger:(NSUInteger)thumbnail.size.width] forKey:@"w"];
@ -1405,7 +1425,7 @@ NSString *const kCmdResetUserPowerLevel = @"/deop";
}
UIImage *preview = nil;
if (message.previewURL) {
preview = [MediaManager loadCachePicture:message.previewURL];
preview = [MediaManager loadCachePictureForURL:message.previewURL];
}
[cell.attachmentView setImageURL:url withPreviewImage:preview];
@ -2010,7 +2030,7 @@ NSString *const kCmdResetUserPowerLevel = @"/deop";
// We store temporarily the image in cache, use the localId to build temporary url
NSString *dummyURL = [NSString stringWithFormat:@"%@%@", kMediaManagerPrefixForDummyURL, localEvent.eventId];
NSData *imageData = UIImageJPEGRepresentation(image, 0.5);
NSString *cacheFilePath = [MediaManager cacheMediaData:imageData forURL:dummyURL mimeType:@"image/jpeg"];
NSString *cacheFilePath = [MediaManager cacheMediaData:imageData forURL:dummyURL andType:@"image/jpeg"];
if (cacheFilePath) {
if (tmpCachedAttachments == nil) {
tmpCachedAttachments = [NSMutableArray array];

View file

@ -455,14 +455,14 @@ NSString* const kCommandsDescriptionText = @"The following commands are availabl
currentPictureURL = [avatar_url isEqual:[NSNull null]] ? nil : avatar_url;
if (currentPictureURL) {
// Check whether the image download is in progress
id loader = [MediaManager mediaLoaderForURL:currentPictureURL];
id loader = [MediaManager existingDownloaderForURL:currentPictureURL];
if (loader) {
// Add observers
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMediaDownloadEnd:) name:kMediaDownloadDidFinishNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMediaDownloadEnd:) name:kMediaDownloadDidFailNotification object:nil];
} else {
// Retrieve the image from cache
UIImage* image = [MediaManager loadCachePicture:currentPictureURL];
UIImage* image = [MediaManager loadCachePictureForURL:currentPictureURL];
if (image) {
[self updateAvatarImage:image];
} else {
@ -473,7 +473,7 @@ NSString* const kCommandsDescriptionText = @"The following commands are availabl
// Add observers
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMediaDownloadEnd:) name:kMediaDownloadDidFinishNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMediaDownloadEnd:) name:kMediaDownloadDidFailNotification object:nil];
imageLoader = [MediaManager downloadPicture:currentPictureURL];
imageLoader = [MediaManager downloadMedia:currentPictureURL mimeType:@"image/jpeg"];
}
}
} else {
@ -490,7 +490,7 @@ NSString* const kCommandsDescriptionText = @"The following commands are availabl
if ([url isEqualToString:currentPictureURL]) {
// update the image
UIImage* image = [MediaManager loadCachePicture:currentPictureURL];
UIImage* image = [MediaManager loadCachePictureForURL:currentPictureURL];
if (image == nil) {
image = [UIImage imageNamed:@"default-profile"];
}