@@ -26,6 +26,7 @@ @interface ASVideoPlayerNode() <ASVideoNodeDelegate>
2626 unsigned int delegateSpinnerTintColor:1 ;
2727 unsigned int delegateSpinnerStyle:1 ;
2828 unsigned int delegatePlaybackButtonTint:1 ;
29+ unsigned int delegateFullScreenButtonImage:1 ;
2930 unsigned int delegateScrubberMaximumTrackTintColor:1 ;
3031 unsigned int delegateScrubberMinimumTrackTintColor:1 ;
3132 unsigned int delegateScrubberThumbTintColor:1 ;
@@ -38,6 +39,7 @@ @interface ASVideoPlayerNode() <ASVideoNodeDelegate>
3839 unsigned int delegateVideoNodeShouldChangeState:1 ;
3940 unsigned int delegateVideoNodePlaybackDidFinish:1 ;
4041 unsigned int delegateDidTapVideoPlayerNode:1 ;
42+ unsigned int delegateDidTapFullScreenButtonNode:1 ;
4143 unsigned int delegateVideoPlayerNodeDidSetCurrentItem:1 ;
4244 unsigned int delegateVideoPlayerNodeDidStallAtTimeInterval:1 ;
4345 unsigned int delegateVideoPlayerNodeDidStartInitialLoading:1 ;
@@ -57,6 +59,7 @@ @interface ASVideoPlayerNode() <ASVideoNodeDelegate>
5759 NSMutableDictionary *_cachedControls;
5860
5961 ASDefaultPlaybackButton *_playbackButtonNode;
62+ ASButtonNode *_fullScreenButtonNode;
6063 ASTextNode *_elapsedTextNode;
6164 ASTextNode *_durationTextNode;
6265 ASDisplayNode *_scrubberNode;
@@ -274,6 +277,9 @@ - (void)createControls
274277 case ASVideoPlayerNodeControlTypeScrubber:
275278 [self createScrubber ];
276279 break ;
280+ case ASVideoPlayerNodeControlTypeFullScreenButton:
281+ [self createFullScreenButton ];
282+ break ;
277283 case ASVideoPlayerNodeControlTypeFlexGrowSpacer:
278284 [self createControlFlexGrowSpacer ];
279285 break ;
@@ -315,6 +321,7 @@ - (void)cleanCachedControls
315321 [_cachedControls removeAllObjects ];
316322
317323 _playbackButtonNode = nil ;
324+ _fullScreenButtonNode = nil ;
318325 _elapsedTextNode = nil ;
319326 _durationTextNode = nil ;
320327 _scrubberNode = nil ;
@@ -343,6 +350,23 @@ - (void)createPlaybackButton
343350 [self addSubnode: _playbackButtonNode];
344351}
345352
353+ - (void )createFullScreenButton
354+ {
355+ if (_fullScreenButtonNode == nil ) {
356+ _fullScreenButtonNode = [[ASButtonNode alloc ] init ];
357+ _fullScreenButtonNode.style .preferredSize = CGSizeMake (16.0 , 22.0 );
358+
359+ if (_delegateFlags.delegateFullScreenButtonImage ) {
360+ [_fullScreenButtonNode setImage: [_delegate videoPlayerNodeFullScreenButtonImage: self ] forState: ASControlStateNormal];
361+ }
362+
363+ [_fullScreenButtonNode addTarget: self action: @selector (didTapFullScreenButton: ) forControlEvents: ASControlNodeEventTouchUpInside];
364+ [_cachedControls setObject: _fullScreenButtonNode forKey: @(ASVideoPlayerNodeControlTypeFullScreenButton)];
365+ }
366+
367+ [self addSubnode: _fullScreenButtonNode];
368+ }
369+
346370- (void )createElapsedTextField
347371{
348372 if (_elapsedTextNode == nil ) {
@@ -366,6 +390,7 @@ - (void)createDurationTextField
366390
367391 [_cachedControls setObject: _durationTextNode forKey: @(ASVideoPlayerNodeControlTypeDurationText)];
368392 }
393+ [self updateDurationTimeLabel ];
369394 [self addSubnode: _durationTextNode];
370395}
371396
@@ -624,6 +649,11 @@ - (void)didTapPlaybackButton:(ASControlNode*)node
624649 [self togglePlayPause ];
625650}
626651
652+ - (void )didTapFullScreenButton : (ASButtonNode*)node
653+ {
654+ [_delegate didTapFullScreenButtonNode: node];
655+ }
656+
627657- (void )beginSeek
628658{
629659 _isSeeking = YES ;
@@ -692,6 +722,10 @@ - (NSArray *)controlsForLayoutSpec
692722 if (_cachedControls[ @(ASVideoPlayerNodeControlTypeDurationText) ]) {
693723 [controls addObject: _cachedControls[ @(ASVideoPlayerNodeControlTypeDurationText) ]];
694724 }
725+
726+ if (_cachedControls[ @(ASVideoPlayerNodeControlTypeFullScreenButton) ]) {
727+ [controls addObject: _cachedControls[ @(ASVideoPlayerNodeControlTypeFullScreenButton) ]];
728+ }
695729
696730 return controls;
697731}
@@ -795,7 +829,9 @@ - (void)setDelegate:(id<ASVideoPlayerNodeDelegate>)delegate
795829 _delegateFlags.delegateVideoNodeShouldChangeState = [_delegate respondsToSelector: @selector (videoPlayerNode:shouldChangeVideoNodeStateTo: )];
796830 _delegateFlags.delegateTimeLabelAttributedString = [_delegate respondsToSelector: @selector (videoPlayerNode:timeStringForTimeLabelType:forTime: )];
797831 _delegateFlags.delegatePlaybackButtonTint = [_delegate respondsToSelector: @selector (videoPlayerNodePlaybackButtonTint: )];
832+ _delegateFlags.delegateFullScreenButtonImage = [_delegate respondsToSelector: @selector (videoPlayerNodeFullScreenButtonImage: )];
798833 _delegateFlags.delegateDidTapVideoPlayerNode = [_delegate respondsToSelector: @selector (didTapVideoPlayerNode: )];
834+ _delegateFlags.delegateDidTapFullScreenButtonNode = [_delegate respondsToSelector: @selector (didTapFullScreenButtonNode: )];
799835 _delegateFlags.delegateVideoPlayerNodeDidSetCurrentItem = [_delegate respondsToSelector: @selector (videoPlayerNode:didSetCurrentItem: )];
800836 _delegateFlags.delegateVideoPlayerNodeDidStallAtTimeInterval = [_delegate respondsToSelector: @selector (videoPlayerNode:didStallAtTimeInterval: )];
801837 _delegateFlags.delegateVideoPlayerNodeDidStartInitialLoading = [_delegate respondsToSelector: @selector (videoPlayerNodeDidStartInitialLoading: )];
@@ -892,6 +928,11 @@ - (NSURL*) placeholderImageURL
892928 return _videoNode.URL ;
893929}
894930
931+ - (ASVideoNode*)videoNode
932+ {
933+ return _videoNode;
934+ }
935+
895936- (void )setShouldAggressivelyRecoverFromStall : (BOOL )shouldAggressivelyRecoverFromStall
896937{
897938 if (_shouldAggressivelyRecoverFromStall == shouldAggressivelyRecoverFromStall) {
@@ -904,6 +945,9 @@ - (void)setShouldAggressivelyRecoverFromStall:(BOOL)shouldAggressivelyRecoverFro
904945#pragma mark - Helpers
905946- (NSString *)timeStringForCMTime : (CMTime)time forTimeLabelType : (ASVideoPlayerNodeControlType)type
906947{
948+ if (!CMTIME_IS_VALID (time)) {
949+ return @" 00:00" ;
950+ }
907951 if (_delegateFlags.delegateTimeLabelAttributedString ) {
908952 return [_delegate videoPlayerNode: self timeStringForTimeLabelType: type forTime: time];
909953 }
0 commit comments