Unverified Commit 0418d8a9 authored by Hampton Maxwell's avatar Hampton Maxwell Committed by GitHub
Browse files

Merge pull request #1076 from react-native-community/feature/ios-configurable-seek

Ability to specify seek tolerance on iOS
parents dc4c180c 9401328d
Loading
Loading
Loading
Loading
+44 −0
Changes for README.md: 44 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -240,6 +240,11 @@ var styles = StyleSheet.create({
* [onLoad](#onload)
* [onLoadStart](#onloadstart)

### Methods
* [seek](#seek)

### Configurable props

#### allowsExternalPlayback
Indicates whether the player allows switching to external playback mode such as AirPlay or HDMI.
* **true (default)** - allow switching to external playback mode
@@ -502,6 +507,45 @@ Example:

Platforms: all

### Methods
Methods operate on a ref to the Video element. You can create a ref using code like:
```
return (
  <Video source={...}
    ref => (this.player = ref) />
);
```

#### seek()
`seek(seconds)`

Seek to the specified position represented by seconds. seconds is a float value.

`seek()` can only be called after the `onLoad` event has fired.

Example:
```
this.player.seek(200); // Seek to 3 minutes, 20 seconds
```

Platforms: all

##### Exact seek

By default iOS seeks within 100 milliseconds of the target position. If you need more accuracy, you can use the seek with tolerance method:

`seek(seconds, tolerance)`

tolerance is the max distance in milliseconds from the seconds position that's allowed. Using a more exact tolerance can cause seeks to take longer. If you want to seek exactly, set tolerance to 0.

Example:
```
this.player.seek(120, 50); // Seek to 2 minutes with +/- 50 milliseconds accuracy
```

Platforms: iOS


### Additional props

To see the full list of available props, you can check the [propTypes](https://github.com/react-native-community/react-native-video/blob/master/Video.js#L246) of the Video.js component.
+15 −3
Changes for Video.js: 15 added lines, 3 removed lines.
Original line number Diff line number Diff line
import React, {Component} from 'react';
import PropTypes from 'prop-types';
import {StyleSheet, requireNativeComponent, NativeModules, View, ViewPropTypes, Image} from 'react-native';
import {StyleSheet, requireNativeComponent, NativeModules, View, ViewPropTypes, Image, Platform} from 'react-native';
import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource';
import TextTrackType from './TextTrackType';
import VideoResizeMode from './VideoResizeMode.js';
@@ -27,8 +27,17 @@ export default class Video extends Component {
    this._root.setNativeProps(nativeProps);
  }

  seek = (time) => {
  seek = (time, tolerance = 100) => {
    if (Platform.OS === 'ios') {
      this.setNativeProps({
        seek: {
          time,
          tolerance
        }
      });
    } else {
      this.setNativeProps({ seek: time });
    }
  };

  presentFullscreenPlayer = () => {
@@ -250,7 +259,10 @@ export default class Video extends Component {
Video.propTypes = {
  /* Native only */
  src: PropTypes.object,
  seek: PropTypes.number,
  seek: PropTypes.oneOfType([
    PropTypes.number,
    PropTypes.object
  ]),
  fullscreen: PropTypes.bool,
  onVideoLoadStart: PropTypes.func,
  onVideoLoad: PropTypes.func,
+14 −7
Changes for ios/RCTVideo.m: 14 added lines, 7 removed lines.
Original line number Diff line number Diff line
@@ -569,21 +569,28 @@ static NSString *const timedMetadata = @"timedMetadata";

- (void)setCurrentTime:(float)currentTime
{
  [self setSeek: currentTime];
  NSDictionary *info = @{
                         @"time": [NSNumber numberWithFloat:currentTime],
                         @"tolerance": [NSNumber numberWithInt:100]
                         };
  [self setSeek:info];
}

- (void)setSeek:(float)seekTime
- (void)setSeek:(NSDictionary *)info
{
  int timeScale = 10000;
  NSNumber *seekTime = info[@"time"];
  NSNumber *seekTolerance = info[@"tolerance"];

  int timeScale = 1000;

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

    CMTime cmSeekTime = CMTimeMakeWithSeconds(seekTime, timeScale);
    CMTime cmSeekTime = CMTimeMakeWithSeconds([seekTime floatValue], timeScale);
    CMTime current = item.currentTime;
    // TODO figure out a good tolerance level
    CMTime tolerance = CMTimeMake(1000, timeScale);
    CMTime tolerance = CMTimeMake([seekTolerance floatValue], timeScale);
    BOOL wasPaused = _paused;

    if (CMTimeCompare(current, cmSeekTime) != 0) {
@@ -597,7 +604,7 @@ static NSString *const timedMetadata = @"timedMetadata";
        }
        if(self.onVideoSeek) {
            self.onVideoSeek(@{@"currentTime": [NSNumber numberWithFloat:CMTimeGetSeconds(item.currentTime)],
                               @"seekTime": [NSNumber numberWithFloat:seekTime],
                               @"seekTime": seekTime,
                               @"target": self.reactTag});
        }
      }];
@@ -608,7 +615,7 @@ static NSString *const timedMetadata = @"timedMetadata";
  } else {
    // TODO: See if this makes sense and if so, actually implement it
    _pendingSeek = true;
    _pendingSeekTime = seekTime;
    _pendingSeekTime = [seekTime floatValue];
  }
}

+1 −1
Changes for ios/RCTVideoManager.m: 1 added line, 1 removed line.
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ RCT_EXPORT_VIEW_PROPERTY(playInBackground, BOOL);
RCT_EXPORT_VIEW_PROPERTY(playWhenInactive, BOOL);
RCT_EXPORT_VIEW_PROPERTY(ignoreSilentSwitch, NSString);
RCT_EXPORT_VIEW_PROPERTY(rate, float);
RCT_EXPORT_VIEW_PROPERTY(seek, float);
RCT_EXPORT_VIEW_PROPERTY(seek, NSDictionary);
RCT_EXPORT_VIEW_PROPERTY(currentTime, float);
RCT_EXPORT_VIEW_PROPERTY(fullscreen, BOOL);
RCT_EXPORT_VIEW_PROPERTY(progressUpdateInterval, float);