mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 14:20:20 +00:00
event better duration handling. time label attributes delegation
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
Reference in New Issue
Block a user