diff --git a/README.md b/README.md
index 90b615fe..e9e514e9 100644
--- a/README.md
+++ b/README.md
@@ -260,6 +260,7 @@ var styles = StyleSheet.create({
* [bufferConfig](#bufferconfig)
* [controls](#controls)
* [filter](#filter)
+* [filterEnabled](#filterEnabled)
* [fullscreen](#fullscreen)
* [fullscreenAutorotate](#fullscreenautorotate)
* [fullscreenOrientation](#fullscreenorientation)
@@ -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
diff --git a/Video.js b/Video.js
index a43b2e0e..e726f401 100644
--- a/Video.js
+++ b/Video.js
@@ -300,6 +300,7 @@ Video.propTypes = {
FilterType.TRANSFER,
FilterType.SEPIA
]),
+ filterEnabled: PropTypes.bool,
/* Native only */
src: PropTypes.object,
seek: PropTypes.oneOfType([
diff --git a/examples/basic/index.ios.js b/examples/basic/index.ios.js
index 2abd3b9f..1bc0ac47 100644
--- a/examples/basic/index.ios.js
+++ b/examples/basic/index.ios.js
@@ -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) {
@@ -34,6 +53,8 @@ class VideoPlayer extends Component {
skin: 'custom',
ignoreSilentSwitch: null,
isBuffering: false,
+ filter: FilterType.NONE,
+ filterEnabled: true
};
onLoad(data) {
@@ -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';
@@ -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}
/>
@@ -151,6 +188,21 @@ class VideoPlayer extends Component {
{this.renderSkinControl('native')}
{this.renderSkinControl('embed')}
+ {
+ (this.state.filterEnabled) ?
+
+ {
+ this.setFilter(-1)
+ }}>
+ Previous Filter
+
+ {
+ this.setFilter(1)
+ }}>
+ Next Filter
+
+ : null
+ }
@@ -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}
/>
@@ -221,6 +275,21 @@ class VideoPlayer extends Component {
{this.renderSkinControl('native')}
{this.renderSkinControl('embed')}
+ {
+ (this.state.filterEnabled) ?
+
+ {
+ this.setFilter(-1)
+ }}>
+ Previous Filter
+
+ {
+ this.setFilter(1)
+ }}>
+ Next Filter
+
+ : null
+ }
diff --git a/ios/Video/RCTVideo.m b/ios/Video/RCTVideo.m
index 90ecf057..9c7e8b79 100644
--- a/ios/Video/RCTVideo.m
+++ b/ios/Video/RCTVideo.m
@@ -26,6 +26,7 @@ static int const RCTVideoUnset = -1;
{
AVPlayer *_player;
AVPlayerItem *_playerItem;
+ NSDictionary *_source;
BOOL _playerItemObserversSet;
BOOL _playerBufferEmpty;
AVPlayerLayer *_playerLayer;
@@ -70,6 +71,7 @@ static int const RCTVideoUnset = -1;
NSString * _fullscreenOrientation;
BOOL _fullscreenPlayerPresented;
NSString *_filterName;
+ BOOL _filterEnabled;
UIViewController * _presentingViewController;
#if __has_include()
RCTVideoCache * _videoCache;
@@ -328,6 +330,7 @@ static int const RCTVideoUnset = -1;
- (void)setSrc:(NSDictionary *)source
{
+ _source = source;
[self removePlayerLayer];
[self removePlayerTimeObserver];
[self removePlayerItemObservers];
@@ -1279,18 +1282,18 @@ static int const RCTVideoUnset = -1;
- (void)setFilter:(NSString *)filterName {
_filterName = filterName;
- AVAsset *asset = _playerItem.asset;
-
- if (!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
+ 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;
+ }
+
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];
@@ -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
diff --git a/ios/Video/RCTVideoManager.m b/ios/Video/RCTVideoManager.m
index b5d94ebc..f7e6666a 100644
--- a/ios/Video/RCTVideoManager.m
+++ b/ios/Video/RCTVideoManager.m
@@ -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);
diff --git a/package.json b/package.json
index cf314b42..0c690a04 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "react-native-video",
- "version": "4.2.0",
+ "version": "4.2.1",
"description": "A element for react-native",
"main": "Video.js",
"license": "MIT",