added ASDefaultPlayButton, but need to make drawing dynamic so its always a centered circle, also fixed video player preview layer stuff

This commit is contained in:
Luke Parham 2016-01-28 01:09:01 -08:00
parent f696eb7476
commit 3b38559c4d
7 changed files with 143 additions and 16 deletions

View File

@ -360,6 +360,8 @@
ACF6ED611B178DC700DA7C62 /* ASOverlayLayoutSpecSnapshotTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED591B178DC700DA7C62 /* ASOverlayLayoutSpecSnapshotTests.mm */; };
ACF6ED621B178DC700DA7C62 /* ASRatioLayoutSpecSnapshotTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED5A1B178DC700DA7C62 /* ASRatioLayoutSpecSnapshotTests.mm */; };
ACF6ED631B178DC700DA7C62 /* ASStackLayoutSpecSnapshotTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED5B1B178DC700DA7C62 /* ASStackLayoutSpecSnapshotTests.mm */; };
AEB7B01A1C5962EA00662EF4 /* ASDefaultPlayButton.h in Headers */ = {isa = PBXBuildFile; fileRef = AEB7B0181C5962EA00662EF4 /* ASDefaultPlayButton.h */; };
AEB7B01B1C5962EA00662EF4 /* ASDefaultPlayButton.m in Sources */ = {isa = PBXBuildFile; fileRef = AEB7B0191C5962EA00662EF4 /* ASDefaultPlayButton.m */; };
AEEC47E11C20C2DD00EC1693 /* ASVideoNode.h in Headers */ = {isa = PBXBuildFile; fileRef = AEEC47DF1C20C2DD00EC1693 /* ASVideoNode.h */; };
AEEC47E21C20C2DD00EC1693 /* ASVideoNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEC47E01C20C2DD00EC1693 /* ASVideoNode.mm */; };
AEEC47E41C21D3D200EC1693 /* ASVideoNodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = AEEC47E31C21D3D200EC1693 /* ASVideoNodeTests.m */; };
@ -778,6 +780,8 @@
ACF6ED591B178DC700DA7C62 /* ASOverlayLayoutSpecSnapshotTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASOverlayLayoutSpecSnapshotTests.mm; sourceTree = "<group>"; };
ACF6ED5A1B178DC700DA7C62 /* ASRatioLayoutSpecSnapshotTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASRatioLayoutSpecSnapshotTests.mm; sourceTree = "<group>"; };
ACF6ED5B1B178DC700DA7C62 /* ASStackLayoutSpecSnapshotTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASStackLayoutSpecSnapshotTests.mm; sourceTree = "<group>"; };
AEB7B0181C5962EA00662EF4 /* ASDefaultPlayButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASDefaultPlayButton.h; sourceTree = "<group>"; };
AEB7B0191C5962EA00662EF4 /* ASDefaultPlayButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASDefaultPlayButton.m; sourceTree = "<group>"; };
AEEC47DF1C20C2DD00EC1693 /* ASVideoNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASVideoNode.h; sourceTree = "<group>"; };
AEEC47E01C20C2DD00EC1693 /* ASVideoNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASVideoNode.mm; sourceTree = "<group>"; };
AEEC47E31C21D3D200EC1693 /* ASVideoNodeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASVideoNodeTests.m; sourceTree = "<group>"; };
@ -1153,6 +1157,8 @@
ACF6ED4A1B17847A00DA7C62 /* ASStackUnpositionedLayout.mm */,
0442850B1BAA64EC00D16268 /* ASMultidimensionalArrayUtils.h */,
0442850C1BAA64EC00D16268 /* ASMultidimensionalArrayUtils.mm */,
AEB7B0181C5962EA00662EF4 /* ASDefaultPlayButton.h */,
AEB7B0191C5962EA00662EF4 /* ASDefaultPlayButton.m */,
);
path = Private;
sourceTree = "<group>";
@ -1315,6 +1321,7 @@
205F0E191B37339C007741D0 /* ASAbstractLayoutController.h in Headers */,
058D0A82195D060300B7D73C /* ASAssert.h in Headers */,
0516FA3C1A15563400B4EBED /* ASAvailability.h in Headers */,
AEB7B01A1C5962EA00662EF4 /* ASDefaultPlayButton.h in Headers */,
ACF6ED1A1B17843500DA7C62 /* ASBackgroundLayoutSpec.h in Headers */,
058D0A83195D060300B7D73C /* ASBaseDefines.h in Headers */,
054963491A1EA066000F8E56 /* ASBasicImageDownloader.h in Headers */,
@ -1801,6 +1808,7 @@
A32FEDD61C501B6A004F642A /* ASTextKitFontSizeAdjuster.m in Sources */,
058D0A1B195D050800B7D73C /* ASMutableAttributedStringBuilder.m in Sources */,
055B9FA91A1C154B00035D6D /* ASNetworkImageNode.mm in Sources */,
AEB7B01B1C5962EA00662EF4 /* ASDefaultPlayButton.m in Sources */,
ACF6ED2C1B17843500DA7C62 /* ASOverlayLayoutSpec.mm in Sources */,
0442850F1BAA64EC00D16268 /* ASMultidimensionalArrayUtils.mm in Sources */,
257754921BED28F300737CA5 /* ASEqualityHashHelpers.mm in Sources */,

View File

@ -8,12 +8,6 @@
#import <AsyncDisplayKit/AsyncDisplayKit.h>
typedef NS_ENUM(NSUInteger, ASVideoGravity) {
ASVideoGravityResizeAspect,
ASVideoGravityResizeAspectFill,
ASVideoGravityResize
};
@protocol ASVideoNodeDelegate;
// If you need ASVideoNode, please use AsyncDisplayKit master until this comment is removed.

View File

@ -7,6 +7,7 @@
*/
#import "ASVideoNode.h"
#import "ASDefaultPlayButton.h"
@interface ASVideoNode ()
{
@ -43,12 +44,14 @@
return nil;
}
_previewQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
#if DEBUG
NSLog(@"*** Warning: ASVideoNode is a new component - the 1.9.6 version may cause performance hiccups.");
#endif
_previewQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
self.playButton = [[ASDefaultPlayButton alloc] init];
self.gravity = AVLayerVideoGravityResizeAspect;
[self addTarget:self action:@selector(tapped) forControlEvents:ASControlNodeEventTouchUpInside];
@ -114,6 +117,8 @@
_playerNode.frame = bounds;
_playerNode.layer.frame = bounds;
_playButton.frame = bounds;
CGFloat horizontalDiff = (bounds.size.width - _playButton.bounds.size.width)/2;
CGFloat verticalDiff = (bounds.size.height - _playButton.bounds.size.height)/2;
_playButton.hitTestSlop = UIEdgeInsetsMake(-verticalDiff, -horizontalDiff, -verticalDiff, -horizontalDiff);
@ -142,13 +147,23 @@
} else {
dispatch_async(_previewQueue, ^{
AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:_asset];
imageGenerator.appliesPreferredTrackTransform = YES;
[imageGenerator generateCGImagesAsynchronouslyForTimes:@[[NSValue valueWithCMTime:CMTimeMake(0, 1)]] completionHandler:^(CMTime requestedTime, CGImageRef _Nullable image, CMTime actualTime, AVAssetImageGeneratorResult result, NSError * _Nullable error) {
UIImage *theImage = [UIImage imageWithCGImage:image];
_placeholderImageNode = [[ASImageNode alloc] init];
_placeholderImageNode.layerBacked = YES;
_placeholderImageNode.image = theImage;
if ([_gravity isEqualToString:AVLayerVideoGravityResize]) {
_placeholderImageNode.contentMode = UIViewContentModeRedraw;
}
if ([_gravity isEqualToString:AVLayerVideoGravityResizeAspect]) {
_placeholderImageNode.contentMode = UIViewContentModeScaleAspectFit;
}
if ([_gravity isEqual:AVLayerVideoGravityResizeAspectFill]) {
_placeholderImageNode.contentMode = UIViewContentModeScaleAspectFill;
}
dispatch_async(dispatch_get_main_queue(), ^{
_placeholderImageNode.frame = self.bounds;
@ -321,12 +336,19 @@
return playerLayer;
}];
if ([self.subnodes containsObject:_playButton]) {
[self insertSubnode:_playerNode belowSubnode:_playButton];
} else {
[self addSubnode:_playerNode];
}
}
[_player play];
_shouldBePlaying = YES;
[UIView animateWithDuration:0.15 animations:^{
_playButton.alpha = 0.0;
}];
if (![self ready] && _shouldBePlaying && (self.interfaceState & ASInterfaceStateVisible)) {
[self addSubnode:_spinner];
@ -346,7 +368,9 @@
[_player pause];
[((UIActivityIndicatorView *)_spinner.view) stopAnimating];
_shouldBePlaying = NO;
[UIView animateWithDuration:0.15 animations:^{
_playButton.alpha = 1.0;
}];
}
- (BOOL)isPlaying

View File

@ -0,0 +1,13 @@
//
// ASDefaultPlayButton.h
// AsyncDisplayKit
//
// Created by Luke Parham on 1/27/16.
// Copyright © 2016 Facebook. All rights reserved.
//
#import <AsyncDisplayKit/AsyncDisplayKit.h>
@interface ASDefaultPlayButton : ASButtonNode
@end

View File

@ -0,0 +1,72 @@
//
// ASDefaultPlayButton.m
// AsyncDisplayKit
//
// Created by Luke Parham on 1/27/16.
// Copyright © 2016 Facebook. All rights reserved.
//
#import "ASDefaultPlayButton.h"
@implementation ASDefaultPlayButton
- (instancetype)init
{
if (!(self = [super init])) {
return nil;
}
self.opaque = NO;
return self;
}
+ (void)drawRect:(CGRect)bounds withParameters:(id<NSObject>)parameters isCancelled:(asdisplaynode_iscancelled_block_t)isCancelledBlock isRasterizing:(BOOL)isRasterizing
{
CGRect buttonBounds;
buttonBounds = CGRectMake(bounds.size.width/4, bounds.size.height/4, bounds.size.width/2, bounds.size.height/2);
if (bounds.size.width < bounds.size.height) {
//then use the width to determine the rect size then calculate the origin x y
buttonBounds = CGRectMake(bounds.size.width/4, bounds.size.width/4, bounds.size.width/2, bounds.size.width/2);
}
if (bounds.size.width > bounds.size.height) {
//use the height
buttonBounds = CGRectMake(bounds.size.height/4, bounds.size.height/4, bounds.size.height/2, bounds.size.height/2);
}
if (bounds.size.width == bounds.size.height) {
//square so easy
buttonBounds = CGRectMake(bounds.size.width/4, bounds.size.height/4, bounds.size.width/2, bounds.size.height/2);
}
if (!isRasterizing) {
[[UIColor clearColor] set];
UIRectFill(bounds);
}
CGContextRef context = UIGraphicsGetCurrentContext();
// Circle Drawing
UIBezierPath *ovalPath = [UIBezierPath bezierPathWithOvalInRect: buttonBounds];
[[UIColor colorWithWhite:0.0 alpha:0.5] setFill];
[ovalPath stroke];
[ovalPath fill];
// Triangle Drawing
CGContextSaveGState(context);
CGFloat buttonWidth = buttonBounds.size.width;
UIBezierPath *trianglePath = [UIBezierPath bezierPath];
[trianglePath moveToPoint:CGPointMake(bounds.size.width/4 + buttonWidth/3, bounds.size.height/4 + (bounds.size.height/2)/4)];
[trianglePath addLineToPoint:CGPointMake(bounds.size.width/4 + buttonWidth/3, bounds.size.height - bounds.size.height/4 - (bounds.size.height/2)/4)];
[trianglePath addLineToPoint:CGPointMake(bounds.size.width - bounds.size.width/4 - buttonWidth/4, bounds.size.height/2)];
[trianglePath closePath];
[[UIColor colorWithWhite:0.9 alpha:0.9] setFill];
[trianglePath fill];
CGContextRestoreGState(context);
}
@end

View File

@ -128,6 +128,7 @@
05E2127E19D4DB510098F589 /* Frameworks */,
05E2127F19D4DB510098F589 /* Resources */,
F012A6F39E0149F18F564F50 /* Copy Pods Resources */,
EBE12F047824F0A2C6353B54 /* Embed Pods Frameworks */,
);
buildRules = (
);
@ -199,6 +200,21 @@
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
EBE12F047824F0A2C6353B54 /* Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
F012A6F39E0149F18F564F50 /* Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;

View File

@ -43,7 +43,7 @@
videoNode.backgroundColor = [UIColor lightGrayColor];
videoNode.playButton = [self playButton];
// videoNode.playButton = [self playButton];
return videoNode;
}
@ -61,7 +61,7 @@
nicCageVideo.backgroundColor = [UIColor lightGrayColor];
nicCageVideo.shouldAutorepeat = YES;
nicCageVideo.playButton = [self playButton];
// nicCageVideo.playButton = [self playButton];
return nicCageVideo;
}
@ -75,11 +75,11 @@
simonVideo.frame = CGRectMake(0, [UIScreen mainScreen].bounds.size.height - ([UIScreen mainScreen].bounds.size.height/3), [UIScreen mainScreen].bounds.size.width/2, [UIScreen mainScreen].bounds.size.height/3);
simonVideo.gravity = ASVideoGravityResizeAspect;
simonVideo.gravity = AVLayerVideoGravityResizeAspect;
simonVideo.backgroundColor = [UIColor lightGrayColor];
simonVideo.shouldAutorepeat = YES;
simonVideo.playButton = [self playButton];
// simonVideo.playButton = [self playButton];
simonVideo.shouldAutoplay = YES;
return simonVideo;