Loading README.md +10 −0 Changes for README.md: 10 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -260,6 +260,7 @@ var styles = StyleSheet.create({ * [bufferConfig](#bufferconfig) * [controls](#controls) * [filter](#filter) * [filterEnabled](#filterEnabled) * [fullscreen](#fullscreen) * [fullscreenAutorotate](#fullscreenautorotate) * [fullscreenOrientation](#fullscreenorientation) Loading Loading @@ -381,6 +382,15 @@ For more details on these filters refer to the [iOS docs](https://developer.appl Notes: 1. Using a filter can impact CPU usage. A workaround is to save the video with the filter and then load the saved video. 2. Video filter is currently not supported on HLS playlists. 3. `filterEnabled` must be set to `true` Platforms: iOS #### filterEnabled Enable video filter. * **false (default)** - Don't enable filter * **true** - Enable filter Platforms: iOS Loading Video.js +1 −0 Changes for Video.js: 1 added line, 0 removed lines. Original line number Diff line number Diff line Loading @@ -300,6 +300,7 @@ Video.propTypes = { FilterType.TRANSFER, FilterType.SEPIA ]), filterEnabled: PropTypes.bool, /* Native only */ src: PropTypes.object, seek: PropTypes.oneOfType([ Loading examples/basic/index.ios.js +70 −1 Changes for examples/basic/index.ios.js: 70 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -13,7 +13,26 @@ import { View, } from 'react-native'; import Video from 'react-native-video'; import Video,{FilterType} from 'react-native-video'; const filterTypes = [ FilterType.NONE, FilterType.INVERT, FilterType.MONOCHROME, FilterType.POSTERIZE, FilterType.FALSE, FilterType.MAXIMUMCOMPONENT, FilterType.MINIMUMCOMPONENT, FilterType.CHROME, FilterType.FADE, FilterType.INSTANT, FilterType.MONO, FilterType.NOIR, FilterType.PROCESS, FilterType.TONAL, FilterType.TRANSFER, FilterType.SEPIA ]; class VideoPlayer extends Component { constructor(props) { Loading @@ -34,6 +53,8 @@ class VideoPlayer extends Component { skin: 'custom', ignoreSilentSwitch: null, isBuffering: false, filter: FilterType.NONE, filterEnabled: true }; onLoad(data) { Loading @@ -57,6 +78,20 @@ class VideoPlayer extends Component { } } setFilter(step) { let index = filterTypes.indexOf(this.state.filter) + step; if (index === filterTypes.length) { index = 0; } else if (index === -1) { index = filterTypes.length - 1; } this.setState({ filter: filterTypes[index] }) } renderSkinControl(skin) { const isSelected = this.state.skin == skin; const selectControls = skin == 'native' || skin == 'embed'; Loading Loading @@ -141,6 +176,8 @@ class VideoPlayer extends Component { onProgress={this.onProgress} onEnd={() => { AlertIOS.alert('Done!') }} repeat={true} filter={this.state.filter} filterEnabled={this.state.filterEnabled} /> </TouchableOpacity> Loading @@ -151,6 +188,21 @@ class VideoPlayer extends Component { {this.renderSkinControl('native')} {this.renderSkinControl('embed')} </View> { (this.state.filterEnabled) ? <View style={styles.skinControl}> <TouchableOpacity onPress={() => { this.setFilter(-1) }}> <Text style={styles.controlOption}>Previous Filter</Text> </TouchableOpacity> <TouchableOpacity onPress={() => { this.setFilter(1) }}> <Text style={styles.controlOption}>Next Filter</Text> </TouchableOpacity> </View> : null } </View> <View style={styles.generalControls}> <View style={styles.rateControl}> Loading Loading @@ -212,6 +264,8 @@ class VideoPlayer extends Component { onEnd={() => { AlertIOS.alert('Done!') }} repeat={true} controls={this.state.controls} filter={this.state.filter} filterEnabled={this.state.filterEnabled} /> </View> <View style={styles.controls}> Loading @@ -221,6 +275,21 @@ class VideoPlayer extends Component { {this.renderSkinControl('native')} {this.renderSkinControl('embed')} </View> { (this.state.filterEnabled) ? <View style={styles.skinControl}> <TouchableOpacity onPress={() => { this.setFilter(-1) }}> <Text style={styles.controlOption}>Previous Filter</Text> </TouchableOpacity> <TouchableOpacity onPress={() => { this.setFilter(1) }}> <Text style={styles.controlOption}>Next Filter</Text> </TouchableOpacity> </View> : null } </View> <View style={styles.generalControls}> <View style={styles.rateControl}> Loading ios/Video/RCTVideo.m +13 −6 Changes for ios/Video/RCTVideo.m: 13 added lines, 6 removed lines. Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ static int const RCTVideoUnset = -1; { AVPlayer *_player; AVPlayerItem *_playerItem; NSDictionary *_source; BOOL _playerItemObserversSet; BOOL _playerBufferEmpty; AVPlayerLayer *_playerLayer; Loading Loading @@ -70,6 +71,7 @@ static int const RCTVideoUnset = -1; NSString * _fullscreenOrientation; BOOL _fullscreenPlayerPresented; NSString *_filterName; BOOL _filterEnabled; UIViewController * _presentingViewController; #if __has_include(<react-native-video/RCTVideoCache.h>) RCTVideoCache * _videoCache; Loading Loading @@ -328,6 +330,7 @@ static int const RCTVideoUnset = -1; - (void)setSrc:(NSDictionary *)source { _source = source; [self removePlayerLayer]; [self removePlayerTimeObserver]; [self removePlayerItemObservers]; Loading Loading @@ -1279,18 +1282,18 @@ static int const RCTVideoUnset = -1; - (void)setFilter:(NSString *)filterName { _filterName = filterName; AVAsset *asset = _playerItem.asset; if (!asset) { if (!_filterEnabled) { return; } else if ([[_source objectForKey:@"uri"] rangeOfString:@"m3u8"].location != NSNotFound) { return; // filters don't work for HLS... return } else if (!_playerItem.asset) { return; } else if (!_playerItem.videoComposition && (filterName == nil || [filterName isEqualToString:@""])) { return; // Setting up an empty filter has a cost so avoid whenever possible } // TODO: filters don't work for HLS, check & return CIFilter *filter = [CIFilter filterWithName:filterName]; _playerItem.videoComposition = [AVVideoComposition videoCompositionWithAsset:asset videoCompositionWithAsset:_playerItem.asset applyingCIFiltersWithHandler:^(AVAsynchronousCIImageFilteringRequest *_Nonnull request) { if (filter == nil) { [request finishWithImage:request.sourceImage context:nil]; Loading @@ -1303,6 +1306,10 @@ static int const RCTVideoUnset = -1; }]; } - (void)setFilterEnabled:(BOOL)filterEnabled { _filterEnabled = filterEnabled; } #pragma mark - React View Management - (void)insertReactSubview:(UIView *)view atIndex:(NSInteger)atIndex Loading ios/Video/RCTVideoManager.m +1 −0 Changes for ios/Video/RCTVideoManager.m: 1 added line, 0 removed lines. Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ RCT_EXPORT_VIEW_PROPERTY(fullscreen, BOOL); RCT_EXPORT_VIEW_PROPERTY(fullscreenAutorotate, BOOL); RCT_EXPORT_VIEW_PROPERTY(fullscreenOrientation, NSString); RCT_EXPORT_VIEW_PROPERTY(filter, NSString); RCT_EXPORT_VIEW_PROPERTY(filterEnabled, BOOL); RCT_EXPORT_VIEW_PROPERTY(progressUpdateInterval, float); /* Should support: onLoadStart, onLoad, and onError to stay consistent with Image */ RCT_EXPORT_VIEW_PROPERTY(onVideoLoadStart, RCTBubblingEventBlock); Loading Loading
README.md +10 −0 Changes for README.md: 10 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -260,6 +260,7 @@ var styles = StyleSheet.create({ * [bufferConfig](#bufferconfig) * [controls](#controls) * [filter](#filter) * [filterEnabled](#filterEnabled) * [fullscreen](#fullscreen) * [fullscreenAutorotate](#fullscreenautorotate) * [fullscreenOrientation](#fullscreenorientation) Loading Loading @@ -381,6 +382,15 @@ For more details on these filters refer to the [iOS docs](https://developer.appl Notes: 1. Using a filter can impact CPU usage. A workaround is to save the video with the filter and then load the saved video. 2. Video filter is currently not supported on HLS playlists. 3. `filterEnabled` must be set to `true` Platforms: iOS #### filterEnabled Enable video filter. * **false (default)** - Don't enable filter * **true** - Enable filter Platforms: iOS Loading
Video.js +1 −0 Changes for Video.js: 1 added line, 0 removed lines. Original line number Diff line number Diff line Loading @@ -300,6 +300,7 @@ Video.propTypes = { FilterType.TRANSFER, FilterType.SEPIA ]), filterEnabled: PropTypes.bool, /* Native only */ src: PropTypes.object, seek: PropTypes.oneOfType([ Loading
examples/basic/index.ios.js +70 −1 Changes for examples/basic/index.ios.js: 70 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -13,7 +13,26 @@ import { View, } from 'react-native'; import Video from 'react-native-video'; import Video,{FilterType} from 'react-native-video'; const filterTypes = [ FilterType.NONE, FilterType.INVERT, FilterType.MONOCHROME, FilterType.POSTERIZE, FilterType.FALSE, FilterType.MAXIMUMCOMPONENT, FilterType.MINIMUMCOMPONENT, FilterType.CHROME, FilterType.FADE, FilterType.INSTANT, FilterType.MONO, FilterType.NOIR, FilterType.PROCESS, FilterType.TONAL, FilterType.TRANSFER, FilterType.SEPIA ]; class VideoPlayer extends Component { constructor(props) { Loading @@ -34,6 +53,8 @@ class VideoPlayer extends Component { skin: 'custom', ignoreSilentSwitch: null, isBuffering: false, filter: FilterType.NONE, filterEnabled: true }; onLoad(data) { Loading @@ -57,6 +78,20 @@ class VideoPlayer extends Component { } } setFilter(step) { let index = filterTypes.indexOf(this.state.filter) + step; if (index === filterTypes.length) { index = 0; } else if (index === -1) { index = filterTypes.length - 1; } this.setState({ filter: filterTypes[index] }) } renderSkinControl(skin) { const isSelected = this.state.skin == skin; const selectControls = skin == 'native' || skin == 'embed'; Loading Loading @@ -141,6 +176,8 @@ class VideoPlayer extends Component { onProgress={this.onProgress} onEnd={() => { AlertIOS.alert('Done!') }} repeat={true} filter={this.state.filter} filterEnabled={this.state.filterEnabled} /> </TouchableOpacity> Loading @@ -151,6 +188,21 @@ class VideoPlayer extends Component { {this.renderSkinControl('native')} {this.renderSkinControl('embed')} </View> { (this.state.filterEnabled) ? <View style={styles.skinControl}> <TouchableOpacity onPress={() => { this.setFilter(-1) }}> <Text style={styles.controlOption}>Previous Filter</Text> </TouchableOpacity> <TouchableOpacity onPress={() => { this.setFilter(1) }}> <Text style={styles.controlOption}>Next Filter</Text> </TouchableOpacity> </View> : null } </View> <View style={styles.generalControls}> <View style={styles.rateControl}> Loading Loading @@ -212,6 +264,8 @@ class VideoPlayer extends Component { onEnd={() => { AlertIOS.alert('Done!') }} repeat={true} controls={this.state.controls} filter={this.state.filter} filterEnabled={this.state.filterEnabled} /> </View> <View style={styles.controls}> Loading @@ -221,6 +275,21 @@ class VideoPlayer extends Component { {this.renderSkinControl('native')} {this.renderSkinControl('embed')} </View> { (this.state.filterEnabled) ? <View style={styles.skinControl}> <TouchableOpacity onPress={() => { this.setFilter(-1) }}> <Text style={styles.controlOption}>Previous Filter</Text> </TouchableOpacity> <TouchableOpacity onPress={() => { this.setFilter(1) }}> <Text style={styles.controlOption}>Next Filter</Text> </TouchableOpacity> </View> : null } </View> <View style={styles.generalControls}> <View style={styles.rateControl}> Loading
ios/Video/RCTVideo.m +13 −6 Changes for ios/Video/RCTVideo.m: 13 added lines, 6 removed lines. Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ static int const RCTVideoUnset = -1; { AVPlayer *_player; AVPlayerItem *_playerItem; NSDictionary *_source; BOOL _playerItemObserversSet; BOOL _playerBufferEmpty; AVPlayerLayer *_playerLayer; Loading Loading @@ -70,6 +71,7 @@ static int const RCTVideoUnset = -1; NSString * _fullscreenOrientation; BOOL _fullscreenPlayerPresented; NSString *_filterName; BOOL _filterEnabled; UIViewController * _presentingViewController; #if __has_include(<react-native-video/RCTVideoCache.h>) RCTVideoCache * _videoCache; Loading Loading @@ -328,6 +330,7 @@ static int const RCTVideoUnset = -1; - (void)setSrc:(NSDictionary *)source { _source = source; [self removePlayerLayer]; [self removePlayerTimeObserver]; [self removePlayerItemObservers]; Loading Loading @@ -1279,18 +1282,18 @@ static int const RCTVideoUnset = -1; - (void)setFilter:(NSString *)filterName { _filterName = filterName; AVAsset *asset = _playerItem.asset; if (!asset) { if (!_filterEnabled) { return; } else if ([[_source objectForKey:@"uri"] rangeOfString:@"m3u8"].location != NSNotFound) { return; // filters don't work for HLS... return } else if (!_playerItem.asset) { return; } else if (!_playerItem.videoComposition && (filterName == nil || [filterName isEqualToString:@""])) { return; // Setting up an empty filter has a cost so avoid whenever possible } // TODO: filters don't work for HLS, check & return CIFilter *filter = [CIFilter filterWithName:filterName]; _playerItem.videoComposition = [AVVideoComposition videoCompositionWithAsset:asset videoCompositionWithAsset:_playerItem.asset applyingCIFiltersWithHandler:^(AVAsynchronousCIImageFilteringRequest *_Nonnull request) { if (filter == nil) { [request finishWithImage:request.sourceImage context:nil]; Loading @@ -1303,6 +1306,10 @@ static int const RCTVideoUnset = -1; }]; } - (void)setFilterEnabled:(BOOL)filterEnabled { _filterEnabled = filterEnabled; } #pragma mark - React View Management - (void)insertReactSubview:(UIView *)view atIndex:(NSInteger)atIndex Loading
ios/Video/RCTVideoManager.m +1 −0 Changes for ios/Video/RCTVideoManager.m: 1 added line, 0 removed lines. Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ RCT_EXPORT_VIEW_PROPERTY(fullscreen, BOOL); RCT_EXPORT_VIEW_PROPERTY(fullscreenAutorotate, BOOL); RCT_EXPORT_VIEW_PROPERTY(fullscreenOrientation, NSString); RCT_EXPORT_VIEW_PROPERTY(filter, NSString); RCT_EXPORT_VIEW_PROPERTY(filterEnabled, BOOL); RCT_EXPORT_VIEW_PROPERTY(progressUpdateInterval, float); /* Should support: onLoadStart, onLoad, and onError to stay consistent with Image */ RCT_EXPORT_VIEW_PROPERTY(onVideoLoadStart, RCTBubblingEventBlock); Loading