Skip to content
This repository was archived by the owner on Feb 2, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion AsyncDisplayKit/ASVideoNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#import <AsyncDisplayKit/ASButtonNode.h>
#import <AsyncDisplayKit/ASNetworkImageNode.h>

@class AVAsset, AVPlayer, AVPlayerItem;
@class AVAsset, AVPlayer, AVPlayerItem, AVVideoComposition, AVAudioMix;
@protocol ASVideoNodeDelegate;

typedef enum {
Expand Down Expand Up @@ -41,6 +41,8 @@ NS_ASSUME_NONNULL_BEGIN
- (BOOL)isPlaying;

@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) AVPlayerItem *currentItem;
Expand Down Expand Up @@ -121,6 +123,12 @@ NS_ASSUME_NONNULL_BEGIN
* @param videoNode The 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
* @param videoNode The videoNode
Expand Down
45 changes: 42 additions & 3 deletions AsyncDisplayKit/ASVideoNode.mm
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ @interface ASVideoNode ()
unsigned int delegateVideoNodeDidPlayToTimeInterval:1;
unsigned int delegateVideoNodeDidStartInitialLoading:1;
unsigned int delegateVideoNodeDidFinishInitialLoading:1;
unsigned int delegateVideoNodeDidSetCurrentItem:1;
unsigned int delegateVideoNodeDidStallAtTimeInterval:1;
unsigned int delegateVideoNodeDidRecoverFromStall:1;

Expand All @@ -68,6 +69,8 @@ @interface ASVideoNode ()
ASVideoNodePlayerState _playerState;

AVAsset *_asset;
AVVideoComposition *_videoComposition;
AVAudioMix *_audioMix;

AVPlayerItem *_currentPlayerItem;
AVPlayer *_player;
Expand Down Expand Up @@ -124,7 +127,10 @@ - (AVPlayerItem *)constructPlayerItem
ASDN::MutexLocker l(_propertyLock);

if (_asset != nil) {
return [[AVPlayerItem alloc] initWithAsset:_asset];
AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithAsset:_asset];
playerItem.videoComposition = _videoComposition;
playerItem.audioMix = _audioMix;
return playerItem;
}

return nil;
Expand Down Expand Up @@ -153,7 +159,11 @@ - (void)prepareToPlayAsset:(AVAsset *)asset withKeys:(NSArray<NSString *> *)requ
} else {
self.player = [AVPlayer playerWithPlayerItem:playerItem];
}


if (_delegateFlags.delegateVideoNodeDidSetCurrentItem) {
[_delegate videoNode:self didSetCurrentItem:playerItem];
}

if (self.image == nil && self.URL == nil) {
[self generatePlaceholderImage];
}
Expand Down Expand Up @@ -448,6 +458,34 @@ - (AVAsset *)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
{
ASDN::MutexLocker l(_propertyLock);
Expand All @@ -473,6 +511,7 @@ - (void)setDelegate:(id<ASVideoNodeDelegate>)delegate
_delegateFlags.delegateVideoNodeDidPlayToTimeInterval = [_delegate respondsToSelector:@selector(videoNode:didPlayToTimeInterval:)];
_delegateFlags.delegateVideoNodeDidStartInitialLoading = [_delegate respondsToSelector:@selector(videoNodeDidStartInitialLoading:)];
_delegateFlags.delegateVideoNodeDidFinishInitialLoading = [_delegate respondsToSelector:@selector(videoNodeDidFinishInitialLoading:)];
_delegateFlags.delegateVideoNodeDidSetCurrentItem = [_delegate respondsToSelector:@selector(videoNode:didSetCurrentItem:)];
_delegateFlags.delegateVideoNodeDidStallAtTimeInterval = [_delegate respondsToSelector:@selector(videoNode:didStallAtTimeInterval:)];
_delegateFlags.delegateVideoNodeDidRecoverFromStall = [_delegate respondsToSelector:@selector(videoNodeDidRecoverFromStall:)];

Expand Down Expand Up @@ -697,4 +736,4 @@ - (void)dealloc
}

@end
#endif
#endif
37 changes: 36 additions & 1 deletion AsyncDisplayKit/ASVideoPlayerNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,10 @@ NS_ASSUME_NONNULL_BEGIN

- (instancetype)initWithUrl:(NSURL*)url;
- (instancetype)initWithAsset:(AVAsset*)asset;
- (instancetype)initWithAsset:(AVAsset *)asset videoComposition:(AVVideoComposition *)videoComposition audioMix:(AVAudioMix *)audioMix;
- (instancetype)initWithUrl:(NSURL *)url 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
- (void)seekToTime:(CGFloat)percentComplete;
Expand Down Expand Up @@ -156,10 +158,43 @@ NS_ASSUME_NONNULL_BEGIN

/**
* @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;

/**
* @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
NS_ASSUME_NONNULL_END
#endif
93 changes: 91 additions & 2 deletions AsyncDisplayKit/ASVideoPlayerNode.mm
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,17 @@ @interface ASVideoPlayerNode() <ASVideoNodeDelegate>
unsigned int delegateVideoNodeShouldChangeState:1;
unsigned int delegateVideoNodePlaybackDidFinish: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;

NSURL *_url;
AVAsset *_asset;
AVVideoComposition *_videoComposition;
AVAudioMix *_audioMix;

ASVideoNode *_videoNode;

Expand Down Expand Up @@ -118,6 +125,22 @@ - (instancetype)initWithAsset:(AVAsset *)asset
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
{
if (!(self = [super init])) {
Expand Down Expand Up @@ -147,6 +170,22 @@ - (instancetype)initWithAsset:(AVAsset *)asset loadAssetWhenNodeBecomesVisible:(
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
{
_defaultControlsColor = [UIColor whiteColor];
Expand All @@ -156,6 +195,8 @@ - (void)_init
_videoNode.delegate = self;
if (_loadAssetWhenNodeBecomesVisible == NO) {
_videoNode.asset = _asset;
_videoNode.videoComposition = _videoComposition;
_videoNode.audioMix = _audioMix;
}
[self addSubnode:_videoNode];
}
Expand All @@ -175,8 +216,16 @@ - (void)visibleStateDidChange:(BOOL)isVisible

ASDN::MutexLocker l(_propertyLock);

if (isVisible && _loadAssetWhenNodeBecomesVisible && _asset != _videoNode.asset) {
_videoNode.asset = _asset;
if (isVisible && _loadAssetWhenNodeBecomesVisible) {
if (_asset != _videoNode.asset) {
_videoNode.asset = _asset;
}
if (_videoComposition != _videoNode.videoComposition) {
_videoNode.videoComposition = _videoComposition;
}
if (_audioMix != _videoNode.audioMix) {
_videoNode.audioMix = _audioMix;
}
}
}

Expand Down Expand Up @@ -480,6 +529,41 @@ - (void)didTapVideoNode:(ASVideoNode *)videoNode
}
}

- (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
- (void)togglePlayPause
{
Expand Down Expand Up @@ -702,6 +786,11 @@ - (void)setDelegate:(id<ASVideoPlayerNodeDelegate>)delegate
_delegateFlags.delegateTimeLabelAttributedString = [_delegate respondsToSelector:@selector(videoPlayerNode:timeStringForTimeLabelType:forTime:)];
_delegateFlags.delegatePlaybackButtonTint = [_delegate respondsToSelector:@selector(videoPlayerNodePlaybackButtonTint:)];
_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:)];
}
}

Expand Down