Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Video instruction step presentation improvements #1291

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions ResearchKit/Common/ORKStepContentView.m
Expand Up @@ -185,6 +185,7 @@ - (void)setupTopContentImageView {
_topContentImageView = [UIImageView new];
}
_topContentImageView.contentMode = UIViewContentModeScaleAspectFit;
_topContentImageView.clipsToBounds = YES;
[_topContentImageView setBackgroundColor:ORKColor(ORKTopContentImageViewBackgroundColorKey)];
[self addSubview:_topContentImageView];
[self setTopContentImageViewConstraints];
Expand Down
1 change: 1 addition & 0 deletions ResearchKit/Common/ORKVideoInstructionStep.m
Expand Up @@ -45,6 +45,7 @@ - (instancetype)initWithIdentifier:(NSString *)identifier {
self = [super initWithIdentifier:identifier];
if (self) {
_thumbnailTime = 0;
self.imageContentMode = UIViewContentModeScaleAspectFill;
}
return self;
}
Expand Down
69 changes: 41 additions & 28 deletions ResearchKit/Common/ORKVideoInstructionStepViewController.m
Expand Up @@ -32,7 +32,7 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
#import "ORKVideoInstructionStepViewController.h"
#import "ORKInstructionStepViewController_Internal.h"
#import "ORKStepViewController_Internal.h"
#import "ORKInstructionStepView.h"
#import "ORKStepContentView.h"
#import "ORKVideoInstructionStepResult.h"
#import "AVFoundation/AVFoundation.h"
#import <AVKit/AVKit.h>
Expand Down Expand Up @@ -79,25 +79,27 @@ - (void)stepDidChange {
[super stepDidChange];
_playbackStoppedTime = NAN;
_playbackCompleted = NO;
//FIXME: video instruction step needs to adopt ORKInstructionStepContainerView
// if (self.step && [self isViewLoaded] && [self videoInstructionStep].image) {
// UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] init];
// [tapRecognizer addTarget:self action:@selector(play)];
// [self.stepView.instructionImageView addGestureRecognizer:tapRecognizer];
//
// if (self.stepView.instructionImageView.image) {
// UIImageView *playImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"play" inBundle:ORKBundle() compatibleWithTraitCollection:nil]];
// self.stepView.instructionImageView.userInteractionEnabled = YES;
// [self.stepView.instructionImageView addSubview:playImageView];
//
// playImageView.translatesAutoresizingMaskIntoConstraints = NO;
//
// NSLayoutConstraint* xConstraint = [NSLayoutConstraint constraintWithItem:self.stepView.instructionImageView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:playImageView attribute:NSLayoutAttributeCenterX multiplier:1 constant:0];
// NSLayoutConstraint* yConstraint = [NSLayoutConstraint constraintWithItem:self.stepView.instructionImageView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:playImageView attribute:NSLayoutAttributeCenterY multiplier:1 constant:0];
//
// [self.stepView.instructionImageView addConstraints:@[xConstraint, yConstraint]];
// }
// }

if (self.step && [self isViewLoaded] && [self videoInstructionStep].image) {
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] init];
[tapRecognizer addTarget:self action:@selector(play)];
[self.stepView.stepContentView addGestureRecognizer:tapRecognizer];

if (self.stepView.stepTopContentImage) {
UIImageView *playImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"play" inBundle:ORKBundle() compatibleWithTraitCollection:nil]];
self.stepView.stepContentView.userInteractionEnabled = YES;
[self.stepView.stepContentView addSubview:playImageView];

playImageView.translatesAutoresizingMaskIntoConstraints = NO;

NSLayoutConstraint* xConstraint = [NSLayoutConstraint constraintWithItem:self.stepView.stepContentView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:playImageView attribute:NSLayoutAttributeCenterX multiplier:1 constant:0];

CGFloat yOffSet = ORKStepContainerTopContentHeightForWindow(self.view.window)/2 - playImageView.frame.size.height/2;
NSLayoutConstraint* yConstraint = [NSLayoutConstraint constraintWithItem:playImageView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.stepView.stepContentView attribute:NSLayoutAttributeTop multiplier:1 constant:yOffSet];

[self.stepView.stepContentView addConstraints:@[xConstraint, yConstraint]];
}
}
}

- (void)setThumbnailImageFromAsset {
Expand All @@ -108,14 +110,25 @@ - (void)setThumbnailImageFromAsset {
self.videoInstructionStep.image = nil;
return;
}
AVAsset* asset = [AVAsset assetWithURL:[self videoInstructionStep].videoURL];
CMTime duration = [asset duration];
duration.value = MIN([self videoInstructionStep].thumbnailTime, duration.value / duration.timescale) * duration.timescale;
AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
CGImageRef thumbnailImageRef = [imageGenerator copyCGImageAtTime:duration actualTime:NULL error:NULL];
UIImage *thumbnailImage = [UIImage imageWithCGImage:thumbnailImageRef];
CGImageRelease(thumbnailImageRef);
[self videoInstructionStep].image = thumbnailImage;

[self videoInstructionStep].image = [UIImage imageNamed:@"placeholder"];

ORKWeakTypeOf(self) weakSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
ORKStrongTypeOf(self) strongSelf = weakSelf;
AVAsset* asset = [AVAsset assetWithURL:[strongSelf videoInstructionStep].videoURL];
CMTime duration = [asset duration];
duration.value = MIN([strongSelf videoInstructionStep].thumbnailTime, duration.value / duration.timescale) * duration.timescale;
AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
CGImageRef thumbnailImageRef = [imageGenerator copyCGImageAtTime:duration actualTime:NULL error:NULL];
UIImage *thumbnailImage = [UIImage imageWithCGImage:thumbnailImageRef];
CGImageRelease(thumbnailImageRef);

dispatch_async(dispatch_get_main_queue(), ^(void) {
[strongSelf videoInstructionStep].image = thumbnailImage;
[strongSelf stepDidChange];
});
});
}

- (void)play {
Expand Down
@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "placeholder.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.