HLS videos now repeat at the end fine

This commit is contained in:
Gareth Reese 2016-03-03 13:34:38 +00:00
parent 1eebe4d31a
commit 7c20ba0cdf

View File

@ -25,7 +25,7 @@
AVAsset *_asset; AVAsset *_asset;
NSURL *_url; NSURL *_url;
AVPlayerItem *_currentItem; AVPlayerItem *_currentPlayerItem;
AVPlayer *_player; AVPlayer *_player;
ASImageNode *_placeholderImageNode; ASImageNode *_placeholderImageNode;
@ -44,10 +44,10 @@
//TODO: Have a bash at supplying a preview image node so that we're deferring the construction of the video as it eats memory at the moment //TODO: Have a bash at supplying a preview image node so that we're deferring the construction of the video as it eats memory at the moment
//TODO: URL file videos don't seem to repeat
//TODO: Have a look at any unit tests //TODO: Have a look at any unit tests
//TODO: URL-based streams show a black square when paused, the AVAsset ones pause fine
#pragma mark - Construction and Layout #pragma mark - Construction and Layout
@ -99,8 +99,8 @@
ASDisplayNode* playerNode = [[ASDisplayNode alloc] initWithLayerBlock:^CALayer *{ ASDisplayNode* playerNode = [[ASDisplayNode alloc] initWithLayerBlock:^CALayer *{
AVPlayerLayer *playerLayer = [[AVPlayerLayer alloc] init]; AVPlayerLayer *playerLayer = [[AVPlayerLayer alloc] init];
if (!_player) { if (!_player) {
_currentItem = [self constructPlayerItemFromInitData]; [self constructCurrentPlayerItemFromInitData];
_player = [AVPlayer playerWithPlayerItem:_currentItem]; _player = [AVPlayer playerWithPlayerItem:_currentPlayerItem];
_player.muted = _muted; _player.muted = _muted;
} }
playerLayer.player = _player; playerLayer.player = _player;
@ -111,22 +111,24 @@
return playerNode; return playerNode;
} }
- (AVPlayerItem*) constructPlayerItemFromInitData { - (void) constructCurrentPlayerItemFromInitData {
ASDisplayNodeAssert(_asset || _url, @"Must be initialised with an AVAsset or URL"); ASDisplayNodeAssert(_asset || _url, @"Must be initialised with an AVAsset or URL");
if (_currentPlayerItem)
[[NSNotificationCenter defaultCenter] removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
if (_asset) { if (_asset) {
return [[AVPlayerItem alloc] initWithAsset:_asset]; _currentPlayerItem = [[AVPlayerItem alloc] initWithAsset:_asset];
} else if (_url) { } else if (_url) {
return [[AVPlayerItem alloc] initWithURL:_url]; _currentPlayerItem = [[AVPlayerItem alloc] initWithURL:_url];
} }
return nil; if (_currentPlayerItem)
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didPlayToEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:_currentPlayerItem];
} }
- (void)didLoad - (void)didLoad
{ {
[super didLoad]; [super didLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didPlayToEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
if (_shouldBePlaying) { if (_shouldBePlaying) {
_playerNode = [self constructPlayerNode]; _playerNode = [self constructPlayerNode];
@ -224,11 +226,11 @@
// If we don't yet have a placeholder image update it now that we should have data available for it // If we don't yet have a placeholder image update it now that we should have data available for it
if (!_placeholderImageNode) { if (!_placeholderImageNode) {
if (_currentItem && if (_currentPlayerItem &&
_currentItem.tracks.count > 0 && _currentPlayerItem.tracks.count > 0 &&
_currentItem.tracks[0].assetTrack && _currentPlayerItem.tracks[0].assetTrack &&
_currentItem.tracks[0].assetTrack.asset) { _currentPlayerItem.tracks[0].assetTrack.asset) {
_asset = _currentItem.tracks[0].assetTrack.asset; _asset = _currentPlayerItem.tracks[0].assetTrack.asset;
[self setPlaceholderImagefromAsset:_asset]; [self setPlaceholderImagefromAsset:_asset];
} }
} }
@ -241,7 +243,6 @@
- (void)didPlayToEnd:(NSNotification *)notification - (void)didPlayToEnd:(NSNotification *)notification
{ {
if (ASObjectIsEqual([[notification object] asset], _asset)) {
if ([_delegate respondsToSelector:@selector(videoPlaybackDidFinish:)]) { if ([_delegate respondsToSelector:@selector(videoPlaybackDidFinish:)]) {
[_delegate videoPlaybackDidFinish:self]; [_delegate videoPlaybackDidFinish:self];
} }
@ -253,7 +254,6 @@
[self pause]; [self pause];
} }
} }
}
- (void)tapped - (void)tapped
{ {
@ -273,7 +273,7 @@
[super fetchData]; [super fetchData];
@try { @try {
[_currentItem removeObserver:self forKeyPath:NSStringFromSelector(@selector(status))]; [_currentPlayerItem removeObserver:self forKeyPath:NSStringFromSelector(@selector(status))];
} }
@catch (NSException * __unused exception) { @catch (NSException * __unused exception) {
NSLog(@"unnecessary removal in fetch data"); NSLog(@"unnecessary removal in fetch data");
@ -281,13 +281,13 @@
{ {
ASDN::MutexLocker l(_videoLock); ASDN::MutexLocker l(_videoLock);
_currentItem = [self constructPlayerItemFromInitData]; [self constructCurrentPlayerItemFromInitData];
[_currentItem addObserver:self forKeyPath:NSStringFromSelector(@selector(status)) options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:NULL]; [_currentPlayerItem addObserver:self forKeyPath:NSStringFromSelector(@selector(status)) options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:NULL];
if (_player) { if (_player) {
[_player replaceCurrentItemWithPlayerItem:_currentItem]; [_player replaceCurrentItemWithPlayerItem:_currentPlayerItem];
} else { } else {
_player = [[AVPlayer alloc] initWithPlayerItem:_currentItem]; _player = [[AVPlayer alloc] initWithPlayerItem:_currentPlayerItem];
_player.muted = _muted; _player.muted = _muted;
} }
} }
@ -316,8 +316,8 @@
if (isVisible) { if (isVisible) {
if (_playerNode.isNodeLoaded) { if (_playerNode.isNodeLoaded) {
if (!_player) { if (!_player) {
_currentItem = [self constructPlayerItemFromInitData]; [self constructCurrentPlayerItemFromInitData];
_player = [AVPlayer playerWithPlayerItem:_currentItem]; _player = [AVPlayer playerWithPlayerItem:_currentPlayerItem];
_player.muted = _muted; _player.muted = _muted;
} }
((AVPlayerLayer *)_playerNode.layer).player = _player; ((AVPlayerLayer *)_playerNode.layer).player = _player;
@ -451,7 +451,7 @@
- (BOOL)ready - (BOOL)ready
{ {
return _currentItem.status == AVPlayerItemStatusReadyToPlay; return _currentPlayerItem.status == AVPlayerItemStatusReadyToPlay;
} }
- (void)pause - (void)pause
@ -484,13 +484,13 @@
- (AVPlayerItem *)curentItem - (AVPlayerItem *)curentItem
{ {
ASDN::MutexLocker l(_videoLock); ASDN::MutexLocker l(_videoLock);
return _currentItem; return _currentPlayerItem;
} }
- (void)setCurrentItem:(AVPlayerItem *)currentItem - (void)setCurrentItem:(AVPlayerItem *)currentItem
{ {
ASDN::MutexLocker l(_videoLock); ASDN::MutexLocker l(_videoLock);
_currentItem = currentItem; _currentPlayerItem = currentItem;
} }
- (ASDisplayNode *)playerNode - (ASDisplayNode *)playerNode
@ -509,9 +509,11 @@
- (void)dealloc - (void)dealloc
{ {
if (_currentPlayerItem)
[[NSNotificationCenter defaultCenter] removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
@try { @try {
[_currentItem removeObserver:self forKeyPath:NSStringFromSelector(@selector(status))]; [_currentPlayerItem removeObserver:self forKeyPath:NSStringFromSelector(@selector(status))];
} }
@catch (NSException * __unused exception) { @catch (NSException * __unused exception) {
NSLog(@"unnecessary removal in dealloc"); NSLog(@"unnecessary removal in dealloc");