Merge branch 'feature/video_molecule' into 'develop'

Feature/video molecule

See merge request BPHV_MIPS/mvm_core!143
This commit is contained in:
Hedden, Kyle Matthew 2021-02-12 17:30:44 -05:00
commit a480b4b6c9
2 changed files with 66 additions and 0 deletions

View File

@ -9,6 +9,8 @@
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <AVKit/AVKit.h>
@class MVMCoreErrorObject;
//block returned when getting image
//parameters are UIImage object for the image, NSData for gif images, UIImage object for the image, A BOOL to indicate if it is a fall back image.
@ -152,4 +154,13 @@ typedef void(^MVMCoreGetImageBlock)(UIImage * _Nullable, NSData * _Nullable, BOO
// clears the image cache
- (void)clearImageCache;
#pragma mark - Video Functions
/// Loads an AVPlayerAsset from the shared asset cache. Uses default track keys of "duration" and "playable".
- (void)playerAssetFromFileName:(nonnull NSString *)filename onComplete:(void(^_Nonnull)(AVAsset * _Nullable, NSString * _Nonnull, MVMCoreErrorObject * _Nullable))completionHandler;
/// Loads an AVPlayerAsset from the shared asset cache.
- (void)playerAssetFromFileName:(nonnull NSString *)filename trackKeys:(nonnull NSArray *)trackKeys onComplete:(void(^_Nonnull)(AVAsset * _Nullable, NSString * _Nonnull, MVMCoreErrorObject * _Nullable))completionHandler;
@end

View File

@ -15,6 +15,8 @@
#import "MVMCoreConstants.h"
#import "MVMCoreActionUtility.h"
#import "MVMCoreLoggingHandler.h"
#import "MVMCoreDispatchUtility.h"
#import "MVMCoreErrorConstants.h"
@interface MVMCoreCache ()
@ -34,6 +36,9 @@
// For thread safety
@property (strong, nonatomic) dispatch_queue_t imageCacheQueue;
@property (nonnull, strong, nonatomic) dispatch_queue_t videoQueue;
@property (nullable, strong, nonatomic) NSCache *playerItemCache;
@end
@ -58,6 +63,9 @@ static NSString * const STATIC_CACHE_COMPONENT = @"StaticCache.txt";
self.imageCacheQueue = dispatch_queue_create("imgCache", DISPATCH_QUEUE_CONCURRENT);
self.imageBundles = [NSMutableArray array];
self.videoQueue = dispatch_queue_create("video_queue", dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_USER_INTERACTIVE, 0));
self.playerItemCache = [[NSCache alloc] init];
}
return self;
}
@ -664,6 +672,7 @@ static NSString * const STATIC_CACHE_COMPONENT = @"StaticCache.txt";
dispatch_barrier_async(self.imageCacheQueue, ^{
[self.imgCache removeAllObjects];
});
[self.playerItemCache removeAllObjects];
}
- (void)removeImageFromCache:(nonnull NSString *)imageName {
@ -691,4 +700,50 @@ static NSString * const STATIC_CACHE_COMPONENT = @"StaticCache.txt";
}
}
#pragma mark - Video Functions
- (void)playerAssetFromFileName:(NSString *)filename onComplete:(void(^)(AVAsset * _Nullable, NSString * _Nonnull, MVMCoreErrorObject * _Nullable))completionHandler {
[self playerAssetFromFileName:filename trackKeys:@[@"playable",@"duration"] onComplete:completionHandler];
}
- (void)playerAssetFromFileName:(NSString *)filename trackKeys:(NSArray *)trackKeys onComplete:(void(^)(AVAsset * _Nullable, NSString * _Nonnull, MVMCoreErrorObject * _Nullable))completionHandler {
[MVMCoreDispatchUtility performBlock:^{
//get the video url, can be downloaded or assets
NSURL *url;
MVMCoreErrorObject *error = nil;
__block AVAsset *item = [self.playerItemCache objectForKey:filename];
if (!item) {
if ([filename hasPrefix:@"http"]) {
url = [NSURL URLWithString:filename];
} else {
url = [[MVMCoreGetterUtility bundleForMVMCore] URLForResource:filename withExtension:@"mp4"];
}
if (url) {
item = [AVURLAsset URLAssetWithURL:url options:@{AVURLAssetPreferPreciseDurationAndTimingKey:@YES}];
[self.playerItemCache setObject:item forKey:filename]; // Set initial vanilla AVURLAsset.
} else {
error = [[MVMCoreErrorObject alloc] initWithTitle:nil messageToLog:[NSString stringWithFormat:@"Invalid URL: %@", filename] code:0 domain:ErrorDomainNative location:nil];
}
} else {
MVMCoreLog(@"Loading video from cache: %@", filename);
}
if (!item) {
if (!error) {
error = [[MVMCoreErrorObject alloc] initWithTitle:nil messageToLog:[NSString stringWithFormat:@"Failed to initialize asset for URL: %@", filename] code:0 domain:ErrorDomainNative location:nil];
}
[MVMCoreDispatchUtility performBlockOnMainThread:^{
completionHandler(nil, filename, error);
}];
} else {
// Load the duration key up front off of the main thread. Later duration will be used for seek and loop calculations.
[item loadValuesAsynchronouslyForKeys:trackKeys completionHandler:^{
[MVMCoreDispatchUtility performBlockOnMainThread:^{
completionHandler(item, filename, error);
}];
}];
}
} onQueue:self.videoQueue];
}
@end