mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-17 11:50:56 +00:00
[ASVideoPlayerNode] fixes; Ability to add custom controls
This commit is contained in:
parent
03f193c58b
commit
4ab0f1ec60
@ -443,10 +443,6 @@ static NSString * const kStatus = @"status";
|
|||||||
_asset = asset;
|
_asset = asset;
|
||||||
|
|
||||||
[self setNeedsDataFetch];
|
[self setNeedsDataFetch];
|
||||||
|
|
||||||
if (_shouldAutoplay) {
|
|
||||||
[self play];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (AVAsset *)asset
|
- (AVAsset *)asset
|
||||||
|
|||||||
@ -31,15 +31,17 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
|
|
||||||
@property (nonatomic, assign, readonly) CMTime duration;
|
@property (nonatomic, assign, readonly) CMTime duration;
|
||||||
|
|
||||||
@property (nonatomic, assign) BOOL disableControls;
|
@property (nonatomic, assign) BOOL controlsDisabled;
|
||||||
|
|
||||||
|
@property (nonatomic, assign, readonly) BOOL loadAssetWhenNodeBecomesVisible;
|
||||||
|
|
||||||
#pragma mark - ASVideoNode property proxy
|
#pragma mark - ASVideoNode property proxy
|
||||||
/**
|
/**
|
||||||
* When shouldAutoplay is set to true, a video node will play when it has both loaded and entered the "visible" interfaceState.
|
* When shouldAutoplay is set to true, a video node will play when it has both loaded and entered the "visible" interfaceState.
|
||||||
* If it leaves the visible interfaceState it will pause but will resume once it has returned.
|
* If it leaves the visible interfaceState it will pause but will resume once it has returned.
|
||||||
*/
|
*/
|
||||||
@property (nonatomic, assign, readwrite) BOOL shouldAutoplay;
|
@property (nonatomic, assign, readwrite) BOOL shouldAutoPlay;
|
||||||
@property (nonatomic, assign, readwrite) BOOL shouldAutorepeat;
|
@property (nonatomic, assign, readwrite) BOOL shouldAutoRepeat;
|
||||||
@property (nonatomic, assign, readwrite) BOOL muted;
|
@property (nonatomic, assign, readwrite) BOOL muted;
|
||||||
@property (nonatomic, assign, readonly) ASVideoNodePlayerState playerState;
|
@property (nonatomic, assign, readonly) ASVideoNodePlayerState playerState;
|
||||||
@property (nonatomic, assign, readwrite) BOOL shouldAggressivelyRecoverFromStall;
|
@property (nonatomic, assign, readwrite) BOOL shouldAggressivelyRecoverFromStall;
|
||||||
@ -51,6 +53,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
|
|
||||||
- (instancetype)initWithUrl:(NSURL*)url;
|
- (instancetype)initWithUrl:(NSURL*)url;
|
||||||
- (instancetype)initWithAsset:(AVAsset*)asset;
|
- (instancetype)initWithAsset:(AVAsset*)asset;
|
||||||
|
- (instancetype)initWithUrl:(NSURL *)url loadAssetWhenNodeBecomesVisible:(BOOL)loadAssetWhenNodeBecomesVisible;
|
||||||
|
- (instancetype)initWithAsset:(AVAsset *)asset loadAssetWhenNodeBecomesVisible:(BOOL)loadAssetWhenNodeBecomesVisible;
|
||||||
|
|
||||||
#pragma mark - Public API
|
#pragma mark - Public API
|
||||||
- (void)seekToTime:(CGFloat)percentComplete;
|
- (void)seekToTime:(CGFloat)percentComplete;
|
||||||
@ -67,7 +71,16 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
* @abstract Delegate method invoked before creating controlbar controls
|
* @abstract Delegate method invoked before creating controlbar controls
|
||||||
* @param videoPlayer
|
* @param videoPlayer
|
||||||
*/
|
*/
|
||||||
- (NSArray *)videoPlayerNodeNeededControls:(ASVideoPlayerNode*)videoPlayer;
|
- (NSArray *)videoPlayerNodeNeededDefaultControls:(ASVideoPlayerNode*)videoPlayer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @abstract Delegate method invoked before creating default controls, asks delegate for custom controls dictionary.
|
||||||
|
* This dictionary must constain only ASDisplayNode subclass objects.
|
||||||
|
* @param videoPlayer
|
||||||
|
* @discussion - This method is invoked only when developer implements videoPlayerNodeLayoutSpec:forControls:forMaximumSize:
|
||||||
|
* and gives ability to add custom constrols to ASVideoPlayerNode, for example mute button.
|
||||||
|
*/
|
||||||
|
- (NSDictionary *)videoPlayerNodeCustomControls:(ASVideoPlayerNode*)videoPlayer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @abstract Delegate method invoked in layoutSpecThatFits:
|
* @abstract Delegate method invoked in layoutSpecThatFits:
|
||||||
@ -106,7 +119,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
|
|
||||||
#pragma mark ASVideoNodeDelegate proxy methods
|
#pragma mark ASVideoNodeDelegate proxy methods
|
||||||
/**
|
/**
|
||||||
* @abstract Delegate method invoked when ASVideoPlayerNode playback time is taped.
|
* @abstract Delegate method invoked when ASVideoPlayerNode is taped.
|
||||||
* @param videoPlayerNode The ASVideoPlayerNode that was tapped.
|
* @param videoPlayerNode The ASVideoPlayerNode that was tapped.
|
||||||
*/
|
*/
|
||||||
- (void)didTapVideoPlayerNode:(ASVideoPlayerNode *)videoPlayer;
|
- (void)didTapVideoPlayerNode:(ASVideoPlayerNode *)videoPlayer;
|
||||||
|
|||||||
@ -18,7 +18,8 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
|||||||
__weak id<ASVideoPlayerNodeDelegate> _delegate;
|
__weak id<ASVideoPlayerNodeDelegate> _delegate;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
unsigned int delegateNeededControls:1;
|
unsigned int delegateNeededDefaultControls:1;
|
||||||
|
unsigned int delegateCustomControls:1;
|
||||||
unsigned int delegateSpinnerTintColor:1;
|
unsigned int delegateSpinnerTintColor:1;
|
||||||
unsigned int delegatePlaybackButtonTint:1;
|
unsigned int delegatePlaybackButtonTint:1;
|
||||||
unsigned int delegateScrubberMaximumTrackTintColor:1;
|
unsigned int delegateScrubberMaximumTrackTintColor:1;
|
||||||
@ -40,7 +41,7 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
|||||||
|
|
||||||
ASVideoNode *_videoNode;
|
ASVideoNode *_videoNode;
|
||||||
|
|
||||||
NSArray *_neededControls;
|
NSArray *_neededDefaultControls;
|
||||||
|
|
||||||
NSMutableDictionary *_cachedControls;
|
NSMutableDictionary *_cachedControls;
|
||||||
|
|
||||||
@ -51,13 +52,14 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
|||||||
ASStackLayoutSpec *_controlFlexGrowSpacerSpec;
|
ASStackLayoutSpec *_controlFlexGrowSpacerSpec;
|
||||||
ASDisplayNode *_spinnerNode;
|
ASDisplayNode *_spinnerNode;
|
||||||
|
|
||||||
|
BOOL _loadAssetWhenNodeBecomesVisible;
|
||||||
BOOL _isSeeking;
|
BOOL _isSeeking;
|
||||||
CMTime _duration;
|
CMTime _duration;
|
||||||
|
|
||||||
BOOL _disableControls;
|
BOOL _controlsDisabled;
|
||||||
|
|
||||||
BOOL _shouldAutoplay;
|
BOOL _shouldAutoPlay;
|
||||||
BOOL _shouldAutorepeat;
|
BOOL _shouldAutoRepeat;
|
||||||
BOOL _muted;
|
BOOL _muted;
|
||||||
int32_t _periodicTimeObserverTimescale;
|
int32_t _periodicTimeObserverTimescale;
|
||||||
NSString *_gravity;
|
NSString *_gravity;
|
||||||
@ -89,6 +91,7 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
|||||||
|
|
||||||
_url = url;
|
_url = url;
|
||||||
_asset = [AVAsset assetWithURL:_url];
|
_asset = [AVAsset assetWithURL:_url];
|
||||||
|
_loadAssetWhenNodeBecomesVisible = YES;
|
||||||
|
|
||||||
[self _init];
|
[self _init];
|
||||||
|
|
||||||
@ -102,7 +105,36 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
|||||||
}
|
}
|
||||||
|
|
||||||
_asset = asset;
|
_asset = asset;
|
||||||
_disableControls = NO;
|
_loadAssetWhenNodeBecomesVisible = YES;
|
||||||
|
|
||||||
|
[self _init];
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)initWithUrl:(NSURL *)url loadAssetWhenNodeBecomesVisible:(BOOL)loadAssetWhenNodeBecomesVisible
|
||||||
|
{
|
||||||
|
if (!(self = [super init])) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
_url = url;
|
||||||
|
_asset = [AVAsset assetWithURL:_url];
|
||||||
|
_loadAssetWhenNodeBecomesVisible = loadAssetWhenNodeBecomesVisible;
|
||||||
|
|
||||||
|
[self _init];
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)initWithAsset:(AVAsset *)asset loadAssetWhenNodeBecomesVisible:(BOOL)loadAssetWhenNodeBecomesVisible
|
||||||
|
{
|
||||||
|
if (!(self = [super init])) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
_asset = asset;
|
||||||
|
_loadAssetWhenNodeBecomesVisible = loadAssetWhenNodeBecomesVisible;
|
||||||
|
|
||||||
[self _init];
|
[self _init];
|
||||||
|
|
||||||
@ -111,16 +143,15 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
|||||||
|
|
||||||
- (void)_init
|
- (void)_init
|
||||||
{
|
{
|
||||||
|
|
||||||
_defaultControlsColor = [UIColor whiteColor];
|
_defaultControlsColor = [UIColor whiteColor];
|
||||||
_cachedControls = [[NSMutableDictionary alloc] init];
|
_cachedControls = [[NSMutableDictionary alloc] init];
|
||||||
|
|
||||||
_videoNode = [[ASVideoNode alloc] init];
|
_videoNode = [[ASVideoNode alloc] init];
|
||||||
_videoNode.asset = _asset;
|
|
||||||
_videoNode.delegate = self;
|
_videoNode.delegate = self;
|
||||||
|
if (_loadAssetWhenNodeBecomesVisible == NO) {
|
||||||
|
_videoNode.asset = _asset;
|
||||||
|
}
|
||||||
[self addSubnode:_videoNode];
|
[self addSubnode:_videoNode];
|
||||||
|
|
||||||
[self addObservers];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)didLoad
|
- (void)didLoad
|
||||||
@ -132,10 +163,21 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray*)createControlElementArray
|
- (void)visibilityDidChange:(BOOL)isVisible
|
||||||
{
|
{
|
||||||
if (_delegateFlags.delegateNeededControls) {
|
[super visibilityDidChange:isVisible];
|
||||||
return [_delegate videoPlayerNodeNeededControls:self];
|
|
||||||
|
ASDN::MutexLocker l(_videoPlayerLock);
|
||||||
|
|
||||||
|
if (isVisible && _loadAssetWhenNodeBecomesVisible && _asset != _videoNode.asset) {
|
||||||
|
_videoNode.asset = _asset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSArray *)createDefaultControlElementArray
|
||||||
|
{
|
||||||
|
if (_delegateFlags.delegateNeededDefaultControls) {
|
||||||
|
return [_delegate videoPlayerNodeNeededDefaultControls:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
return @[ @(ASVideoPlayerNodeControlTypePlaybackButton),
|
return @[ @(ASVideoPlayerNodeControlTypePlaybackButton),
|
||||||
@ -144,35 +186,25 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
|||||||
@(ASVideoPlayerNodeControlTypeDurationText) ];
|
@(ASVideoPlayerNodeControlTypeDurationText) ];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)addObservers
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)removeObservers
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - UI
|
#pragma mark - UI
|
||||||
- (void)createControls
|
- (void)createControls
|
||||||
{
|
{
|
||||||
ASDN::MutexLocker l(_videoPlayerLock);
|
ASDN::MutexLocker l(_videoPlayerLock);
|
||||||
|
|
||||||
if (_disableControls) {
|
if (_controlsDisabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_neededControls == nil) {
|
if (_neededDefaultControls == nil) {
|
||||||
_neededControls = [self createControlElementArray];
|
_neededDefaultControls = [self createDefaultControlElementArray];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_cachedControls == nil) {
|
if (_cachedControls == nil) {
|
||||||
_cachedControls = [[NSMutableDictionary alloc] init];
|
_cachedControls = [[NSMutableDictionary alloc] init];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < _neededControls.count; i++) {
|
for (id object in _neededDefaultControls) {
|
||||||
ASVideoPlayerNodeControlType type = (ASVideoPlayerNodeControlType)[[_neededControls objectAtIndex:i] integerValue];
|
ASVideoPlayerNodeControlType type = (ASVideoPlayerNodeControlType)[object integerValue];
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ASVideoPlayerNodeControlTypePlaybackButton:
|
case ASVideoPlayerNodeControlTypePlaybackButton:
|
||||||
[self createPlaybackButton];
|
[self createPlaybackButton];
|
||||||
@ -194,6 +226,19 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_delegateFlags.delegateCustomControls && _delegateFlags.delegateLayoutSpecForControls) {
|
||||||
|
NSDictionary *customControls = [_delegate videoPlayerNodeCustomControls:self];
|
||||||
|
for (id key in customControls) {
|
||||||
|
id node = customControls[key];
|
||||||
|
if (![node isKindOfClass:[ASDisplayNode class]]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
[self addSubnode:node];
|
||||||
|
[_cachedControls setObject:node forKey:key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ASPerformBlockOnMainThread(^{
|
ASPerformBlockOnMainThread(^{
|
||||||
ASDN::MutexLocker l(_videoPlayerLock);
|
ASDN::MutexLocker l(_videoPlayerLock);
|
||||||
[self setNeedsLayout];
|
[self setNeedsLayout];
|
||||||
@ -246,7 +291,9 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
|||||||
{
|
{
|
||||||
if (_elapsedTextNode == nil) {
|
if (_elapsedTextNode == nil) {
|
||||||
_elapsedTextNode = [[ASTextNode alloc] init];
|
_elapsedTextNode = [[ASTextNode alloc] init];
|
||||||
_elapsedTextNode.attributedString = [self timeLabelAttributedStringForString:@"00:00" forControlType:ASVideoPlayerNodeControlTypeElapsedText];
|
_elapsedTextNode.attributedString = [self timeLabelAttributedStringForString:@"00:00"
|
||||||
|
forControlType:ASVideoPlayerNodeControlTypeElapsedText];
|
||||||
|
_elapsedTextNode.truncationMode = NSLineBreakByClipping;
|
||||||
|
|
||||||
[_cachedControls setObject:_elapsedTextNode forKey:@(ASVideoPlayerNodeControlTypeElapsedText)];
|
[_cachedControls setObject:_elapsedTextNode forKey:@(ASVideoPlayerNodeControlTypeElapsedText)];
|
||||||
}
|
}
|
||||||
@ -257,7 +304,9 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
|||||||
{
|
{
|
||||||
if (_durationTextNode == nil) {
|
if (_durationTextNode == nil) {
|
||||||
_durationTextNode = [[ASTextNode alloc] init];
|
_durationTextNode = [[ASTextNode alloc] init];
|
||||||
_durationTextNode.attributedString = [self timeLabelAttributedStringForString:@"00:00" forControlType:ASVideoPlayerNodeControlTypeDurationText];
|
_durationTextNode.attributedString = [self timeLabelAttributedStringForString:@"00:00"
|
||||||
|
forControlType:ASVideoPlayerNodeControlTypeDurationText];
|
||||||
|
_durationTextNode.truncationMode = NSLineBreakByClipping;
|
||||||
|
|
||||||
[_cachedControls setObject:_durationTextNode forKey:@(ASVideoPlayerNodeControlTypeDurationText)];
|
[_cachedControls setObject:_durationTextNode forKey:@(ASVideoPlayerNodeControlTypeDurationText)];
|
||||||
}
|
}
|
||||||
@ -317,14 +366,20 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
|||||||
|
|
||||||
- (void)updateDurationTimeLabel
|
- (void)updateDurationTimeLabel
|
||||||
{
|
{
|
||||||
NSString *formatedDuration = [self timeStringForCMTime:_duration forTimeLabelType:ASVideoPlayerNodeControlTypeDurationText];
|
if (!_durationTextNode) {
|
||||||
_durationTextNode.attributedString = [self timeLabelAttributedStringForString:formatedDuration forControlType:ASVideoPlayerNodeControlTypeDurationText];
|
return;
|
||||||
|
}
|
||||||
|
NSString *formattedDuration = [self timeStringForCMTime:_duration forTimeLabelType:ASVideoPlayerNodeControlTypeDurationText];
|
||||||
|
_durationTextNode.attributedString = [self timeLabelAttributedStringForString:formattedDuration forControlType:ASVideoPlayerNodeControlTypeDurationText];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateElapsedTimeLabel:(NSTimeInterval)seconds
|
- (void)updateElapsedTimeLabel:(NSTimeInterval)seconds
|
||||||
{
|
{
|
||||||
NSString *formatedDuration = [self timeStringForCMTime:CMTimeMakeWithSeconds( seconds, _videoNode.periodicTimeObserverTimescale ) forTimeLabelType:ASVideoPlayerNodeControlTypeElapsedText];
|
if (!_elapsedTextNode) {
|
||||||
_elapsedTextNode.attributedString = [self timeLabelAttributedStringForString:formatedDuration forControlType:ASVideoPlayerNodeControlTypeElapsedText];
|
return;
|
||||||
|
}
|
||||||
|
NSString *formatteElapsed = [self timeStringForCMTime:CMTimeMakeWithSeconds( seconds, _videoNode.periodicTimeObserverTimescale ) forTimeLabelType:ASVideoPlayerNodeControlTypeElapsedText];
|
||||||
|
_elapsedTextNode.attributedString = [self timeLabelAttributedStringForString:formatteElapsed forControlType:ASVideoPlayerNodeControlTypeElapsedText];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSAttributedString*)timeLabelAttributedStringForString:(NSString*)string forControlType:(ASVideoPlayerNodeControlType)controlType
|
- (NSAttributedString*)timeLabelAttributedStringForString:(NSString*)string forControlType:(ASVideoPlayerNodeControlType)controlType
|
||||||
@ -352,7 +407,7 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
|||||||
[_delegate videoPlayerNode:self willChangeVideoNodeState:state toVideoNodeState:toState];
|
[_delegate videoPlayerNode:self willChangeVideoNodeState:state toVideoNodeState:toState];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (toState == ASVideoNodePlayerStateReadyToPlay && _durationTextNode) {
|
if (toState == ASVideoNodePlayerStateReadyToPlay) {
|
||||||
_duration = _videoNode.currentItem.duration;
|
_duration = _videoNode.currentItem.duration;
|
||||||
[self updateDurationTimeLabel];
|
[self updateDurationTimeLabel];
|
||||||
}
|
}
|
||||||
@ -383,9 +438,6 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
|||||||
|
|
||||||
- (void)videoNode:(ASVideoNode *)videoNode didPlayToTimeInterval:(NSTimeInterval)timeInterval
|
- (void)videoNode:(ASVideoNode *)videoNode didPlayToTimeInterval:(NSTimeInterval)timeInterval
|
||||||
{
|
{
|
||||||
//TODO: ask Max about CMTime problem in ASVideoNode Header file
|
|
||||||
//as we said yesterday, we must use CMTime in ASVideoNode instead of NSTimeInterval
|
|
||||||
//when this will be done, must just proxy value to delegate
|
|
||||||
if (_delegateFlags.delegateVideoNodeDidPlayToTime) {
|
if (_delegateFlags.delegateVideoNodeDidPlayToTime) {
|
||||||
[_delegate videoPlayerNode:self didPlayToTime:_videoNode.player.currentTime];
|
[_delegate videoPlayerNode:self didPlayToTime:_videoNode.player.currentTime];
|
||||||
}
|
}
|
||||||
@ -415,12 +467,12 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
|||||||
if (_delegateFlags.delegateDidTapVideoPlayerNode) {
|
if (_delegateFlags.delegateDidTapVideoPlayerNode) {
|
||||||
[_delegate didTapVideoPlayerNode:self];
|
[_delegate didTapVideoPlayerNode:self];
|
||||||
} else {
|
} else {
|
||||||
[self manageVideoNodePlayback];
|
[self togglePlayPause];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Actions
|
#pragma mark - Actions
|
||||||
- (void)manageVideoNodePlayback
|
- (void)togglePlayPause
|
||||||
{
|
{
|
||||||
if (_videoNode.playerState == ASVideoNodePlayerStatePlaying) {
|
if (_videoNode.playerState == ASVideoNodePlayerStatePlaying) {
|
||||||
[_videoNode pause];
|
[_videoNode pause];
|
||||||
@ -463,7 +515,7 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
|||||||
|
|
||||||
- (void)didTapPlaybackButton:(ASControlNode*)node
|
- (void)didTapPlaybackButton:(ASControlNode*)node
|
||||||
{
|
{
|
||||||
[self manageVideoNodePlayback];
|
[self togglePlayPause];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)beginSeek
|
- (void)beginSeek
|
||||||
@ -491,7 +543,7 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
|||||||
[_videoNode.player seekToTime:CMTimeMakeWithSeconds(seconds, _videoNode.periodicTimeObserverTimescale)];
|
[_videoNode.player seekToTime:CMTimeMakeWithSeconds(seconds, _videoNode.periodicTimeObserverTimescale)];
|
||||||
|
|
||||||
if (_videoNode.playerState != ASVideoNodePlayerStatePlaying) {
|
if (_videoNode.playerState != ASVideoNodePlayerStatePlaying) {
|
||||||
[self manageVideoNodePlayback];
|
[self togglePlayPause];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -609,12 +661,17 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
|||||||
|
|
||||||
- (void)setDelegate:(id<ASVideoPlayerNodeDelegate>)delegate
|
- (void)setDelegate:(id<ASVideoPlayerNodeDelegate>)delegate
|
||||||
{
|
{
|
||||||
|
if (delegate == _delegate) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_delegate = delegate;
|
_delegate = delegate;
|
||||||
|
|
||||||
if (_delegate == nil) {
|
if (_delegate == nil) {
|
||||||
memset(&_delegateFlags, 0, sizeof(_delegateFlags));
|
memset(&_delegateFlags, 0, sizeof(_delegateFlags));
|
||||||
} else {
|
} else {
|
||||||
_delegateFlags.delegateNeededControls = [_delegate respondsToSelector:@selector(videoPlayerNodeNeededControls:)];
|
_delegateFlags.delegateNeededDefaultControls = [_delegate respondsToSelector:@selector(videoPlayerNodeNeededDefaultControls:)];
|
||||||
|
_delegateFlags.delegateCustomControls = [_delegate respondsToSelector:@selector(videoPlayerNodeCustomControls:)];
|
||||||
_delegateFlags.delegateSpinnerTintColor = [_delegate respondsToSelector:@selector(videoPlayerNodeSpinnerTint:)];
|
_delegateFlags.delegateSpinnerTintColor = [_delegate respondsToSelector:@selector(videoPlayerNodeSpinnerTint:)];
|
||||||
_delegateFlags.delegateScrubberMaximumTrackTintColor = [_delegate respondsToSelector:@selector(videoPlayerNodeScrubberMaximumTrackTint:)];
|
_delegateFlags.delegateScrubberMaximumTrackTintColor = [_delegate respondsToSelector:@selector(videoPlayerNodeScrubberMaximumTrackTint:)];
|
||||||
_delegateFlags.delegateScrubberMinimumTrackTintColor = [_delegate respondsToSelector:@selector(videoPlayerNodeScrubberMinimumTrackTint:)];
|
_delegateFlags.delegateScrubberMinimumTrackTintColor = [_delegate respondsToSelector:@selector(videoPlayerNodeScrubberMinimumTrackTint:)];
|
||||||
@ -632,37 +689,53 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setDisableControls:(BOOL)disableControls
|
- (void)setControlsDisabled:(BOOL)controlsDisabled
|
||||||
{
|
{
|
||||||
_disableControls = disableControls;
|
if (_controlsDisabled == controlsDisabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (_disableControls && _cachedControls.count > 0) {
|
_controlsDisabled = controlsDisabled;
|
||||||
|
|
||||||
|
if (_controlsDisabled && _cachedControls.count > 0) {
|
||||||
[self removeControls];
|
[self removeControls];
|
||||||
} else if (!_disableControls) {
|
} else if (!_controlsDisabled) {
|
||||||
[self createControls];
|
[self createControls];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setShouldAutoplay:(BOOL)shouldAutoplay
|
- (void)setShouldAutoPlay:(BOOL)shouldAutoPlay
|
||||||
{
|
{
|
||||||
_shouldAutoplay = shouldAutoplay;
|
if (_shouldAutoPlay == shouldAutoPlay) {
|
||||||
_videoNode.shouldAutoplay = _shouldAutoplay;
|
return;
|
||||||
|
}
|
||||||
|
_shouldAutoPlay = shouldAutoPlay;
|
||||||
|
_videoNode.shouldAutoplay = _shouldAutoPlay;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setShouldAutorepeat:(BOOL)shouldAutorepeat
|
- (void)setShouldAutoRepeat:(BOOL)shouldAutoRepeat
|
||||||
{
|
{
|
||||||
_shouldAutorepeat = shouldAutorepeat;
|
if (_shouldAutoRepeat == shouldAutoRepeat) {
|
||||||
_videoNode.shouldAutorepeat = YES;
|
return;
|
||||||
|
}
|
||||||
|
_shouldAutoRepeat = shouldAutoRepeat;
|
||||||
|
_videoNode.shouldAutorepeat = _shouldAutoRepeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setMuted:(BOOL)muted
|
- (void)setMuted:(BOOL)muted
|
||||||
{
|
{
|
||||||
|
if (_muted == muted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
_muted = muted;
|
_muted = muted;
|
||||||
_videoNode.muted = _muted;
|
_videoNode.muted = _muted;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setPeriodicTimeObserverTimescale:(int32_t)periodicTimeObserverTimescale
|
- (void)setPeriodicTimeObserverTimescale:(int32_t)periodicTimeObserverTimescale
|
||||||
{
|
{
|
||||||
|
if (_periodicTimeObserverTimescale == periodicTimeObserverTimescale) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
_periodicTimeObserverTimescale = periodicTimeObserverTimescale;
|
_periodicTimeObserverTimescale = periodicTimeObserverTimescale;
|
||||||
_videoNode.periodicTimeObserverTimescale = _periodicTimeObserverTimescale;
|
_videoNode.periodicTimeObserverTimescale = _periodicTimeObserverTimescale;
|
||||||
}
|
}
|
||||||
@ -677,6 +750,9 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
|||||||
|
|
||||||
- (void)setGravity:(NSString *)gravity
|
- (void)setGravity:(NSString *)gravity
|
||||||
{
|
{
|
||||||
|
if (_gravity == gravity) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
_gravity = gravity;
|
_gravity = gravity;
|
||||||
_videoNode.gravity = _gravity;
|
_videoNode.gravity = _gravity;
|
||||||
}
|
}
|
||||||
@ -693,6 +769,9 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
|||||||
|
|
||||||
- (void)setShouldAggressivelyRecoverFromStall:(BOOL)shouldAggressivelyRecoverFromStall
|
- (void)setShouldAggressivelyRecoverFromStall:(BOOL)shouldAggressivelyRecoverFromStall
|
||||||
{
|
{
|
||||||
|
if (_shouldAggressivelyRecoverFromStall == shouldAggressivelyRecoverFromStall) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
_shouldAggressivelyRecoverFromStall = shouldAggressivelyRecoverFromStall;
|
_shouldAggressivelyRecoverFromStall = shouldAggressivelyRecoverFromStall;
|
||||||
_videoNode.shouldAggressivelyRecoverFromStall = _shouldAggressivelyRecoverFromStall;
|
_videoNode.shouldAggressivelyRecoverFromStall = _shouldAggressivelyRecoverFromStall;
|
||||||
}
|
}
|
||||||
@ -719,11 +798,4 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
|||||||
return videoDurationText;
|
return videoDurationText;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Lifecycle
|
|
||||||
|
|
||||||
- (void)dealloc
|
|
||||||
{
|
|
||||||
[self removeObservers];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@ -19,6 +19,12 @@
|
|||||||
8B0768BF1CE7C5A1002E1453 /* WindowWithStatusBarUnderlay.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B0768BE1CE7C5A1002E1453 /* WindowWithStatusBarUnderlay.m */; };
|
8B0768BF1CE7C5A1002E1453 /* WindowWithStatusBarUnderlay.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B0768BE1CE7C5A1002E1453 /* WindowWithStatusBarUnderlay.m */; };
|
||||||
8B0768C51CE7C707002E1453 /* Utilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B0768C41CE7C707002E1453 /* Utilities.m */; };
|
8B0768C51CE7C707002E1453 /* Utilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B0768C41CE7C707002E1453 /* Utilities.m */; };
|
||||||
8B0768C91CE7C889002E1453 /* VideoFeedNodeController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B0768C81CE7C889002E1453 /* VideoFeedNodeController.m */; };
|
8B0768C91CE7C889002E1453 /* VideoFeedNodeController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B0768C81CE7C889002E1453 /* VideoFeedNodeController.m */; };
|
||||||
|
8B9075851CF386A400F924C1 /* ico-unmute.png in Resources */ = {isa = PBXBuildFile; fileRef = 8B90757F1CF386A400F924C1 /* ico-unmute.png */; };
|
||||||
|
8B9075861CF386A400F924C1 /* ico-unmute@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8B9075801CF386A400F924C1 /* ico-unmute@2x.png */; };
|
||||||
|
8B9075871CF386A400F924C1 /* ico-unmute@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8B9075811CF386A400F924C1 /* ico-unmute@3x.png */; };
|
||||||
|
8B9075881CF386A400F924C1 /* ico-mute.png in Resources */ = {isa = PBXBuildFile; fileRef = 8B9075821CF386A400F924C1 /* ico-mute.png */; };
|
||||||
|
8B9075891CF386A400F924C1 /* ico-mute@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8B9075831CF386A400F924C1 /* ico-mute@2x.png */; };
|
||||||
|
8B90758A1CF386A400F924C1 /* ico-mute@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8B9075841CF386A400F924C1 /* ico-mute@3x.png */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
@ -42,6 +48,12 @@
|
|||||||
8B0768C41CE7C707002E1453 /* Utilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Utilities.m; sourceTree = "<group>"; };
|
8B0768C41CE7C707002E1453 /* Utilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Utilities.m; sourceTree = "<group>"; };
|
||||||
8B0768C71CE7C889002E1453 /* VideoFeedNodeController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoFeedNodeController.h; sourceTree = "<group>"; };
|
8B0768C71CE7C889002E1453 /* VideoFeedNodeController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoFeedNodeController.h; sourceTree = "<group>"; };
|
||||||
8B0768C81CE7C889002E1453 /* VideoFeedNodeController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VideoFeedNodeController.m; sourceTree = "<group>"; };
|
8B0768C81CE7C889002E1453 /* VideoFeedNodeController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VideoFeedNodeController.m; sourceTree = "<group>"; };
|
||||||
|
8B90757F1CF386A400F924C1 /* ico-unmute.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "ico-unmute.png"; sourceTree = "<group>"; };
|
||||||
|
8B9075801CF386A400F924C1 /* ico-unmute@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "ico-unmute@2x.png"; sourceTree = "<group>"; };
|
||||||
|
8B9075811CF386A400F924C1 /* ico-unmute@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "ico-unmute@3x.png"; sourceTree = "<group>"; };
|
||||||
|
8B9075821CF386A400F924C1 /* ico-mute.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "ico-mute.png"; sourceTree = "<group>"; };
|
||||||
|
8B9075831CF386A400F924C1 /* ico-mute@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "ico-mute@2x.png"; sourceTree = "<group>"; };
|
||||||
|
8B9075841CF386A400F924C1 /* ico-mute@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "ico-mute@3x.png"; sourceTree = "<group>"; };
|
||||||
A2092CAF5607B3863A3700A2 /* libPods-Sample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Sample.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
A2092CAF5607B3863A3700A2 /* libPods-Sample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Sample.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
CFD6AA1D30516C27DEE5602B /* Pods-Sample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Sample.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Sample/Pods-Sample.debug.xcconfig"; sourceTree = "<group>"; };
|
CFD6AA1D30516C27DEE5602B /* Pods-Sample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Sample.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Sample/Pods-Sample.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
E51646FF8D3676A1D826A5AE /* Pods-Sample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Sample.release.xcconfig"; path = "Pods/Target Support Files/Pods-Sample/Pods-Sample.release.xcconfig"; sourceTree = "<group>"; };
|
E51646FF8D3676A1D826A5AE /* Pods-Sample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Sample.release.xcconfig"; path = "Pods/Target Support Files/Pods-Sample/Pods-Sample.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
@ -83,6 +95,7 @@
|
|||||||
05E2128319D4DB510098F589 /* Sample */ = {
|
05E2128319D4DB510098F589 /* Sample */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
8B90757E1CF3869100F924C1 /* Icons */,
|
||||||
8B0768C61CE7C85F002E1453 /* Controller */,
|
8B0768C61CE7C85F002E1453 /* Controller */,
|
||||||
8B0768B91CE7B07E002E1453 /* Nodes */,
|
8B0768B91CE7B07E002E1453 /* Nodes */,
|
||||||
8B0768B51CE7ACE8002E1453 /* Models */,
|
8B0768B51CE7ACE8002E1453 /* Models */,
|
||||||
@ -155,6 +168,19 @@
|
|||||||
path = Controller;
|
path = Controller;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
8B90757E1CF3869100F924C1 /* Icons */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
8B90757F1CF386A400F924C1 /* ico-unmute.png */,
|
||||||
|
8B9075801CF386A400F924C1 /* ico-unmute@2x.png */,
|
||||||
|
8B9075811CF386A400F924C1 /* ico-unmute@3x.png */,
|
||||||
|
8B9075821CF386A400F924C1 /* ico-mute.png */,
|
||||||
|
8B9075831CF386A400F924C1 /* ico-mute@2x.png */,
|
||||||
|
8B9075841CF386A400F924C1 /* ico-mute@3x.png */,
|
||||||
|
);
|
||||||
|
path = Icons;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
/* End PBXGroup section */
|
/* End PBXGroup section */
|
||||||
|
|
||||||
/* Begin PBXNativeTarget section */
|
/* Begin PBXNativeTarget section */
|
||||||
@ -215,9 +241,15 @@
|
|||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
8B9075861CF386A400F924C1 /* ico-unmute@2x.png in Resources */,
|
||||||
|
8B9075881CF386A400F924C1 /* ico-mute.png in Resources */,
|
||||||
0585428019D4DBE100606EA6 /* Default-568h@2x.png in Resources */,
|
0585428019D4DBE100606EA6 /* Default-568h@2x.png in Resources */,
|
||||||
6C2C82AC19EE274300767484 /* Default-667h@2x.png in Resources */,
|
6C2C82AC19EE274300767484 /* Default-667h@2x.png in Resources */,
|
||||||
6C2C82AD19EE274300767484 /* Default-736h@3x.png in Resources */,
|
6C2C82AD19EE274300767484 /* Default-736h@3x.png in Resources */,
|
||||||
|
8B90758A1CF386A400F924C1 /* ico-mute@3x.png in Resources */,
|
||||||
|
8B9075851CF386A400F924C1 /* ico-unmute.png in Resources */,
|
||||||
|
8B9075871CF386A400F924C1 /* ico-unmute@3x.png in Resources */,
|
||||||
|
8B9075891CF386A400F924C1 /* ico-mute@2x.png in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
BIN
examples/ASDKTube/Sample/Icons/ico-mute.png
Normal file
BIN
examples/ASDKTube/Sample/Icons/ico-mute.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 483 B |
BIN
examples/ASDKTube/Sample/Icons/ico-mute@2x.png
Normal file
BIN
examples/ASDKTube/Sample/Icons/ico-mute@2x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 801 B |
BIN
examples/ASDKTube/Sample/Icons/ico-mute@3x.png
Normal file
BIN
examples/ASDKTube/Sample/Icons/ico-mute@3x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
BIN
examples/ASDKTube/Sample/Icons/ico-unmute.png
Normal file
BIN
examples/ASDKTube/Sample/Icons/ico-unmute.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 578 B |
BIN
examples/ASDKTube/Sample/Icons/ico-unmute@2x.png
Normal file
BIN
examples/ASDKTube/Sample/Icons/ico-unmute@2x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
examples/ASDKTube/Sample/Icons/ico-unmute@3x.png
Normal file
BIN
examples/ASDKTube/Sample/Icons/ico-unmute@3x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
@ -25,6 +25,7 @@
|
|||||||
ASNetworkImageNode *_avatarNode;
|
ASNetworkImageNode *_avatarNode;
|
||||||
ASVideoPlayerNode *_videoPlayerNode;
|
ASVideoPlayerNode *_videoPlayerNode;
|
||||||
ASControlNode *_likeButtonNode;
|
ASControlNode *_likeButtonNode;
|
||||||
|
ASButtonNode *_muteButtonNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)initWithVideoObject:(VideoModel *)video
|
- (instancetype)initWithVideoObject:(VideoModel *)video
|
||||||
@ -52,10 +53,16 @@
|
|||||||
_likeButtonNode.backgroundColor = [UIColor redColor];
|
_likeButtonNode.backgroundColor = [UIColor redColor];
|
||||||
[self addSubnode:_likeButtonNode];
|
[self addSubnode:_likeButtonNode];
|
||||||
|
|
||||||
_videoPlayerNode = [[ASVideoPlayerNode alloc] initWithUrl:_videoModel.url];
|
_muteButtonNode = [[ASButtonNode alloc] init];
|
||||||
|
_muteButtonNode.preferredFrameSize = CGSizeMake(16.0, 22.0);
|
||||||
|
[_muteButtonNode addTarget:self action:@selector(didTapMuteButton) forControlEvents:ASControlNodeEventTouchUpInside];
|
||||||
|
|
||||||
|
_videoPlayerNode = [[ASVideoPlayerNode alloc] initWithUrl:_videoModel.url loadAssetWhenNodeBecomesVisible:YES];
|
||||||
_videoPlayerNode.delegate = self;
|
_videoPlayerNode.delegate = self;
|
||||||
_videoPlayerNode.backgroundColor = [UIColor blackColor];
|
_videoPlayerNode.backgroundColor = [UIColor blackColor];
|
||||||
[self addSubnode:_videoPlayerNode];
|
[self addSubnode:_videoPlayerNode];
|
||||||
|
|
||||||
|
[self setMuteButtonIcon];
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
@ -98,43 +105,101 @@
|
|||||||
return verticalStack;
|
return verticalStack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)setMuteButtonIcon
|
||||||
|
{
|
||||||
|
if (_videoPlayerNode.muted) {
|
||||||
|
[_muteButtonNode setImage:[UIImage imageNamed:@"ico-mute"] forState:ASControlStateNormal];
|
||||||
|
} else {
|
||||||
|
[_muteButtonNode setImage:[UIImage imageNamed:@"ico-unmute"] forState:ASControlStateNormal];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)didTapMuteButton
|
||||||
|
{
|
||||||
|
_videoPlayerNode.muted = !_videoPlayerNode.muted;
|
||||||
|
[self setMuteButtonIcon];
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark - ASVideoPlayerNodeDelegate
|
#pragma mark - ASVideoPlayerNodeDelegate
|
||||||
- (void)didTapVideoPlayerNode:(ASVideoPlayerNode *)videoPlayer
|
- (void)didTapVideoPlayerNode:(ASVideoPlayerNode *)videoPlayer
|
||||||
{
|
{
|
||||||
if (_videoPlayerNode.isPlaying) {
|
if (_videoPlayerNode.playerState == ASVideoNodePlayerStatePlaying) {
|
||||||
NSLog(@"TRANSITION");
|
NSLog(@"TRANSITION");
|
||||||
|
_videoPlayerNode.controlsDisabled = !_videoPlayerNode.controlsDisabled;
|
||||||
[_videoPlayerNode pause];
|
[_videoPlayerNode pause];
|
||||||
} else {
|
} else {
|
||||||
[_videoPlayerNode play];
|
[_videoPlayerNode play];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*- (NSArray *)videoPlayerNodeNeededControls:(ASVideoPlayerNode *)videoPlayer
|
- (NSDictionary *)videoPlayerNodeCustomControls:(ASVideoPlayerNode *)videoPlayer
|
||||||
{
|
{
|
||||||
return @[ @(ASVideoPlayerNodeControlTypePlaybackButton) ];
|
return @{
|
||||||
}*/
|
@"muteControl" : _muteButtonNode
|
||||||
|
};
|
||||||
/*- (ASLayoutSpec *)videoPlayerNodeLayoutSpec:(ASVideoPlayerNode *)videoPlayer forControls:(NSDictionary *)controls forMaximumSize:(CGSize)maxSize
|
|
||||||
{
|
|
||||||
NSMutableArray *bottomControls = [[NSMutableArray alloc] init];
|
|
||||||
|
|
||||||
ASDisplayNode *playbackButtonNode = controls[@(ASVideoPlayerNodeControlTypePlaybackButton)];
|
|
||||||
|
|
||||||
if (playbackButtonNode) {
|
|
||||||
[bottomControls addObject:playbackButtonNode];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSArray *)controlsForControlBar:(NSDictionary *)availableControls
|
||||||
|
{
|
||||||
|
NSMutableArray *controls = [[NSMutableArray alloc] init];
|
||||||
|
|
||||||
|
if (availableControls[ @(ASVideoPlayerNodeControlTypePlaybackButton) ]) {
|
||||||
|
[controls addObject:availableControls[ @(ASVideoPlayerNodeControlTypePlaybackButton) ]];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (availableControls[ @(ASVideoPlayerNodeControlTypeElapsedText) ]) {
|
||||||
|
[controls addObject:availableControls[ @(ASVideoPlayerNodeControlTypeElapsedText) ]];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (availableControls[ @(ASVideoPlayerNodeControlTypeScrubber) ]) {
|
||||||
|
[controls addObject:availableControls[ @(ASVideoPlayerNodeControlTypeScrubber) ]];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (availableControls[ @(ASVideoPlayerNodeControlTypeDurationText) ]) {
|
||||||
|
[controls addObject:availableControls[ @(ASVideoPlayerNodeControlTypeDurationText) ]];
|
||||||
|
}
|
||||||
|
|
||||||
|
return controls;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Layout
|
||||||
|
- (ASLayoutSpec*)videoPlayerNodeLayoutSpec:(ASVideoPlayerNode *)videoPlayer forControls:(NSDictionary *)controls forMaximumSize:(CGSize)maxSize
|
||||||
|
{
|
||||||
ASLayoutSpec *spacer = [[ASLayoutSpec alloc] init];
|
ASLayoutSpec *spacer = [[ASLayoutSpec alloc] init];
|
||||||
spacer.flexGrow = YES;
|
spacer.flexGrow = YES;
|
||||||
|
|
||||||
|
UIEdgeInsets insets = UIEdgeInsetsMake(10.0, 10.0, 10.0, 10.0);
|
||||||
|
|
||||||
|
if (controls[ @(ASVideoPlayerNodeControlTypeScrubber) ]) {
|
||||||
|
ASDisplayNode *scrubber = controls[ @(ASVideoPlayerNodeControlTypeScrubber) ];
|
||||||
|
scrubber.preferredFrameSize = CGSizeMake(maxSize.width, 44.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
NSArray *controlBarControls = [self controlsForControlBar:controls];
|
||||||
|
NSMutableArray *topBarControls = [[NSMutableArray alloc] init];
|
||||||
|
|
||||||
|
//Our custom control
|
||||||
|
if (controls[@"muteControl"]) {
|
||||||
|
[topBarControls addObject:controls[@"muteControl"]];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ASStackLayoutSpec *topBarSpec = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionHorizontal
|
||||||
|
spacing:10.0
|
||||||
|
justifyContent:ASStackLayoutJustifyContentStart
|
||||||
|
alignItems:ASStackLayoutAlignItemsCenter
|
||||||
|
children:topBarControls];
|
||||||
|
|
||||||
|
ASInsetLayoutSpec *topBarInsetSpec = [ASInsetLayoutSpec insetLayoutSpecWithInsets:insets child:topBarSpec];
|
||||||
|
|
||||||
ASStackLayoutSpec *controlbarSpec = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionHorizontal
|
ASStackLayoutSpec *controlbarSpec = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionHorizontal
|
||||||
spacing:10.0
|
spacing:10.0
|
||||||
justifyContent:ASStackLayoutJustifyContentStart
|
justifyContent:ASStackLayoutJustifyContentStart
|
||||||
alignItems:ASStackLayoutAlignItemsCenter
|
alignItems:ASStackLayoutAlignItemsCenter
|
||||||
children:bottomControls];
|
children: controlBarControls ];
|
||||||
controlbarSpec.alignSelf = ASStackLayoutAlignSelfStretch;
|
controlbarSpec.alignSelf = ASStackLayoutAlignSelfStretch;
|
||||||
|
|
||||||
UIEdgeInsets insets = UIEdgeInsetsMake(10.0, 10.0, 10.0, 10.0);
|
|
||||||
|
|
||||||
ASInsetLayoutSpec *controlbarInsetSpec = [ASInsetLayoutSpec insetLayoutSpecWithInsets:insets child:controlbarSpec];
|
ASInsetLayoutSpec *controlbarInsetSpec = [ASInsetLayoutSpec insetLayoutSpecWithInsets:insets child:controlbarSpec];
|
||||||
|
|
||||||
@ -144,9 +209,9 @@
|
|||||||
spacing:0.0
|
spacing:0.0
|
||||||
justifyContent:ASStackLayoutJustifyContentStart
|
justifyContent:ASStackLayoutJustifyContentStart
|
||||||
alignItems:ASStackLayoutAlignItemsStart
|
alignItems:ASStackLayoutAlignItemsStart
|
||||||
children:@[ spacer, controlbarInsetSpec ]];
|
children:@[topBarInsetSpec, spacer, controlbarInsetSpec]];
|
||||||
|
|
||||||
|
|
||||||
return mainVerticalStack;
|
return mainVerticalStack;
|
||||||
}*/
|
|
||||||
|
}
|
||||||
@end
|
@end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user