mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 14:45:21 +00:00
[ASVideoNode, ASVideoPlayerNode] Add video composition and audio mix capabilities (#1800)
* [ASVideoNode] Add delegate method called when the currentItem is set. * [ASVideoNode] Add videoComposition and audioMix properties to the ASVideoNode. * [ASVideoPlayerNode] Add new initialiser with videoComposition and audioMix, and forward new delegate method. * [ASVideoPlayerNode] Forward missing ASVideoNodeDelegate methods.
This commit is contained in:
@@ -12,7 +12,7 @@
|
|||||||
#import <AsyncDisplayKit/ASButtonNode.h>
|
#import <AsyncDisplayKit/ASButtonNode.h>
|
||||||
#import <AsyncDisplayKit/ASNetworkImageNode.h>
|
#import <AsyncDisplayKit/ASNetworkImageNode.h>
|
||||||
|
|
||||||
@class AVAsset, AVPlayer, AVPlayerItem;
|
@class AVAsset, AVPlayer, AVPlayerItem, AVVideoComposition, AVAudioMix;
|
||||||
@protocol ASVideoNodeDelegate;
|
@protocol ASVideoNodeDelegate;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -41,6 +41,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
- (BOOL)isPlaying;
|
- (BOOL)isPlaying;
|
||||||
|
|
||||||
@property (nullable, atomic, strong, readwrite) AVAsset *asset;
|
@property (nullable, atomic, strong, readwrite) AVAsset *asset;
|
||||||
|
@property (nullable, atomic, strong, readwrite) AVVideoComposition *videoComposition;
|
||||||
|
@property (nullable, atomic, strong, readwrite) AVAudioMix *audioMix;
|
||||||
|
|
||||||
@property (nullable, atomic, strong, readonly) AVPlayer *player;
|
@property (nullable, atomic, strong, readonly) AVPlayer *player;
|
||||||
@property (nullable, atomic, strong, readonly) AVPlayerItem *currentItem;
|
@property (nullable, atomic, strong, readonly) AVPlayerItem *currentItem;
|
||||||
@@ -121,6 +123,12 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
* @param videoNode The videoNode
|
* @param videoNode The videoNode
|
||||||
*/
|
*/
|
||||||
- (void)videoNodeDidFinishInitialLoading:(ASVideoNode *)videoNode;
|
- (void)videoNodeDidFinishInitialLoading:(ASVideoNode *)videoNode;
|
||||||
|
/**
|
||||||
|
* @abstract Delegate method invoked when the AVPlayerItem for the asset has been set up and can be accessed throught currentItem.
|
||||||
|
* @param videoNode The videoNode.
|
||||||
|
* @param currentItem The AVPlayerItem that was constructed from the asset.
|
||||||
|
*/
|
||||||
|
- (void)videoNode:(ASVideoNode *)videoNode didSetCurrentItem:(AVPlayerItem *)currentItem;
|
||||||
/**
|
/**
|
||||||
* @abstract Delegate method invoked when the video node has recovered from the stall
|
* @abstract Delegate method invoked when the video node has recovered from the stall
|
||||||
* @param videoNode The videoNode
|
* @param videoNode The videoNode
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ static NSString * const kStatus = @"status";
|
|||||||
unsigned int delegateVideoNodeDidPlayToTimeInterval:1;
|
unsigned int delegateVideoNodeDidPlayToTimeInterval:1;
|
||||||
unsigned int delegateVideoNodeDidStartInitialLoading:1;
|
unsigned int delegateVideoNodeDidStartInitialLoading:1;
|
||||||
unsigned int delegateVideoNodeDidFinishInitialLoading:1;
|
unsigned int delegateVideoNodeDidFinishInitialLoading:1;
|
||||||
|
unsigned int delegateVideoNodeDidSetCurrentItem:1;
|
||||||
unsigned int delegateVideoNodeDidStallAtTimeInterval:1;
|
unsigned int delegateVideoNodeDidStallAtTimeInterval:1;
|
||||||
unsigned int delegateVideoNodeDidRecoverFromStall:1;
|
unsigned int delegateVideoNodeDidRecoverFromStall:1;
|
||||||
|
|
||||||
@@ -68,6 +69,8 @@ static NSString * const kStatus = @"status";
|
|||||||
ASVideoNodePlayerState _playerState;
|
ASVideoNodePlayerState _playerState;
|
||||||
|
|
||||||
AVAsset *_asset;
|
AVAsset *_asset;
|
||||||
|
AVVideoComposition *_videoComposition;
|
||||||
|
AVAudioMix *_audioMix;
|
||||||
|
|
||||||
AVPlayerItem *_currentPlayerItem;
|
AVPlayerItem *_currentPlayerItem;
|
||||||
AVPlayer *_player;
|
AVPlayer *_player;
|
||||||
@@ -124,7 +127,10 @@ static NSString * const kStatus = @"status";
|
|||||||
ASDN::MutexLocker l(_propertyLock);
|
ASDN::MutexLocker l(_propertyLock);
|
||||||
|
|
||||||
if (_asset != nil) {
|
if (_asset != nil) {
|
||||||
return [[AVPlayerItem alloc] initWithAsset:_asset];
|
AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithAsset:_asset];
|
||||||
|
playerItem.videoComposition = _videoComposition;
|
||||||
|
playerItem.audioMix = _audioMix;
|
||||||
|
return playerItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil;
|
return nil;
|
||||||
@@ -154,6 +160,10 @@ static NSString * const kStatus = @"status";
|
|||||||
self.player = [AVPlayer playerWithPlayerItem:playerItem];
|
self.player = [AVPlayer playerWithPlayerItem:playerItem];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_delegateFlags.delegateVideoNodeDidSetCurrentItem) {
|
||||||
|
[_delegate videoNode:self didSetCurrentItem:playerItem];
|
||||||
|
}
|
||||||
|
|
||||||
if (self.image == nil && self.URL == nil) {
|
if (self.image == nil && self.URL == nil) {
|
||||||
[self generatePlaceholderImage];
|
[self generatePlaceholderImage];
|
||||||
}
|
}
|
||||||
@@ -448,6 +458,34 @@ static NSString * const kStatus = @"status";
|
|||||||
return _asset;
|
return _asset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)setVideoComposition:(AVVideoComposition *)videoComposition
|
||||||
|
{
|
||||||
|
ASDN::MutexLocker l(_propertyLock);
|
||||||
|
|
||||||
|
_videoComposition = videoComposition;
|
||||||
|
_currentPlayerItem.videoComposition = videoComposition;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (AVVideoComposition *)videoComposition
|
||||||
|
{
|
||||||
|
ASDN::MutexLocker l(_propertyLock);
|
||||||
|
return _videoComposition;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setAudioMix:(AVAudioMix *)audioMix
|
||||||
|
{
|
||||||
|
ASDN::MutexLocker l(_propertyLock);
|
||||||
|
|
||||||
|
_audioMix = audioMix;
|
||||||
|
_currentPlayerItem.audioMix = audioMix;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (AVAudioMix *)audioMix
|
||||||
|
{
|
||||||
|
ASDN::MutexLocker l(_propertyLock);
|
||||||
|
return _audioMix;
|
||||||
|
}
|
||||||
|
|
||||||
- (AVPlayer *)player
|
- (AVPlayer *)player
|
||||||
{
|
{
|
||||||
ASDN::MutexLocker l(_propertyLock);
|
ASDN::MutexLocker l(_propertyLock);
|
||||||
@@ -473,6 +511,7 @@ static NSString * const kStatus = @"status";
|
|||||||
_delegateFlags.delegateVideoNodeDidPlayToTimeInterval = [_delegate respondsToSelector:@selector(videoNode:didPlayToTimeInterval:)];
|
_delegateFlags.delegateVideoNodeDidPlayToTimeInterval = [_delegate respondsToSelector:@selector(videoNode:didPlayToTimeInterval:)];
|
||||||
_delegateFlags.delegateVideoNodeDidStartInitialLoading = [_delegate respondsToSelector:@selector(videoNodeDidStartInitialLoading:)];
|
_delegateFlags.delegateVideoNodeDidStartInitialLoading = [_delegate respondsToSelector:@selector(videoNodeDidStartInitialLoading:)];
|
||||||
_delegateFlags.delegateVideoNodeDidFinishInitialLoading = [_delegate respondsToSelector:@selector(videoNodeDidFinishInitialLoading:)];
|
_delegateFlags.delegateVideoNodeDidFinishInitialLoading = [_delegate respondsToSelector:@selector(videoNodeDidFinishInitialLoading:)];
|
||||||
|
_delegateFlags.delegateVideoNodeDidSetCurrentItem = [_delegate respondsToSelector:@selector(videoNode:didSetCurrentItem:)];
|
||||||
_delegateFlags.delegateVideoNodeDidStallAtTimeInterval = [_delegate respondsToSelector:@selector(videoNode:didStallAtTimeInterval:)];
|
_delegateFlags.delegateVideoNodeDidStallAtTimeInterval = [_delegate respondsToSelector:@selector(videoNode:didStallAtTimeInterval:)];
|
||||||
_delegateFlags.delegateVideoNodeDidRecoverFromStall = [_delegate respondsToSelector:@selector(videoNodeDidRecoverFromStall:)];
|
_delegateFlags.delegateVideoNodeDidRecoverFromStall = [_delegate respondsToSelector:@selector(videoNodeDidRecoverFromStall:)];
|
||||||
|
|
||||||
|
|||||||
@@ -58,8 +58,10 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
|
|
||||||
- (instancetype)initWithUrl:(NSURL*)url;
|
- (instancetype)initWithUrl:(NSURL*)url;
|
||||||
- (instancetype)initWithAsset:(AVAsset*)asset;
|
- (instancetype)initWithAsset:(AVAsset*)asset;
|
||||||
|
- (instancetype)initWithAsset:(AVAsset *)asset videoComposition:(AVVideoComposition *)videoComposition audioMix:(AVAudioMix *)audioMix;
|
||||||
- (instancetype)initWithUrl:(NSURL *)url loadAssetWhenNodeBecomesVisible:(BOOL)loadAssetWhenNodeBecomesVisible;
|
- (instancetype)initWithUrl:(NSURL *)url loadAssetWhenNodeBecomesVisible:(BOOL)loadAssetWhenNodeBecomesVisible;
|
||||||
- (instancetype)initWithAsset:(AVAsset *)asset loadAssetWhenNodeBecomesVisible:(BOOL)loadAssetWhenNodeBecomesVisible;
|
- (instancetype)initWithAsset:(AVAsset *)asset loadAssetWhenNodeBecomesVisible:(BOOL)loadAssetWhenNodeBecomesVisible;
|
||||||
|
- (instancetype)initWithAsset:(AVAsset *)asset videoComposition:(AVVideoComposition *)videoComposition audioMix:(AVAudioMix *)audioMix loadAssetWhenNodeBecomesVisible:(BOOL)loadAssetWhenNodeBecomesVisible;
|
||||||
|
|
||||||
#pragma mark - Public API
|
#pragma mark - Public API
|
||||||
- (void)seekToTime:(CGFloat)percentComplete;
|
- (void)seekToTime:(CGFloat)percentComplete;
|
||||||
@@ -156,10 +158,43 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @abstract Delegate method invoked when the ASVideoNode has played to its end time.
|
* @abstract Delegate method invoked when the ASVideoNode has played to its end time.
|
||||||
* @param videoPlayerNode The video node has played to its end time.
|
* @param videoPlayer The video node has played to its end time.
|
||||||
*/
|
*/
|
||||||
- (void)videoPlayerNodeDidPlayToEnd:(ASVideoPlayerNode *)videoPlayer;
|
- (void)videoPlayerNodeDidPlayToEnd:(ASVideoPlayerNode *)videoPlayer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @abstract Delegate method invoked when the ASVideoNode has constructed its AVPlayerItem for the asset.
|
||||||
|
* @param videoPlayer The video player node.
|
||||||
|
* @param currentItem The AVPlayerItem that was constructed from the asset.
|
||||||
|
*/
|
||||||
|
- (void)videoPlayerNode:(ASVideoPlayerNode *)videoPlayer didSetCurrentItem:(AVPlayerItem *)currentItem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @abstract Delegate method invoked when the ASVideoNode stalls.
|
||||||
|
* @param videoPlayer The video player node that has experienced the stall
|
||||||
|
* @param second Current playback time when the stall happens
|
||||||
|
*/
|
||||||
|
- (void)videoPlayerNode:(ASVideoPlayerNode *)videoPlayer didStallAtTimeInterval:(NSTimeInterval)timeInterval;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @abstract Delegate method invoked when the ASVideoNode starts the inital asset loading
|
||||||
|
* @param videoPlayer The videoPlayer
|
||||||
|
*/
|
||||||
|
- (void)videoPlayerNodeDidStartInitialLoading:(ASVideoPlayerNode *)videoPlayer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @abstract Delegate method invoked when the ASVideoNode is done loading the asset and can start the playback
|
||||||
|
* @param videoPlayer The videoPlayer
|
||||||
|
*/
|
||||||
|
- (void)videoPlayerNodeDidFinishInitialLoading:(ASVideoPlayerNode *)videoPlayer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @abstract Delegate method invoked when the ASVideoNode has recovered from the stall
|
||||||
|
* @param videoPlayer The videoplayer
|
||||||
|
*/
|
||||||
|
- (void)videoPlayerNodeDidRecoverFromStall:(ASVideoPlayerNode *)videoPlayer;
|
||||||
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -37,10 +37,17 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
|||||||
unsigned int delegateVideoNodeShouldChangeState:1;
|
unsigned int delegateVideoNodeShouldChangeState:1;
|
||||||
unsigned int delegateVideoNodePlaybackDidFinish:1;
|
unsigned int delegateVideoNodePlaybackDidFinish:1;
|
||||||
unsigned int delegateDidTapVideoPlayerNode:1;
|
unsigned int delegateDidTapVideoPlayerNode:1;
|
||||||
|
unsigned int delegateVideoPlayerNodeDidSetCurrentItem:1;
|
||||||
|
unsigned int delegateVideoPlayerNodeDidStallAtTimeInterval:1;
|
||||||
|
unsigned int delegateVideoPlayerNodeDidStartInitialLoading:1;
|
||||||
|
unsigned int delegateVideoPlayerNodeDidFinishInitialLoading:1;
|
||||||
|
unsigned int delegateVideoPlayerNodeDidRecoverFromStall:1;
|
||||||
} _delegateFlags;
|
} _delegateFlags;
|
||||||
|
|
||||||
NSURL *_url;
|
NSURL *_url;
|
||||||
AVAsset *_asset;
|
AVAsset *_asset;
|
||||||
|
AVVideoComposition *_videoComposition;
|
||||||
|
AVAudioMix *_audioMix;
|
||||||
|
|
||||||
ASVideoNode *_videoNode;
|
ASVideoNode *_videoNode;
|
||||||
|
|
||||||
@@ -118,6 +125,22 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-(instancetype)initWithAsset:(AVAsset *)asset videoComposition:(AVVideoComposition *)videoComposition audioMix:(AVAudioMix *)audioMix
|
||||||
|
{
|
||||||
|
if (!(self = [super init])) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
_asset = asset;
|
||||||
|
_videoComposition = videoComposition;
|
||||||
|
_audioMix = audioMix;
|
||||||
|
_loadAssetWhenNodeBecomesVisible = YES;
|
||||||
|
|
||||||
|
[self _init];
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
- (instancetype)initWithUrl:(NSURL *)url loadAssetWhenNodeBecomesVisible:(BOOL)loadAssetWhenNodeBecomesVisible
|
- (instancetype)initWithUrl:(NSURL *)url loadAssetWhenNodeBecomesVisible:(BOOL)loadAssetWhenNodeBecomesVisible
|
||||||
{
|
{
|
||||||
if (!(self = [super init])) {
|
if (!(self = [super init])) {
|
||||||
@@ -147,6 +170,22 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-(instancetype)initWithAsset:(AVAsset *)asset videoComposition:(AVVideoComposition *)videoComposition audioMix:(AVAudioMix *)audioMix loadAssetWhenNodeBecomesVisible:(BOOL)loadAssetWhenNodeBecomesVisible
|
||||||
|
{
|
||||||
|
if (!(self = [super init])) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
_asset = asset;
|
||||||
|
_videoComposition = videoComposition;
|
||||||
|
_audioMix = audioMix;
|
||||||
|
_loadAssetWhenNodeBecomesVisible = loadAssetWhenNodeBecomesVisible;
|
||||||
|
|
||||||
|
[self _init];
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)_init
|
- (void)_init
|
||||||
{
|
{
|
||||||
_defaultControlsColor = [UIColor whiteColor];
|
_defaultControlsColor = [UIColor whiteColor];
|
||||||
@@ -156,6 +195,8 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
|||||||
_videoNode.delegate = self;
|
_videoNode.delegate = self;
|
||||||
if (_loadAssetWhenNodeBecomesVisible == NO) {
|
if (_loadAssetWhenNodeBecomesVisible == NO) {
|
||||||
_videoNode.asset = _asset;
|
_videoNode.asset = _asset;
|
||||||
|
_videoNode.videoComposition = _videoComposition;
|
||||||
|
_videoNode.audioMix = _audioMix;
|
||||||
}
|
}
|
||||||
[self addSubnode:_videoNode];
|
[self addSubnode:_videoNode];
|
||||||
}
|
}
|
||||||
@@ -175,8 +216,16 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
|||||||
|
|
||||||
ASDN::MutexLocker l(_propertyLock);
|
ASDN::MutexLocker l(_propertyLock);
|
||||||
|
|
||||||
if (isVisible && _loadAssetWhenNodeBecomesVisible && _asset != _videoNode.asset) {
|
if (isVisible && _loadAssetWhenNodeBecomesVisible) {
|
||||||
_videoNode.asset = _asset;
|
if (_asset != _videoNode.asset) {
|
||||||
|
_videoNode.asset = _asset;
|
||||||
|
}
|
||||||
|
if (_videoComposition != _videoNode.videoComposition) {
|
||||||
|
_videoNode.videoComposition = _videoComposition;
|
||||||
|
}
|
||||||
|
if (_audioMix != _videoNode.audioMix) {
|
||||||
|
_videoNode.audioMix = _audioMix;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -480,6 +529,41 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)videoNode:(ASVideoNode *)videoNode didSetCurrentItem:(AVPlayerItem *)currentItem
|
||||||
|
{
|
||||||
|
if (_delegateFlags.delegateVideoPlayerNodeDidSetCurrentItem) {
|
||||||
|
[_delegate videoPlayerNode:self didSetCurrentItem:currentItem];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)videoNode:(ASVideoNode *)videoNode didStallAtTimeInterval:(NSTimeInterval)timeInterval
|
||||||
|
{
|
||||||
|
if (_delegateFlags.delegateVideoPlayerNodeDidStallAtTimeInterval) {
|
||||||
|
[_delegate videoPlayerNode:self didStallAtTimeInterval:timeInterval];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)videoNodeDidStartInitialLoading:(ASVideoNode *)videoNode
|
||||||
|
{
|
||||||
|
if (_delegateFlags.delegateVideoPlayerNodeDidStartInitialLoading) {
|
||||||
|
[_delegate videoPlayerNodeDidStartInitialLoading:self];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)videoNodeDidFinishInitialLoading:(ASVideoNode *)videoNode
|
||||||
|
{
|
||||||
|
if (_delegateFlags.delegateVideoPlayerNodeDidFinishInitialLoading) {
|
||||||
|
[_delegate videoPlayerNodeDidFinishInitialLoading:self];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)videoNodeDidRecoverFromStall:(ASVideoNode *)videoNode
|
||||||
|
{
|
||||||
|
if (_delegateFlags.delegateVideoPlayerNodeDidRecoverFromStall) {
|
||||||
|
[_delegate videoPlayerNodeDidRecoverFromStall:self];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark - Actions
|
#pragma mark - Actions
|
||||||
- (void)togglePlayPause
|
- (void)togglePlayPause
|
||||||
{
|
{
|
||||||
@@ -702,6 +786,11 @@ static void *ASVideoPlayerNodeContext = &ASVideoPlayerNodeContext;
|
|||||||
_delegateFlags.delegateTimeLabelAttributedString = [_delegate respondsToSelector:@selector(videoPlayerNode:timeStringForTimeLabelType:forTime:)];
|
_delegateFlags.delegateTimeLabelAttributedString = [_delegate respondsToSelector:@selector(videoPlayerNode:timeStringForTimeLabelType:forTime:)];
|
||||||
_delegateFlags.delegatePlaybackButtonTint = [_delegate respondsToSelector:@selector(videoPlayerNodePlaybackButtonTint:)];
|
_delegateFlags.delegatePlaybackButtonTint = [_delegate respondsToSelector:@selector(videoPlayerNodePlaybackButtonTint:)];
|
||||||
_delegateFlags.delegateDidTapVideoPlayerNode = [_delegate respondsToSelector:@selector(didTapVideoPlayerNode:)];
|
_delegateFlags.delegateDidTapVideoPlayerNode = [_delegate respondsToSelector:@selector(didTapVideoPlayerNode:)];
|
||||||
|
_delegateFlags.delegateVideoPlayerNodeDidSetCurrentItem = [_delegate respondsToSelector:@selector(videoPlayerNode:didSetCurrentItem:)];
|
||||||
|
_delegateFlags.delegateVideoPlayerNodeDidStallAtTimeInterval = [_delegate respondsToSelector:@selector(videoPlayerNode:didStallAtTimeInterval:)];
|
||||||
|
_delegateFlags.delegateVideoPlayerNodeDidStartInitialLoading = [_delegate respondsToSelector:@selector(videoPlayerNodeDidStartInitialLoading:)];
|
||||||
|
_delegateFlags.delegateVideoPlayerNodeDidFinishInitialLoading = [_delegate respondsToSelector:@selector(videoPlayerNodeDidFinishInitialLoading:)];
|
||||||
|
_delegateFlags.delegateVideoPlayerNodeDidRecoverFromStall = [_delegate respondsToSelector:@selector(videoPlayerNodeDidRecoverFromStall:)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user