diff --git a/RCTVideo.m b/RCTVideo.m index c03debf3..68b7c4ab 100644 --- a/RCTVideo.m +++ b/RCTVideo.m @@ -69,6 +69,7 @@ static NSString *const statusKeyPath = @"status"; (([_prevProgressUpdateTime timeIntervalSinceNow] * -1000.0) >= _progressUpdateInterval)) { [_eventDispatcher sendInputEventWithName:RNVideoEventProgress body:@{ @"currentTime": [NSNumber numberWithFloat:CMTimeGetSeconds(video.currentTime)], + @"playableDuration": [self calculatePlayableDuration], @"target": self.reactTag }]; @@ -76,6 +77,27 @@ static NSString *const statusKeyPath = @"status"; } } +/*! + * Calculates and returns the playable duration of the current player item using its loaded time ranges. + * + * \returns The playable duration of the current player item in seconds. + */ +- (NSNumber *)calculatePlayableDuration { + AVPlayerItem *video = _player.currentItem; + if (video.status == AVPlayerItemStatusReadyToPlay) { + __block CMTimeRange effectiveTimeRange; + [video.loadedTimeRanges enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + CMTimeRange timeRange = [obj CMTimeRangeValue]; + if (CMTimeRangeContainsTime(timeRange, video.currentTime)) { + effectiveTimeRange = timeRange; + *stop = YES; + } + }]; + return [NSNumber numberWithFloat:CMTimeGetSeconds(CMTimeRangeGetEnd(effectiveTimeRange))]; + } + return [NSNumber numberWithFloat:CMTimeGetSeconds(kCMTimeInvalid)]; +} + - (void)stopProgressTimer { [_progressUpdateTimer invalidate];