Commit f467ca95 authored by Tobias's avatar Tobias

request images from watch if the do not exist on watch

parent c37cebc0
......@@ -17,6 +17,9 @@ extern NSString *const VLCWatchMessageNameSkipBackward;
extern NSString *const VLCWatchMessageNamePlayFile;
extern NSString *const VLCWatchMessageNameSetVolume;
extern NSString *const VLCWatchMessageNameNotification;
extern NSString *const VLCWatchMessageNameRequestThumbnail;
extern NSString *const VLCWatchMessageKeyURIRepresentation;
@interface VLCWatchMessage : NSObject
@property (nonatomic, readonly) NSString *name;
......
......@@ -15,6 +15,10 @@ NSString *const VLCWatchMessageNameSkipBackward = @"skipBackward";
NSString *const VLCWatchMessageNamePlayFile = @"playFile";
NSString *const VLCWatchMessageNameSetVolume = @"setVolume";
NSString *const VLCWatchMessageNameNotification = @"notification";
NSString *const VLCWatchMessageNameRequestThumbnail = @"requestThumbnail";
NSString *const VLCWatchMessageKeyURIRepresentation = @"URIRepresentation";
static NSString *const VLCWatchMessageNameKey = @"name";
static NSString *const VLCWatchMessagePayloadKey = @"payload";
......
/*****************************************************************************
* UIImage+Scaling.h
* VLC for iOS
*****************************************************************************
* Copyright (c) 2015 VideoLAN. All rights reserved.
* $Id$
*
* Authors: Felix Paul Kühne <fkuehne # videolan.org>
*
* Refer to the COPYING file of the official project for license.
*****************************************************************************/
@interface UIImage (Scaling)
+ (UIImage *)scaleImage:(UIImage *)image toFitRect:(CGRect)rect;
@end
/*****************************************************************************
* UIImage+Scaling.m
* VLC for iOS
*****************************************************************************
* Copyright (c) 2015 VideoLAN. All rights reserved.
* $Id$
*
* Authors: Felix Paul Kühne <fkuehne # videolan.org>
*
* Refer to the COPYING file of the official project for license.
*****************************************************************************/
#import <UIKit/UIKit.h>
#import "UIImage+Scaling.h"
#import <AVFoundation/AVFoundation.h>
@implementation UIImage (Scaling)
+ (UIImage *)scaleImage:(UIImage *)image toFitRect:(CGRect)rect
{
CGRect destinationRect = AVMakeRectWithAspectRatioInsideRect(image.size, rect);
CGImageRef cgImage = image.CGImage;
size_t bitsPerComponent = CGImageGetBitsPerComponent(cgImage);
size_t bytesPerRow = CGImageGetBytesPerRow(cgImage);
CGColorSpaceRef colorSpaceRef = CGImageGetColorSpace(cgImage);
CGBitmapInfo bitmapInfoRef = CGImageGetBitmapInfo(cgImage);
CGContextRef contextRef = CGBitmapContextCreate(NULL,
destinationRect.size.width,
destinationRect.size.height,
bitsPerComponent,
bytesPerRow,
colorSpaceRef,
bitmapInfoRef);
CGContextSetInterpolationQuality(contextRef, kCGInterpolationLow);
CGContextDrawImage(contextRef, (CGRect){CGPointZero, destinationRect.size}, cgImage);
return [UIImage imageWithCGImage:CGBitmapContextCreateImage(contextRef)];
}
@end
......@@ -18,6 +18,6 @@
+ (UIImage *)thumbnailForManagedObject:(NSManagedObject *)object refreshCache:(BOOL)refreshCache;
+ (UIImage *)thumbnailForManagedObject:(NSManagedObject *)object toFitRect:(CGRect)rect shouldReplaceCache:(BOOL)replaceCache;
+ (UIImage *)thumbnailForManagedObject:(NSManagedObject *)object refreshCache:(BOOL)refreshCache toFitRect:(CGRect)rect scale:(CGFloat)scale shouldReplaceCache:(BOOL)replaceCache;
@end
......@@ -16,10 +16,10 @@
#import "VLCThumbnailsCache.h"
#import <CommonCrypto/CommonDigest.h>
#import "UIImage+Blur.h"
#import "UIImage+Scaling.h"
#import <WatchKit/WatchKit.h>
#import <CoreData/CoreData.h>
#import <MediaLibraryKit/MediaLibraryKit.h>
#import <MediaLibraryKit/UIImage+MLKit.h>
#if TARGET_OS_IOS
#import <UIKit/UIKit.h>
#endif
......@@ -108,16 +108,16 @@
return thumbnail;
}
+ (UIImage *)thumbnailForManagedObject:(NSManagedObject *)object toFitRect:(CGRect)rect shouldReplaceCache:(BOOL)replaceCache
+ (UIImage *)thumbnailForManagedObject:(NSManagedObject *)object refreshCache:(BOOL)refreshCache toFitRect:(CGRect)rect scale:(CGFloat)scale shouldReplaceCache:(BOOL)replaceCache;
{
UIImage *rawThumbnail = [self thumbnailForManagedObject:object];
UIImage *rawThumbnail = [self thumbnailForManagedObject:object refreshCache:refreshCache];
CGSize rawSize = rawThumbnail.size;
/* scaling is potentially expensive, so we should avoid re-doing it for the same size over and over again */
if (rawSize.width <= rect.size.width && rawSize.height <= rect.size.height)
return rawThumbnail;
UIImage *scaledImage = [UIImage scaleImage:rawThumbnail toFitRect:rect];
UIImage *scaledImage = [UIImage scaleImage:rawThumbnail toFitRect:rect scale:scale];
if (replaceCache)
[[VLCThumbnailsCache sharedThumbnailCache] _setThumbnail:scaledImage forObjectId:object.objectID];
......@@ -266,7 +266,7 @@
- (UIImage *)clusterThumbFromFiles:(NSArray *)files andNumber:(NSUInteger)fileNumber blur:(BOOL)blurImage
{
UIImage *clusterThumb;
CGSize imageSize;
CGSize imageSize = CGSizeZero;
// TODO: correct for watch
#ifndef TARGET_OS_WATCH
if (_currentDeviceIdiom == UIUserInterfaceIdiomPad) {
......
......@@ -17,6 +17,7 @@
#import <MediaPlayer/MediaPlayer.h>
#import <MediaLibraryKit/UIImage+MLKit.h>
#import <WatchKit/WatchKit.h>
#import "VLCThumbnailsCache.h"
@interface VLCWatchCommunication()
@property (nonatomic, strong) NSOperationQueue *thumbnailingQueue;
......@@ -105,6 +106,8 @@ static VLCWatchCommunication *_singeltonInstance = nil;
[self playFileFromWatch:message];
} else if ([name isEqualToString:VLCWatchMessageNameSetVolume]) {
[self setVolumeFromWatch:message];
} else if ([name isEqualToString:VLCWatchMessageNameRequestThumbnail]) {
[self requestThumnail:message];
} else {
APLog(@"Did not handle request from WatchKit Extension: %@",message);
}
......@@ -148,7 +151,7 @@ static VLCWatchCommunication *_singeltonInstance = nil;
MLFile *currentFile = [VLCPlaybackController sharedInstance].currentlyPlayingMediaFile;
NSString *URIString = currentFile.objectID.URIRepresentation.absoluteString;
if (URIString) {
response[@"URIRepresentation"] = URIString;
response[VLCWatchMessageKeyURIRepresentation] = URIString;
}
response[@"volume"] = @([MPMusicPlayerController applicationMusicPlayer].volume);
......@@ -156,6 +159,15 @@ static VLCWatchCommunication *_singeltonInstance = nil;
return response;
}
- (void)requestThumnail:(VLCWatchMessage *)message {
NSString *uriString = message.payload[VLCWatchMessageKeyURIRepresentation];
NSURL *url = [NSURL URLWithString:uriString];
NSManagedObject *object = [[MLMediaLibrary sharedMediaLibrary] objectForURIRepresentation:url];
if (object) {
[self transferThumbnailForObject:object refreshCache:NO];
}
}
#pragma mark - Notifications
- (void)startRelayingNotificationName:(nullable NSString *)name object:(nullable id)object {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(relayNotification:) name:name object:object];
......@@ -215,19 +227,22 @@ static VLCWatchCommunication *_singeltonInstance = nil;
[[WCSession defaultSession] transferFile:tmpURL metadata:metadata];
}
- (void)didUpdateThumbnail:(NSNotification *)notification {
MLFile *file = notification.object;
if(![file isKindOfClass:[MLFile class]])
return;
- (void)transferThumbnailForObject:(NSManagedObject *__nonnull)object refreshCache:(BOOL)refresh{
UIImage *image = file.computedThumbnail;
NSManagedObjectID *objectID = file.objectID;
CGRect bounds = [WKInterfaceDevice currentDevice].screenBounds;
CGFloat scale = [WKInterfaceDevice currentDevice].screenScale;
[self.thumbnailingQueue addOperationWithBlock:^{
UIImage *scaledImage = [UIImage scaleImage:image toFitRect:bounds scale:scale];
[self transferImage:scaledImage forObjectID:objectID];
UIImage *scaledImage = [VLCThumbnailsCache thumbnailForManagedObject:object refreshCache:refresh toFitRect:bounds scale:scale shouldReplaceCache:NO];
[self transferImage:scaledImage forObjectID:object.objectID];
}];
}
- (void)didUpdateThumbnail:(NSNotification *)notification {
NSManagedObject *object = notification.object;
if(![object isKindOfClass:[NSManagedObject class]])
return;
[self transferThumbnailForObject:object refreshCache:YES];
}
- (void)transferImage:(UIImage *)image forObjectID:(NSManagedObjectID *)objectID {
......@@ -239,8 +254,7 @@ static VLCWatchCommunication *_singeltonInstance = nil;
[data writeToURL:tmpURL atomically:YES];
NSDictionary *metaData = @{@"filetype" : @"thumbnail",
@"URIRepresentation" : objectID.URIRepresentation.absoluteString};
VLCWatchMessageKeyURIRepresentation : objectID.URIRepresentation.absoluteString};
NSArray<WCSessionFileTransfer *> *outstandingtransfers = [[WCSession defaultSession] outstandingFileTransfers];
[outstandingtransfers enumerateObjectsUsingBlock:^(WCSessionFileTransfer * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
......
......@@ -85,7 +85,7 @@ static NSString *const VLCNowPlayingUpdateNotification = @"VLCPlaybackController
NSDictionary *dict = [VLCWatchMessage messageDictionaryForName:VLCWatchMessageNameGetNowPlayingInfo];
[[WCSession defaultSession] sendMessage:dict replyHandler:^(NSDictionary<NSString *,id> * _Nonnull replyInfo) {
MLFile *file = nil;
NSString *uriString = replyInfo[@"URIRepresentation"];
NSString *uriString = replyInfo[VLCWatchMessageKeyURIRepresentation];
if (uriString) {
NSURL *uriRepresentation = [NSURL URLWithString:uriString];
file = [MLFile fileForURIRepresentation:uriRepresentation];
......@@ -131,7 +131,7 @@ static NSString *const VLCNowPlayingUpdateNotification = @"VLCPlaybackController
- (void)loadThumbnailForFile:(MLFile *)file
{
UIImage *image = [VLCThumbnailsCache thumbnailForManagedObject:file toFitRect:CGRectMake(0., 0., _screenBounds.size.width * _screenScale, _screenBounds.size.height * _screenScale) shouldReplaceCache:NO];
UIImage *image = [VLCThumbnailsCache thumbnailForManagedObject:file refreshCache:YES toFitRect:_screenBounds scale:_screenScale shouldReplaceCache:NO];
[self.playElementsGroup performSelectorOnMainThread:@selector(setBackgroundImage:) withObject:image waitUntilDone:NO];
}
......
......@@ -13,12 +13,14 @@
#import "VLCRowController.h"
#import "WKInterfaceObject+VLCProgress.h"
#import "VLCThumbnailsCache.h"
#import "VLCWatchMessage.h"
#import <WatchConnectivity/WatchConnectivity.h>
@interface VLCRowController()
@property (nonatomic, weak, readwrite) id mediaLibraryObject;
@property (nonatomic, readonly) CGRect thumbnailSize;
@property (nonatomic, readonly) CGFloat rowWidth;
@property (nonatomic, readonly) CGFloat scale;
@property (nonatomic) UIImage *rawBackgroundImage;
@end
......@@ -41,11 +43,12 @@
CGRect screenRect = currentDevice.screenBounds;
CGFloat screenScale = currentDevice.screenScale;
_thumbnailSize = CGRectMake(0,
0,
screenRect.size.width * screenScale,
120. * screenScale
);
_rowWidth = screenRect.size.width * screenScale;
0,
screenRect.size.width,
120.
);
_rowWidth = screenRect.size.width;
_scale = screenScale;
}
- (void)configureWithMediaLibraryObject:(id)storageObject
......@@ -95,9 +98,28 @@
self.mediaLibraryObject = storageObject;
}
- (void)requestBackgroundImageForObjectID:(NSManagedObjectID *)objectID {
NSDictionary *dict = [VLCWatchMessage messageDictionaryForName:VLCWatchMessageNameRequestThumbnail
payload:@{VLCWatchMessageKeyURIRepresentation : objectID.URIRepresentation.absoluteString}];
[[WCSession defaultSession] sendMessage:dict replyHandler:nil errorHandler:nil];
}
- (void)backgroundThumbnailSetter:(NSArray *)array
{
UIImage *backgroundImage = [VLCThumbnailsCache thumbnailForManagedObject:array[1] toFitRect:_thumbnailSize shouldReplaceCache:YES];
WKInterfaceGroup *interfaceGroup = array.firstObject;
NSManagedObject *managedObject = array[1];
UIImage *backgroundImage = [VLCThumbnailsCache thumbnailForManagedObject:managedObject
refreshCache:NO
toFitRect:_thumbnailSize
scale:_scale
shouldReplaceCache:YES];
if (!backgroundImage) {
[self requestBackgroundImageForObjectID:managedObject.objectID];
return;
}
// don't redo image processing if no necessary
if ([self.rawBackgroundImage isEqual:backgroundImage]) {
......@@ -108,7 +130,7 @@
UIImage *gradient = [UIImage imageNamed:@"tableview-gradient"];
CGSize newSize = backgroundImage ? backgroundImage.size : CGSizeMake(_rowWidth, 120.);
UIGraphicsBeginImageContext(newSize);
UIGraphicsBeginImageContextWithOptions(newSize, YES, _scale);
if (backgroundImage)
[backgroundImage drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
......@@ -123,7 +145,7 @@
UIGraphicsEndImageContext();
[array.firstObject performSelectorOnMainThread:@selector(setBackgroundImage:) withObject:newImage waitUntilDone:NO];
[interfaceGroup performSelectorOnMainThread:@selector(setBackgroundImage:) withObject:newImage waitUntilDone:NO];
}
- (void)setMediaTitle:(NSString *)mediaTitle {
......
......@@ -604,8 +604,6 @@
7D8139CD1865211900D65504 /* ms */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ms; path = ms.lproj/Localizable.strings; sourceTree = "<group>"; };
7D84E4C51B41AB2800EA7D1F /* VideoToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = VideoToolbox.framework; path = System/Library/Frameworks/VideoToolbox.framework; sourceTree = SDKROOT; };
7D84E4C81B41ABCE00EA7D1F /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; };
7D871F4F1AD7257100348D27 /* UIImage+Scaling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIImage+Scaling.h"; path = "Sources/UIImage+Scaling.h"; sourceTree = SOURCE_ROOT; };
7D871F501AD7257100348D27 /* UIImage+Scaling.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIImage+Scaling.m"; path = "Sources/UIImage+Scaling.m"; sourceTree = SOURCE_ROOT; };
7D89786E185DED88009BAB5D /* VLCDownloadViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = VLCDownloadViewController.xib; path = Resources/VLCDownloadViewController.xib; sourceTree = SOURCE_ROOT; };
7D89787C185DF794009BAB5D /* VLCOpenNetworkStreamViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = VLCOpenNetworkStreamViewController.xib; path = Resources/VLCOpenNetworkStreamViewController.xib; sourceTree = SOURCE_ROOT; };
7D8E19271B6BC186000D7C74 /* VLC WatchKit App.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "VLC WatchKit App.entitlements"; sourceTree = "<group>"; };
......@@ -1628,8 +1626,6 @@
7D3784C7183A9972009EE944 /* UIDevice+VLC.m */,
7D168F7218D4A317003FAF59 /* UIImage+Blur.h */,
7D168F7318D4A33F003FAF59 /* UIImage+Blur.m */,
7D871F4F1AD7257100348D27 /* UIImage+Scaling.h */,
7D871F501AD7257100348D27 /* UIImage+Scaling.m */,
7DF9352D1958AB0600E60FD4 /* UIColor+Presets.h */,
7DF9352E1958AB0600E60FD4 /* UIColor+Presets.m */,
);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment