Commit 45d79b70 authored by Johannes Lumpe's avatar Johannes Lumpe
Browse files

Initial commit for seeking

parent ac3e4cf7
Loading
Loading
Loading
Loading
+1 −0
Changes for RCTVideo.h: 1 added line, 0 removed lines.
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
extern NSString *const RNVideoEventLoaded;
extern NSString *const RNVideoEventLoading;
extern NSString *const RNVideoEventProgress;
extern NSString *const RNVideoEventSeek;
extern NSString *const RNVideoEventLoadingError;

@class RCTEventDispatcher;
+55 −8
Changes for RCTVideo.m: 55 added lines, 8 removed lines.
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
NSString *const RNVideoEventLoaded = @"videoLoaded";
NSString *const RNVideoEventLoading = @"videoLoading";
NSString *const RNVideoEventProgress = @"videoProgress";
NSString *const RNVideoEventSeek = @"videoSeek";
NSString *const RNVideoEventLoadingError = @"videoLoadError";

static NSString *const statusKeyPath = @"status";
@@ -23,6 +24,10 @@ static NSString *const statusKeyPath = @"status";
  /* Required to publish events */
  RCTEventDispatcher *_eventDispatcher;

  bool _pendingSeek;
  float _pendingSeekTime;
  float _lastSeekTime;

  /* For sending videoProgress events */
  id _progressUpdateTimer;
  int _progressUpdateInterval;
@@ -39,6 +44,10 @@ static NSString *const statusKeyPath = @"status";
    _eventDispatcher = eventDispatcher;
    _rate = 1.0;
    _volume = 1.0;

    _pendingSeek = false;
    _pendingSeekTime = 0.0f;
    _lastSeekTime = 0.0f;
  }
  return self;
}
@@ -169,8 +178,7 @@ static NSString *const statusKeyPath = @"status";
  _playerLayer.videoGravity = mode;
}

- (void)setPaused:(BOOL)paused
{
- (void)setPaused:(BOOL)paused {
  if (paused) {
    [self stopProgressTimer];
    [_player pause];
@@ -181,14 +189,54 @@ static NSString *const statusKeyPath = @"status";
  }
}

- (void)setRate:(float)rate
{
- (void)setSeek:(NSDictionary*)seek {
  NSNumber *seekValue = [seek objectForKey:@"time"];
  if (!seekValue) {
    return;
  }
  
  int timeScale = 10000;
  float seekTime = [RCTConvert float:seekValue];
  bool force = [RCTConvert BOOL:[seek objectForKey:@"force"]];

  if (seekTime == _lastSeekTime && !force) {
    return;
  }

  AVPlayerItem *item = _player.currentItem;
  if (item && item.status == AVPlayerItemStatusReadyToPlay) {
    // TODO check loadedTimeRanges

    CMTime cmSeekTime = CMTimeMakeWithSeconds(seekTime, timeScale);
    CMTime current = item.currentTime;
    // TODO figure out a good tolerance level
    CMTime tolerance = CMTimeMake(1000, timeScale);
    
    if (CMTimeCompare(current, cmSeekTime) != 0) {
      [_player seekToTime:cmSeekTime toleranceBefore:tolerance toleranceAfter:tolerance];
      _pendingSeek = false;
      _lastSeekTime = seekTime;
      [_eventDispatcher sendInputEventWithName:RNVideoEventSeek body:@{
        @"currentTime": [NSNumber numberWithFloat:CMTimeGetSeconds(item.currentTime)],
        @"seekTime": seekValue,
        @"target": self.reactTag
      }];
    }

  } else {
    // TODO see if this makes sense and if so,
    // actually implement it
    _pendingSeek = true;
    _pendingSeekTime = seekTime;
  }
}

- (void)setRate:(float)rate {
  _rate = rate;
  [self applyModifiers];
}

- (void)setMuted:(BOOL)muted
{
- (void)setMuted:(BOOL)muted {
  _muted = muted;
  [self applyModifiers];
}
@@ -198,8 +246,7 @@ static NSString *const statusKeyPath = @"status";
  [self applyModifiers];
}

- (void)applyModifiers
{
- (void)applyModifiers {
  /* volume must be set to 0 if muted is YES, or the video freezes playback */
  if (_muted) {
    [_player setVolume:0];
+4 −0
Changes for RCTVideoManager.m: 4 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -29,6 +29,9 @@
    RNVideoEventProgress: @{
      @"registrationName": @"onProgress"
    },
    RNVideoEventSeek: @{
      @"registrationName": @"onSeek"
    }
  };
}

@@ -39,6 +42,7 @@ RCT_EXPORT_VIEW_PROPERTY(paused, BOOL);
RCT_EXPORT_VIEW_PROPERTY(muted, BOOL);
RCT_EXPORT_VIEW_PROPERTY(volume, float);
RCT_EXPORT_VIEW_PROPERTY(rate, float);
RCT_EXPORT_VIEW_PROPERTY(seek, NSDictionary);

- (NSDictionary *)constantsToExport
{
+10 −2
Changes for Video.ios.js: 10 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ var Video = React.createClass({
    resizeMode: PropTypes.string,
    repeat: PropTypes.bool,
    paused: PropTypes.bool,
    seek: PropTypes.number,
    muted: PropTypes.bool,
    volume: PropTypes.number,
    rate: PropTypes.number,
@@ -53,6 +54,10 @@ var Video = React.createClass({
    this.props.onProgress && this.props.onProgress(event.nativeEvent);
  },

  _onSeek(event) {
    this.props.onSeek && this.props.onSeek(event.nativeEvent);
  },

  render() {
    var style = flattenStyle([styles.base, this.props.style]);
    var source = this.props.source;
@@ -71,6 +76,10 @@ var Video = React.createClass({
    }

    var nativeProps = merge(this.props, {
      seek: {
        time: this.props.seek,
        force: this.props.forceSeek
      },
      style,
      resizeMode: resizeMode,
      src: {
@@ -81,7 +90,6 @@ var Video = React.createClass({
      },
      onLoad: this._onLoad,
      onProgress: this._onProgress,

    });

    return <RCTVideo {... nativeProps} />
@@ -91,7 +99,7 @@ var Video = React.createClass({
var RCTVideo = createReactIOSNativeComponentClass({
  validAttributes: merge(ReactIOSViewAttributes.UIView,
    {src: {diff: deepDiffer}, resizeMode: true, repeat: true,
     paused: true, muted: true, volume: true, rate: true}),
     seek: {diff: () => true}, paused: true, muted: true, volume: true, rate: true}),
  uiViewClassName: 'RCTVideo',
});