event better duration handling. time label attributes delegation

This commit is contained in:
Erekle
2016-05-11 23:22:17 +04:00
parent 9fe57ea583
commit 58101feeee
3 changed files with 69 additions and 33 deletions

View File

@@ -27,9 +27,9 @@ NS_ASSUME_NONNULL_BEGIN
@interface ASVideoPlayerNode : ASDisplayNode @interface ASVideoPlayerNode : ASDisplayNode
@property (nullable, atomic, weak, readwrite) id<ASVideoPlayerNodeDelegate> delegate; @property (nullable, atomic, weak) id<ASVideoPlayerNodeDelegate> delegate;
@property (nonatomic,assign,readonly) CGFloat duration; @property (nonatomic,assign,readonly) CMTime duration;
- (instancetype)initWithUrl:(NSURL*)url; - (instancetype)initWithUrl:(NSURL*)url;
- (instancetype)initWithAsset:(AVAsset*)asset; - (instancetype)initWithAsset:(AVAsset*)asset;
@@ -46,9 +46,13 @@ NS_ASSUME_NONNULL_BEGIN
* @param videoPlayer * @param videoPlayer
*/ */
- (NSArray *)videoPlayerNodeNeededControls:(ASVideoPlayerNode*)videoPlayer; - (NSArray *)videoPlayerNodeNeededControls:(ASVideoPlayerNode*)videoPlayer;
- (UIColor *)videoPlayerNodeScrubberMaximumTrackTint:(ASVideoPlayerNode*)videoPlayer; - (NSDictionary *)videoPlayerNodeTimeLabelAttributes:(ASVideoPlayerNode *)videoPlayerNode timeLabelType:(ASVideoPlayerNodeControlType)timeLabelType;
- (UIColor *)videoPlayerNodeScrubberMinimumTrackTint:(ASVideoPlayerNode*)videoPlayer;
- (UIColor *)videoPlayerNodeScrubberThumbTint:(ASVideoPlayerNode*)videoPlayer; #pragma mark - Scrubber delegate methods
- (UIColor *)videoPlayerNodeScrubberMaximumTrackTint:(ASVideoPlayerNode *)videoPlayer;
- (UIColor *)videoPlayerNodeScrubberMinimumTrackTint:(ASVideoPlayerNode *)videoPlayer;
- (UIColor *)videoPlayerNodeScrubberThumbTint:(ASVideoPlayerNode *)videoPlayer;
- (UIImage *)videoPlayerNodeScrubberThumbImage:(ASVideoPlayerNode *)videoPlayer;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END
#endif #endif

View File

@@ -21,6 +21,8 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
unsigned int delegateScrubberMaximumTrackTintColor:1; unsigned int delegateScrubberMaximumTrackTintColor:1;
unsigned int delegateScrubberMinimumTrackTintColor:1; unsigned int delegateScrubberMinimumTrackTintColor:1;
unsigned int delegateScrubberThumbTintColor:1; unsigned int delegateScrubberThumbTintColor:1;
unsigned int delegateScrubberThumbImage:1;
unsigned int delegateTimeLabelAttributes:1;
} _delegateFlags; } _delegateFlags;
NSURL *_url; NSURL *_url;
@@ -41,7 +43,7 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
ASStackLayoutSpec *_controlFlexGrowSpacerSpec; ASStackLayoutSpec *_controlFlexGrowSpacerSpec;
BOOL _isSeeking; BOOL _isSeeking;
CGFloat _duration; CMTime _duration;
} }
@@ -112,7 +114,7 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
} }
} }
- (NSArray*)createNeededControlElementsArray - (NSArray*)createControlElementArray
{ {
if (_delegateFlags.delegateNeededControls) { if (_delegateFlags.delegateNeededControls) {
return [_delegate videoPlayerNodeNeededControls:self]; return [_delegate videoPlayerNodeNeededControls:self];
@@ -141,7 +143,7 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
ASDN::MutexLocker l(_videoPlayerLock); ASDN::MutexLocker l(_videoPlayerLock);
if (_neededControls == nil) { if (_neededControls == nil) {
_neededControls = [self createNeededControlElementsArray]; _neededControls = [self createControlElementArray];
} }
for (int i = 0; i < _neededControls.count; i++) { for (int i = 0; i < _neededControls.count; i++) {
@@ -195,7 +197,7 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
{ {
if (_elapsedTextNode == nil) { if (_elapsedTextNode == nil) {
_elapsedTextNode = [[ASTextNode alloc] init]; _elapsedTextNode = [[ASTextNode alloc] init];
_elapsedTextNode.attributedString = [self timeLabelAttributedStringForString:@"00:00"]; _elapsedTextNode.attributedString = [self timeLabelAttributedStringForString:@"00:00" forControlType:ASVideoPlayerNodeControlTypeElapsedText];
[_cachedControls addObject:_elapsedTextNode]; [_cachedControls addObject:_elapsedTextNode];
} }
@@ -206,7 +208,7 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
{ {
if (_durationTextNode == nil) { if (_durationTextNode == nil) {
_durationTextNode = [[ASTextNode alloc] init]; _durationTextNode = [[ASTextNode alloc] init];
_durationTextNode.attributedString = [self timeLabelAttributedStringForString:@"00:00"]; _durationTextNode.attributedString = [self timeLabelAttributedStringForString:@"00:00" forControlType:ASVideoPlayerNodeControlTypeDurationText];
[_cachedControls addObject:_durationTextNode]; [_cachedControls addObject:_durationTextNode];
} }
@@ -229,10 +231,16 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
slider.maximumTrackTintColor = [_delegate videoPlayerNodeScrubberMaximumTrackTint:self]; slider.maximumTrackTintColor = [_delegate videoPlayerNodeScrubberMaximumTrackTint:self];
} }
if (_delegateFlags.delegateScrubberThumbTintColor){ if (_delegateFlags.delegateScrubberThumbTintColor) {
slider.thumbTintColor = [_delegate videoPlayerNodeScrubberThumbTint:self]; slider.thumbTintColor = [_delegate videoPlayerNodeScrubberThumbTint:self];
} }
if (_delegateFlags.delegateScrubberThumbImage) {
UIImage *thumbImage = [_delegate videoPlayerNodeScrubberThumbImage:self];
[slider setThumbImage:thumbImage forState:UIControlStateNormal];
}
[slider addTarget:self action:@selector(beganSeek) forControlEvents:UIControlEventTouchDown]; [slider addTarget:self action:@selector(beganSeek) forControlEvents:UIControlEventTouchDown];
[slider addTarget:self action:@selector(endedSeek) forControlEvents:UIControlEventTouchUpInside|UIControlEventTouchUpOutside|UIControlEventTouchCancel]; [slider addTarget:self action:@selector(endedSeek) forControlEvents:UIControlEventTouchUpInside|UIControlEventTouchUpOutside|UIControlEventTouchCancel];
[slider addTarget:self action:@selector(changedSeekValue:) forControlEvents:UIControlEventValueChanged]; [slider addTarget:self action:@selector(changedSeekValue:) forControlEvents:UIControlEventValueChanged];
@@ -260,23 +268,28 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
- (void)updateDurationTimeLabel - (void)updateDurationTimeLabel
{ {
NSString *formatedDuration = [self timeFormatted:round(_duration)]; NSString *formatedDuration = [self timeStringForCMTime:_duration];
_durationTextNode.attributedString = [self timeLabelAttributedStringForString:formatedDuration]; _durationTextNode.attributedString = [self timeLabelAttributedStringForString:formatedDuration forControlType:ASVideoPlayerNodeControlTypeDurationText];
} }
- (void)updateElapsedTimeLabel:(NSTimeInterval)seconds - (void)updateElapsedTimeLabel:(NSTimeInterval)seconds
{ {
NSString *formatedDuration = [self timeFormatted:round(seconds)]; NSString *formatedDuration = [self timeStringForCMTime:CMTimeMakeWithSeconds( seconds, _videoNode.periodicTimeObserverTimescale )];
_elapsedTextNode.attributedString = [self timeLabelAttributedStringForString:formatedDuration]; _elapsedTextNode.attributedString = [self timeLabelAttributedStringForString:formatedDuration forControlType:ASVideoPlayerNodeControlTypeElapsedText];
} }
- (NSAttributedString*)timeLabelAttributedStringForString:(NSString*)string - (NSAttributedString*)timeLabelAttributedStringForString:(NSString*)string forControlType:(ASVideoPlayerNodeControlType)controlType
{ {
//TODO:: maybe we can ask delegate for this options too NSDictionary *options;
NSDictionary *options = @{ if (_delegateFlags.delegateTimeLabelAttributes) {
NSFontAttributeName : [UIFont systemFontOfSize:12.0], options = [_delegate videoPlayerNodeTimeLabelAttributes:self timeLabelType:controlType];
NSForegroundColorAttributeName: [UIColor whiteColor] } else {
}; options = @{
NSFontAttributeName : [UIFont systemFontOfSize:12.0],
NSForegroundColorAttributeName: [UIColor whiteColor]
};
}
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:string attributes:options]; NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:string attributes:options];
@@ -287,7 +300,7 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
- (void)videoNode:(ASVideoNode *)videoNode willChangePlayerState:(ASVideoNodePlayerState)state toState:(ASVideoNodePlayerState)toSate - (void)videoNode:(ASVideoNode *)videoNode willChangePlayerState:(ASVideoNodePlayerState)state toState:(ASVideoNodePlayerState)toSate
{ {
if (toSate == ASVideoNodePlayerStateReadyToPlay) { if (toSate == ASVideoNodePlayerStateReadyToPlay) {
_duration = CMTimeGetSeconds(_videoNode.currentItem.duration); _duration = _videoNode.currentItem.duration;
[self updateDurationTimeLabel]; [self updateDurationTimeLabel];
} }
} }
@@ -299,7 +312,7 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
} }
[self updateElapsedTimeLabel:second]; [self updateElapsedTimeLabel:second];
[(UISlider*)_scrubberNode.view setValue:(second/_duration) animated:NO]; [(UISlider*)_scrubberNode.view setValue:(second/ CMTimeGetSeconds(_duration) ) animated:NO];
} }
- (void)videoPlaybackDidFinish:(ASVideoNode *)videoNode - (void)videoPlaybackDidFinish:(ASVideoNode *)videoNode
@@ -337,7 +350,7 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
-(void)seekToTime:(CGFloat)percentComplete -(void)seekToTime:(CGFloat)percentComplete
{ {
CGFloat seconds = (_duration * percentComplete) / 100; CGFloat seconds = ( CMTimeGetSeconds(_duration) * percentComplete ) / 100;
[self updateElapsedTimeLabel:seconds]; [self updateElapsedTimeLabel:seconds];
[_videoNode.player seekToTime:CMTimeMakeWithSeconds(seconds, _videoNode.periodicTimeObserverTimescale)]; [_videoNode.player seekToTime:CMTimeMakeWithSeconds(seconds, _videoNode.periodicTimeObserverTimescale)];
@@ -405,17 +418,27 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
_delegateFlags.delegateScrubberMaximumTrackTintColor = [_delegate respondsToSelector:@selector(videoPlayerNodeScrubberMaximumTrackTint:)]; _delegateFlags.delegateScrubberMaximumTrackTintColor = [_delegate respondsToSelector:@selector(videoPlayerNodeScrubberMaximumTrackTint:)];
_delegateFlags.delegateScrubberMinimumTrackTintColor = [_delegate respondsToSelector:@selector(videoPlayerNodeScrubberMinimumTrackTint:)]; _delegateFlags.delegateScrubberMinimumTrackTintColor = [_delegate respondsToSelector:@selector(videoPlayerNodeScrubberMinimumTrackTint:)];
_delegateFlags.delegateScrubberThumbTintColor = [_delegate respondsToSelector:@selector(videoPlayerNodeScrubberThumbTint:)]; _delegateFlags.delegateScrubberThumbTintColor = [_delegate respondsToSelector:@selector(videoPlayerNodeScrubberThumbTint:)];
_delegateFlags.delegateScrubberThumbImage = [_delegate respondsToSelector:@selector(videoPlayerNodeScrubberThumbImage:)];
_delegateFlags.delegateTimeLabelAttributes = [_delegate respondsToSelector:@selector(videoPlayerNodeTimeLabelAttributes:timeLabelType:)];
} }
} }
#pragma mark - Helpers #pragma mark - Helpers
- (NSString *)timeFormatted:(int)totalSeconds - (NSString *)timeStringForCMTime:(CMTime)time
{ {
NSUInteger dTotalSeconds = CMTimeGetSeconds(time);
int seconds = totalSeconds % 60; NSUInteger dHours = floor(dTotalSeconds / 3600);
int minutes = (totalSeconds / 60) % 60; NSUInteger dMinutes = floor(dTotalSeconds % 3600 / 60);
NSUInteger dSeconds = floor(dTotalSeconds % 3600 % 60);
return [NSString stringWithFormat:@"%02d:%02d", minutes, seconds]; NSString *videoDurationText;
if (dHours > 0) {
videoDurationText = [NSString stringWithFormat:@"%i:%01i:%02i", (int)dHours, (int)dMinutes, (int)dSeconds];
} else {
videoDurationText = [NSString stringWithFormat:@"%01i:%02i", (int)dMinutes, (int)dSeconds];
}
return videoDurationText;
} }
#pragma mark - Lifecycle #pragma mark - Lifecycle

View File

@@ -57,23 +57,32 @@
return @[ @(ASVideoPlayerNodeControlTypePlaybackButton), return @[ @(ASVideoPlayerNodeControlTypePlaybackButton),
@(ASVideoPlayerNodeControlTypeElapsedText), @(ASVideoPlayerNodeControlTypeElapsedText),
@(ASVideoPlayerNodeControlTypeScrubber), @(ASVideoPlayerNodeControlTypeScrubber),
@(ASVideoPlayerNodeControlTypeFlexGrowSpacer),
@(ASVideoPlayerNodeControlTypeDurationText) ]; @(ASVideoPlayerNodeControlTypeDurationText) ];
} }
- (UIColor *)videoPlayerNodeScrubberMaximumTrackTint:(ASVideoPlayerNode *)videoPlayer - (UIColor *)videoPlayerNodeScrubberMaximumTrackTint:(ASVideoPlayerNode *)videoPlayer
{ {
return [UIColor clearColor]; return [UIColor colorWithRed:1 green:1 blue:1 alpha:0.3];
} }
- (UIColor *)videoPlayerNodeScrubberMinimumTrackTint:(ASVideoPlayerNode *)videoPlayer - (UIColor *)videoPlayerNodeScrubberMinimumTrackTint:(ASVideoPlayerNode *)videoPlayer
{ {
return [UIColor orangeColor]; return [UIColor whiteColor];
} }
- (UIColor *)videoPlayerNodeScrubberThumbTint:(ASVideoPlayerNode *)videoPlayer - (UIColor *)videoPlayerNodeScrubberThumbTint:(ASVideoPlayerNode *)videoPlayer
{ {
return [UIColor orangeColor]; return [UIColor whiteColor];
}
- (NSDictionary *)videoPlayerNodeTimeLabelAttributes:(ASVideoPlayerNode *)videoPlayerNode timeLabelType:(ASVideoPlayerNodeControlType)timeLabelType
{
NSDictionary *options = @{
NSFontAttributeName : [UIFont fontWithName:@"HelveticaNeue-Medium" size:13.0],
NSForegroundColorAttributeName: [UIColor orangeColor]
};
return options;
} }
@end @end