From e4da5c97734862e6a3585d06088b7aed336166e8 Mon Sep 17 00:00:00 2001 From: benlime Date: Sun, 30 Apr 2017 13:43:01 +0200 Subject: [PATCH 001/148] adds resizeMode to poster image --- Video.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Video.js b/Video.js index 4d69b333..ed55b7fc 100644 --- a/Video.js +++ b/Video.js @@ -217,7 +217,6 @@ export default class Video extends Component { top: 0, right: 0, bottom: 0, - resizeMode: 'contain', }; return ( @@ -229,6 +228,7 @@ export default class Video extends Component { ); @@ -271,6 +271,7 @@ Video.propTypes = { ]), resizeMode: PropTypes.string, poster: PropTypes.string, + posterResizeMode: Image.propTypes.resizeMode, repeat: PropTypes.bool, paused: PropTypes.bool, muted: PropTypes.bool, From b6afaa3378fed72d6bd356f9a76dce965e350cf7 Mon Sep 17 00:00:00 2001 From: Nicolas Ngomai Date: Thu, 11 May 2017 13:46:04 +0200 Subject: [PATCH 002/148] Add link to propTypes Some props are missing in the documentation, the propTypes provides a full list of those. I think it would help a lot of developers to add a link here. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index e473a766..11819fb2 100644 --- a/README.md +++ b/README.md @@ -170,6 +170,8 @@ var styles = StyleSheet.create({ - * *For iOS you also need to specify muted for this to work* +To see 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. + ## Android Expansion File Usage ```javascript From 451f8d0919e94e44d7b294b187ac527533d06b82 Mon Sep 17 00:00:00 2001 From: Alex Fox Date: Thu, 7 Sep 2017 13:16:44 +0100 Subject: [PATCH 003/148] Fixed rate not being respected after seeking Referenced in issue => https://github.com/react-native-community/react-native-video/issues/763 --- ios/RCTVideo.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ios/RCTVideo.m b/ios/RCTVideo.m index 9962c2bb..097e16c8 100644 --- a/ios/RCTVideo.m +++ b/ios/RCTVideo.m @@ -561,7 +561,9 @@ static NSString *const timedMetadata = @"timedMetadata"; if (CMTimeCompare(current, cmSeekTime) != 0) { if (!wasPaused) [_player pause]; [_player seekToTime:cmSeekTime toleranceBefore:tolerance toleranceAfter:tolerance completionHandler:^(BOOL finished) { - if (!wasPaused) [_player play]; + if (!wasPaused) { + [self setPaused:false]; + } if(self.onVideoSeek) { self.onVideoSeek(@{@"currentTime": [NSNumber numberWithFloat:CMTimeGetSeconds(item.currentTime)], @"seekTime": [NSNumber numberWithFloat:seekTime], From 1bdd8720fbc08b2a04edf2b59e8e03063ed41c48 Mon Sep 17 00:00:00 2001 From: Anne Glines Date: Mon, 11 Sep 2017 22:30:17 -0700 Subject: [PATCH 004/148] Reseting isCompleted flag on source change --- android/src/main/java/com/brentvatne/react/ReactVideoView.java | 1 + 1 file changed, 1 insertion(+) diff --git a/android/src/main/java/com/brentvatne/react/ReactVideoView.java b/android/src/main/java/com/brentvatne/react/ReactVideoView.java index 94a25a0e..f426c30e 100644 --- a/android/src/main/java/com/brentvatne/react/ReactVideoView.java +++ b/android/src/main/java/com/brentvatne/react/ReactVideoView.java @@ -297,6 +297,7 @@ public class ReactVideoView extends ScalableVideoView implements MediaPlayer.OnP WritableMap event = Arguments.createMap(); event.putMap(ReactVideoViewManager.PROP_SRC, src); mEventEmitter.receiveEvent(getId(), Events.EVENT_LOAD_START.toString(), event); + isCompleted = false; try { prepareAsync(this); From 3e0f084c621e7af0a60a13c701cb94cd3b211041 Mon Sep 17 00:00:00 2001 From: Louis Capitanchik Date: Wed, 27 Sep 2017 16:13:29 +0100 Subject: [PATCH 005/148] Implement 'rate' prop for android devices - Version locked to 6.0+ because that is the version that introduced setPlaybackParams - Ignores rate prop as before on android versions lower than 6.0 --- .../main/java/com/brentvatne/react/ReactVideoView.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/android/src/main/java/com/brentvatne/react/ReactVideoView.java b/android/src/main/java/com/brentvatne/react/ReactVideoView.java index 94a25a0e..099bec33 100644 --- a/android/src/main/java/com/brentvatne/react/ReactVideoView.java +++ b/android/src/main/java/com/brentvatne/react/ReactVideoView.java @@ -5,6 +5,7 @@ import android.content.res.AssetFileDescriptor; import android.graphics.Matrix; import android.media.MediaPlayer; import android.net.Uri; +import android.os.Build; import android.os.Handler; import android.util.Log; import android.view.MotionEvent; @@ -377,8 +378,11 @@ public class ReactVideoView extends ScalableVideoView implements MediaPlayer.OnP mRate = rate; if (mMediaPlayerValid) { - // TODO: Implement this. - Log.e(ReactVideoViewManager.REACT_CLASS, "Setting playback rate is not yet supported on Android"); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + mMediaPlayer.setPlaybackParams(mMediaPlayer.getPlaybackParams().setSpeed(rate)); + } else { + Log.e(ReactVideoViewManager.REACT_CLASS, "Setting playback rate is not yet supported on Android versions below 6.0"); + } } } @@ -388,7 +392,7 @@ public class ReactVideoView extends ScalableVideoView implements MediaPlayer.OnP setPausedModifier(mPaused); setMutedModifier(mMuted); setProgressUpdateInterval(mProgressUpdateInterval); -// setRateModifier(mRate); + setRateModifier(mRate); } public void setPlayInBackground(final boolean playInBackground) { From 435669a944430fa51b8bbd640c6bf66c7756a1ce Mon Sep 17 00:00:00 2001 From: Dan Hodos Date: Thu, 28 Sep 2017 21:37:26 -0400 Subject: [PATCH 006/148] Extract method to add observer for progress update --- ios/RCTVideo.m | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/ios/RCTVideo.m b/ios/RCTVideo.m index 9962c2bb..88f3a640 100644 --- a/ios/RCTVideo.m +++ b/ios/RCTVideo.m @@ -124,6 +124,16 @@ static NSString *const timedMetadata = @"timedMetadata"; return (kCMTimeRangeZero); } +-(void)addPlayerTimeObserver +{ + const Float64 progressUpdateIntervalMS = _progressUpdateInterval / 1000; + // @see endScrubbing in AVPlayerDemoPlaybackViewController.m of https://developer.apple.com/library/ios/samplecode/AVPlayerDemo/Introduction/Intro.html + __weak RCTVideo *weakSelf = self; + _timeObserver = [_player addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(progressUpdateIntervalMS, NSEC_PER_SEC) + queue:NULL + usingBlock:^(CMTime time) { [weakSelf sendProgressUpdate]; } + ]; +} /* Cancels the previously registered time observer. */ -(void)removePlayerTimeObserver @@ -283,13 +293,7 @@ static NSString *const timedMetadata = @"timedMetadata"; [_player addObserver:self forKeyPath:playbackRate options:0 context:nil]; _playbackRateObserverRegistered = YES; - const Float64 progressUpdateIntervalMS = _progressUpdateInterval / 1000; - // @see endScrubbing in AVPlayerDemoPlaybackViewController.m of https://developer.apple.com/library/ios/samplecode/AVPlayerDemo/Introduction/Intro.html - __weak RCTVideo *weakSelf = self; - _timeObserver = [_player addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(progressUpdateIntervalMS, NSEC_PER_SEC) - queue:NULL - usingBlock:^(CMTime time) { [weakSelf sendProgressUpdate]; } - ]; + [self addPlayerTimeObserver]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ //Perform on next run loop, otherwise onVideoLoadStart is nil From 10cba5ad5c545a1ea6a6e7d53020f834466aa72e Mon Sep 17 00:00:00 2001 From: Dan Hodos Date: Thu, 28 Sep 2017 21:37:52 -0400 Subject: [PATCH 007/148] Reset progress observer on update interval changes --- ios/RCTVideo.m | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ios/RCTVideo.m b/ios/RCTVideo.m index 88f3a640..68e52e31 100644 --- a/ios/RCTVideo.m +++ b/ios/RCTVideo.m @@ -725,6 +725,11 @@ static NSString *const timedMetadata = @"timedMetadata"; - (void)setProgressUpdateInterval:(float)progressUpdateInterval { _progressUpdateInterval = progressUpdateInterval; + + if (_timeObserver) { + [self removePlayerTimeObserver]; + [self addPlayerTimeObserver]; + } } - (void)removePlayerLayer From 2ae99bd484486f468932db7830b7db8b69ccc507 Mon Sep 17 00:00:00 2001 From: Jan Lievens Date: Tue, 24 Oct 2017 09:47:43 +0200 Subject: [PATCH 008/148] remove observers before adding thus preventing multiple observers for the same notification --- ios/RCTVideo.m | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ios/RCTVideo.m b/ios/RCTVideo.m index 9962c2bb..ab0927c6 100644 --- a/ios/RCTVideo.m +++ b/ios/RCTVideo.m @@ -454,10 +454,17 @@ static NSString *const timedMetadata = @"timedMetadata"; - (void)attachListeners { // listen for end of file + [[NSNotificationCenter defaultCenter] removeObserver:self + name:AVPlayerItemDidPlayToEndTimeNotification + object:[_player currentItem]]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerItemDidReachEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:[_player currentItem]]; + + [[NSNotificationCenter defaultCenter] removeObserver:self + name:AVPlayerItemPlaybackStalledNotification + object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackStalled:) name:AVPlayerItemPlaybackStalledNotification From f7b7f2666a206bc92faa94028b26d65b45a7300c Mon Sep 17 00:00:00 2001 From: Marc-Olivier Duval Date: Tue, 24 Oct 2017 21:49:46 -0400 Subject: [PATCH 009/148] Apply fix in playInBackground props --- .../java/com/brentvatne/exoplayer/ReactExoplayerView.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index 52bf24e6..c12b2a48 100644 --- a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -167,6 +167,9 @@ class ReactExoplayerView extends FrameLayout implements @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); + if (playInBackground) { + return; + } stopPlayback(); } @@ -174,9 +177,6 @@ class ReactExoplayerView extends FrameLayout implements @Override public void onHostResume() { - if (playInBackground) { - return; - } setPlayWhenReady(!isPaused); } From ee5818b6ff4e39b1d5bdc5d59616f0f5f255ad7c Mon Sep 17 00:00:00 2001 From: Marc-Olivier Duval Date: Tue, 24 Oct 2017 22:42:41 -0400 Subject: [PATCH 010/148] Fix bug with playInBackground --- .../java/com/brentvatne/exoplayer/ReactExoplayerView.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index c12b2a48..34df0031 100644 --- a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -167,9 +167,6 @@ class ReactExoplayerView extends FrameLayout implements @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); - if (playInBackground) { - return; - } stopPlayback(); } @@ -209,12 +206,14 @@ class ReactExoplayerView extends FrameLayout implements player.setMetadataOutput(this); exoPlayerView.setPlayer(player); audioBecomingNoisyReceiver.setListener(this); - setPlayWhenReady(!isPaused); playerNeedsSource = true; PlaybackParameters params = new PlaybackParameters(rate, 1f); player.setPlaybackParameters(params); } + + setPlayWhenReady(!isPaused); + if (playerNeedsSource && srcUri != null) { MediaSource mediaSource = buildMediaSource(srcUri, extension); mediaSource = repeat ? new LoopingMediaSource(mediaSource) : mediaSource; From 0fe621a26db4f9e091649b0304a5715d4d8b2947 Mon Sep 17 00:00:00 2001 From: Marc-Olivier Duval Date: Tue, 24 Oct 2017 22:42:51 -0400 Subject: [PATCH 011/148] Updated exoplayer readme --- android-exoplayer/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/android-exoplayer/README.md b/android-exoplayer/README.md index e2d4f9fa..9396763b 100644 --- a/android-exoplayer/README.md +++ b/android-exoplayer/README.md @@ -42,6 +42,5 @@ https://github.com/google/ExoPlayer ## Unimplemented props -- `playInBackground={true}` -- `rate={1.0}` - Expansion file - `source={{ mainVer: 1, patchVer: 0 }}` + From 3e293407e8b15cb97b9ed475a0d65e40b079c466 Mon Sep 17 00:00:00 2001 From: Marc-Olivier Duval Date: Tue, 24 Oct 2017 22:50:20 -0400 Subject: [PATCH 012/148] updated readme to with a guid to setup exoplayer --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 597b71ec..89e46a2f 100644 --- a/README.md +++ b/README.md @@ -269,6 +269,16 @@ Toggles a fullscreen player. Access using a ref to the component. - [Lumpen Radio](https://github.com/jhabdas/lumpen-radio) contains another example integration using local files and full screen background video. +## Use ExoPlayer on Android + +To use ExoPlayer instead of the default player, you have to change android to android-exoplayer in settings.gradle + +**android/settings.gradle** + +```gradle +project(':react-native-video').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-video/android-exoplayer') +``` + ## TODOS - [ ] Add support for captions From 1ba6b062e4ac7a415e4d3602f15965f7bf93c779 Mon Sep 17 00:00:00 2001 From: thomasobrien99 Date: Fri, 3 Nov 2017 11:38:37 -0700 Subject: [PATCH 013/148] View.propTypes -> ViewPropTypes (#824) --- Video.js | 4 ++-- ViewPropTypes | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 ViewPropTypes diff --git a/Video.js b/Video.js index b90c030e..feb79861 100644 --- a/Video.js +++ b/Video.js @@ -1,6 +1,6 @@ import React, {Component} from 'react'; import PropTypes from 'prop-types'; -import {StyleSheet, requireNativeComponent, NativeModules, View, Image} from 'react-native'; +import {StyleSheet, requireNativeComponent, NativeModules, View, ViewPropTypes, Image} from 'react-native'; import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource'; import VideoResizeMode from './VideoResizeMode.js'; @@ -308,7 +308,7 @@ Video.propTypes = { translateX: PropTypes.number, translateY: PropTypes.number, rotation: PropTypes.number, - ...View.propTypes, + ...ViewPropTypes, }; const RCTVideo = requireNativeComponent('RCTVideo', Video, { diff --git a/ViewPropTypes b/ViewPropTypes new file mode 100644 index 00000000..0641bc0d --- /dev/null +++ b/ViewPropTypes @@ -0,0 +1 @@ +M Video.js From 6e43701092f5f480eab8ae005a4bc729bb21b5c1 Mon Sep 17 00:00:00 2001 From: Ahmed Hassan Date: Sat, 18 Nov 2017 23:10:58 +0100 Subject: [PATCH 014/148] added native progress notification (#734) --- ios/RCTVideo.m | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ios/RCTVideo.m b/ios/RCTVideo.m index 9962c2bb..58eaf608 100644 --- a/ios/RCTVideo.m +++ b/ios/RCTVideo.m @@ -188,6 +188,9 @@ static NSString *const timedMetadata = @"timedMetadata"; CMTime currentTime = _player.currentTime; const Float64 duration = CMTimeGetSeconds(playerDuration); const Float64 currentTimeSecs = CMTimeGetSeconds(currentTime); + + [[NSNotificationCenter defaultCenter] postNotificationName:@"RCTVideo_progress" object:nil userInfo:@{@"progress": [NSNumber numberWithDouble: currentTimeSecs / duration]}]; + if( currentTimeSecs >= 0 && self.onVideoProgress) { self.onVideoProgress(@{ @"currentTime": [NSNumber numberWithFloat:CMTimeGetSeconds(currentTime)], From c0a8f7c0c9ebf1a82a6f37381de9d96754c931c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kay=20Pl=C3=B6=C3=9Fer?= Date: Fri, 24 Nov 2017 16:22:41 +0100 Subject: [PATCH 015/148] Document fullscreen callbacks fix #861 --- README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 597b71ec..01470edf 100644 --- a/README.md +++ b/README.md @@ -165,12 +165,16 @@ using System.Collections.Generic; playWhenInactive={false} // [iOS] Video continues to play when control or notification center are shown. ignoreSilentSwitch={"ignore"} // [iOS] ignore | obey - When 'ignore', audio will still play with the iOS hard silent switch set to silent. When 'obey', audio will toggle with the switch. When not specified, will inherit audio settings as usual. progressUpdateInterval={250.0} // [iOS] Interval to fire onProgress (default to ~250ms) + onBuffer={this.onBuffer} // Callback when remote video is buffering + onEnd={this.onEnd} // Callback when playback finishes + onError={this.videoError} // Callback when video cannot be loaded + onFullscreenPlayerWillPresent={this.fullScreenPlayerWillPresent} // Callback before fullscreen starts + onFullscreenPlayerDidPresent={this.fullScreenPlayerDidPresent} // Callback after fullscreen started + onFullscreenPlayerWillDismiss={this.fullScreenPlayerWillDismiss} // Callback before fullscreen stops + onFullscreenPlayerDidDismiss={this.fullScreenPlayerDidDissmiss} // Callback after fullscreen stopped onLoadStart={this.loadStart} // Callback when video starts to load onLoad={this.setDuration} // Callback when video loads onProgress={this.setTime} // Callback every ~250ms with currentTime - onEnd={this.onEnd} // Callback when playback finishes - onError={this.videoError} // Callback when video cannot be loaded - onBuffer={this.onBuffer} // Callback when remote video is buffering onTimedMetadata={this.onTimedMetadata} // Callback when the stream receive some metadata style={styles.backgroundVideo} /> From ebe138fa8dad21a4fd786b41a1e541d44c511c9b Mon Sep 17 00:00:00 2001 From: vengadesh Date: Wed, 6 Dec 2017 08:56:41 -0800 Subject: [PATCH 016/148] Raising error for source exception (#799) --- .../java/com/brentvatne/exoplayer/ReactExoplayerView.java | 7 ++++++- android-exoplayer/src/main/res/values/strings.xml | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index 52bf24e6..f24d94c2 100644 --- a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -482,6 +482,7 @@ class ReactExoplayerView extends FrameLayout implements @Override public void onPlayerError(ExoPlaybackException e) { String errorString = null; + Exception ex = e; if (e.type == ExoPlaybackException.TYPE_RENDERER) { Exception cause = e.getRendererException(); if (cause instanceof MediaCodecRenderer.DecoderInitializationException) { @@ -504,8 +505,12 @@ class ReactExoplayerView extends FrameLayout implements } } } + else if (e.type == ExoPlaybackException.TYPE_SOURCE) { + ex = e.getSourceException(); + errorString = getResources().getString(R.string.unrecognized_media_format); + } if (errorString != null) { - eventEmitter.error(errorString, e); + eventEmitter.error(errorString, ex); } playerNeedsSource = true; if (isBehindLiveWindow(e)) { diff --git a/android-exoplayer/src/main/res/values/strings.xml b/android-exoplayer/src/main/res/values/strings.xml index b92a238a..4f69ec34 100644 --- a/android-exoplayer/src/main/res/values/strings.xml +++ b/android-exoplayer/src/main/res/values/strings.xml @@ -9,4 +9,6 @@ Unable to instantiate decoder %1$s + Unrecognized media format + From ce7c732453476cf77b8583981601f521cbb83410 Mon Sep 17 00:00:00 2001 From: Jordan Becker Date: Thu, 7 Dec 2017 19:35:32 +0100 Subject: [PATCH 017/148] Add requiresMainQueueSetup method Since RN 0.49, `requiresMainQueueSetup` needs to be defined if the module overrides `constantsToExport`. --- ios/RCTVideoManager.m | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ios/RCTVideoManager.m b/ios/RCTVideoManager.m index a5cf85e0..c1edb9b7 100644 --- a/ios/RCTVideoManager.m +++ b/ios/RCTVideoManager.m @@ -62,4 +62,9 @@ RCT_EXPORT_VIEW_PROPERTY(onPlaybackRateChange, RCTBubblingEventBlock); }; } ++ (BOOL)requiresMainQueueSetup +{ + return YES; +} + @end From 64191298e514ab52b9cb4fcabcb7e38b40a698fe Mon Sep 17 00:00:00 2001 From: sm2017 Date: Sun, 24 Dec 2017 14:44:00 +0330 Subject: [PATCH 018/148] Update ReactVideoView.cs Fix 'Event' does not contain a constructor that takes 2 arguments ReactNativeVideo --- windows/ReactNativeVideo.Net46/ReactVideoView.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/windows/ReactNativeVideo.Net46/ReactVideoView.cs b/windows/ReactNativeVideo.Net46/ReactVideoView.cs index 8a8b1b29..643965ee 100644 --- a/windows/ReactNativeVideo.Net46/ReactVideoView.cs +++ b/windows/ReactNativeVideo.Net46/ReactVideoView.cs @@ -328,7 +328,7 @@ namespace ReactNativeVideo private readonly JObject _eventData; public ReactVideoEvent(string eventName, int viewTag, JObject eventData) - : base(viewTag, TimeSpan.FromTicks(Environment.TickCount)) + : base(viewTag) { _eventName = eventName; _eventData = eventData; From dd242476a3615055343c0c06a119713f9df6fb0e Mon Sep 17 00:00:00 2001 From: sm2017 Date: Sun, 24 Dec 2017 14:46:02 +0330 Subject: [PATCH 019/148] Update ReactVideoView.cs Fix 'Event' does not contain a constructor that takes 2 arguments ReactNativeVideo --- windows/ReactNativeVideo/ReactVideoView.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/windows/ReactNativeVideo/ReactVideoView.cs b/windows/ReactNativeVideo/ReactVideoView.cs index 22063aff..5a6c103f 100644 --- a/windows/ReactNativeVideo/ReactVideoView.cs +++ b/windows/ReactNativeVideo/ReactVideoView.cs @@ -334,7 +334,7 @@ namespace ReactNativeVideo private readonly JObject _eventData; public ReactVideoEvent(string eventName, int viewTag, JObject eventData) - : base(viewTag, TimeSpan.FromTicks(Environment.TickCount)) + : base(viewTag) { _eventName = eventName; _eventData = eventData; From 093ffccd9b99f5b1de10832f01cda895bcb64a3a Mon Sep 17 00:00:00 2001 From: Austin Witherow Date: Tue, 2 Jan 2018 12:06:43 -0500 Subject: [PATCH 020/148] fix(ios): crash due to persistent keyPath observer (#600) --- ios/RCTVideo.m | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ios/RCTVideo.m b/ios/RCTVideo.m index 58eaf608..0f1227b1 100644 --- a/ios/RCTVideo.m +++ b/ios/RCTVideo.m @@ -252,6 +252,9 @@ static NSString *const timedMetadata = @"timedMetadata"; * observer set */ - (void)removePlayerItemObservers { + if (_playerLayer) { + [_playerLayer removeObserver:self forKeyPath:readyForDisplayKeyPath]; + } if (_playerItemObserversSet) { [_playerItem removeObserver:self forKeyPath:statusKeyPath]; [_playerItem removeObserver:self forKeyPath:playbackBufferEmptyKeyPath]; From 7d48f22d9871bf98f4a1208e53d218954135f6fa Mon Sep 17 00:00:00 2001 From: Alejandro Rangel Date: Thu, 11 Jan 2018 09:16:29 -0800 Subject: [PATCH 021/148] add seekableDuration to android ReactVideoView --- android/src/main/java/com/brentvatne/react/ReactVideoView.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/android/src/main/java/com/brentvatne/react/ReactVideoView.java b/android/src/main/java/com/brentvatne/react/ReactVideoView.java index 94a25a0e..f609bcc4 100644 --- a/android/src/main/java/com/brentvatne/react/ReactVideoView.java +++ b/android/src/main/java/com/brentvatne/react/ReactVideoView.java @@ -64,6 +64,7 @@ public class ReactVideoView extends ScalableVideoView implements MediaPlayer.OnP public static final String EVENT_PROP_DURATION = "duration"; public static final String EVENT_PROP_PLAYABLE_DURATION = "playableDuration"; + public static final String EVENT_PROP_SEEKABLE_DURATION = "seekableDuration"; public static final String EVENT_PROP_CURRENT_TIME = "currentTime"; public static final String EVENT_PROP_SEEK_TIME = "seekTime"; public static final String EVENT_PROP_NATURALSIZE = "naturalSize"; @@ -127,6 +128,7 @@ public class ReactVideoView extends ScalableVideoView implements MediaPlayer.OnP WritableMap event = Arguments.createMap(); event.putDouble(EVENT_PROP_CURRENT_TIME, mMediaPlayer.getCurrentPosition() / 1000.0); event.putDouble(EVENT_PROP_PLAYABLE_DURATION, mVideoBufferedDuration / 1000.0); //TODO:mBufferUpdateRunnable + event.putDouble(EVENT_PROP_SEEKABLE_DURATION, mVideoDuration / 1000.0); mEventEmitter.receiveEvent(getId(), Events.EVENT_PROGRESS.toString(), event); // Check for update after an interval From 5d274631c8d742a5faa49532bf0a967da760be2c Mon Sep 17 00:00:00 2001 From: Brandon Moon Date: Mon, 29 Jan 2018 13:25:58 -0700 Subject: [PATCH 022/148] Link up cookies so exoplayer can use them --- .../brentvatne/exoplayer/DataSourceUtil.java | 31 +++++++++++++------ .../exoplayer/ReactExoplayerView.java | 16 +++------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/DataSourceUtil.java b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/DataSourceUtil.java index 0077c3b0..c486bf0b 100644 --- a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/DataSourceUtil.java +++ b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/DataSourceUtil.java @@ -1,7 +1,11 @@ package com.brentvatne.exoplayer; import android.content.Context; +import android.content.ContextWrapper; +import com.facebook.react.bridge.ReactContext; +import com.facebook.react.modules.network.CookieJarContainer; +import com.facebook.react.modules.network.ForwardingCookieHandler; import com.facebook.react.modules.network.OkHttpClientProvider; import com.google.android.exoplayer2.ext.okhttp.OkHttpDataSourceFactory; import com.google.android.exoplayer2.upstream.DataSource; @@ -10,6 +14,10 @@ import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; import com.google.android.exoplayer2.upstream.HttpDataSource; import com.google.android.exoplayer2.util.Util; +import okhttp3.Cookie; +import okhttp3.JavaNetCookieJar; +import okhttp3.OkHttpClient; + public class DataSourceUtil { private DataSourceUtil() { @@ -23,14 +31,14 @@ public class DataSourceUtil { DataSourceUtil.userAgent = userAgent; } - public static String getUserAgent(Context context) { + public static String getUserAgent(ReactContext context) { if (userAgent == null) { - userAgent = Util.getUserAgent(context.getApplicationContext(), "ReactNativeVideo"); + userAgent = Util.getUserAgent(context, "ReactNativeVideo"); } return userAgent; } - public static DataSource.Factory getRawDataSourceFactory(Context context) { + public static DataSource.Factory getRawDataSourceFactory(ReactContext context) { if (rawDataSourceFactory == null) { rawDataSourceFactory = buildRawDataSourceFactory(context); } @@ -41,7 +49,7 @@ public class DataSourceUtil { DataSourceUtil.rawDataSourceFactory = factory; } - public static DataSource.Factory getDefaultDataSourceFactory(Context context, DefaultBandwidthMeter bandwidthMeter) { + public static DataSource.Factory getDefaultDataSourceFactory(ReactContext context, DefaultBandwidthMeter bandwidthMeter) { if (defaultDataSourceFactory == null) { defaultDataSourceFactory = buildDataSourceFactory(context, bandwidthMeter); } @@ -52,17 +60,20 @@ public class DataSourceUtil { DataSourceUtil.defaultDataSourceFactory = factory; } - private static DataSource.Factory buildRawDataSourceFactory(Context context) { + private static DataSource.Factory buildRawDataSourceFactory(ReactContext context) { return new RawResourceDataSourceFactory(context.getApplicationContext()); } - private static DataSource.Factory buildDataSourceFactory(Context context, DefaultBandwidthMeter bandwidthMeter) { - Context appContext = context.getApplicationContext(); - return new DefaultDataSourceFactory(appContext, bandwidthMeter, - buildHttpDataSourceFactory(appContext, bandwidthMeter)); + private static DataSource.Factory buildDataSourceFactory(ReactContext context, DefaultBandwidthMeter bandwidthMeter) { + return new DefaultDataSourceFactory(context, bandwidthMeter, + buildHttpDataSourceFactory(context, bandwidthMeter)); } - private static HttpDataSource.Factory buildHttpDataSourceFactory(Context context, DefaultBandwidthMeter bandwidthMeter) { + private static HttpDataSource.Factory buildHttpDataSourceFactory(ReactContext context, DefaultBandwidthMeter bandwidthMeter) { + OkHttpClient client = OkHttpClientProvider.getOkHttpClient(); + CookieJarContainer container = (CookieJarContainer) client.cookieJar(); + ForwardingCookieHandler handler = new ForwardingCookieHandler(context); + container.setCookieJar(new JavaNetCookieJar(handler)); return new OkHttpDataSourceFactory(OkHttpClientProvider.getOkHttpClient(), getUserAgent(context), bandwidthMeter); } diff --git a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index f24d94c2..074531af 100644 --- a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -124,14 +124,13 @@ class ReactExoplayerView extends FrameLayout implements public ReactExoplayerView(ThemedReactContext context) { super(context); + this.themedReactContext = context; createViews(); this.eventEmitter = new VideoEventEmitter(context); - this.themedReactContext = context; audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); themedReactContext.addLifecycleEventListener(this); audioBecomingNoisyReceiver = new AudioBecomingNoisyReceiver(themedReactContext); - initializePlayer(); } @@ -353,7 +352,7 @@ class ReactExoplayerView extends FrameLayout implements * @return A new DataSource factory. */ private DataSource.Factory buildDataSourceFactory(boolean useBandwidthMeter) { - return DataSourceUtil.getDefaultDataSourceFactory(getContext(), useBandwidthMeter ? BANDWIDTH_METER : null); + return DataSourceUtil.getDefaultDataSourceFactory(this.themedReactContext, useBandwidthMeter ? BANDWIDTH_METER : null); } // AudioManager.OnAudioFocusChangeListener implementation @@ -482,7 +481,6 @@ class ReactExoplayerView extends FrameLayout implements @Override public void onPlayerError(ExoPlaybackException e) { String errorString = null; - Exception ex = e; if (e.type == ExoPlaybackException.TYPE_RENDERER) { Exception cause = e.getRendererException(); if (cause instanceof MediaCodecRenderer.DecoderInitializationException) { @@ -505,12 +503,8 @@ class ReactExoplayerView extends FrameLayout implements } } } - else if (e.type == ExoPlaybackException.TYPE_SOURCE) { - ex = e.getSourceException(); - errorString = getResources().getString(R.string.unrecognized_media_format); - } if (errorString != null) { - eventEmitter.error(errorString, ex); + eventEmitter.error(errorString, e); } playerNeedsSource = true; if (isBehindLiveWindow(e)) { @@ -549,7 +543,7 @@ class ReactExoplayerView extends FrameLayout implements this.srcUri = uri; this.extension = extension; - this.mediaDataSourceFactory = DataSourceUtil.getDefaultDataSourceFactory(getContext(), BANDWIDTH_METER); + this.mediaDataSourceFactory = DataSourceUtil.getDefaultDataSourceFactory(this.themedReactContext, BANDWIDTH_METER); if (!isOriginalSourceNull && !isSourceEqual) { reloadSource(); @@ -568,7 +562,7 @@ class ReactExoplayerView extends FrameLayout implements this.srcUri = uri; this.extension = extension; - this.mediaDataSourceFactory = DataSourceUtil.getRawDataSourceFactory(getContext()); + this.mediaDataSourceFactory = DataSourceUtil.getRawDataSourceFactory(this.themedReactContext); if (!isOriginalSourceNull && !isSourceEqual) { reloadSource(); From f2e182addc70cb380b56db190b62cca56d3dcac4 Mon Sep 17 00:00:00 2001 From: Brandon Moon Date: Mon, 29 Jan 2018 13:32:31 -0700 Subject: [PATCH 023/148] Bring things up to date with master from copied code --- .../java/com/brentvatne/exoplayer/ReactExoplayerView.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index 074531af..cf8ebc28 100644 --- a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -131,6 +131,7 @@ class ReactExoplayerView extends FrameLayout implements themedReactContext.addLifecycleEventListener(this); audioBecomingNoisyReceiver = new AudioBecomingNoisyReceiver(themedReactContext); + initializePlayer(); } @@ -481,6 +482,7 @@ class ReactExoplayerView extends FrameLayout implements @Override public void onPlayerError(ExoPlaybackException e) { String errorString = null; + Exception ex = e; if (e.type == ExoPlaybackException.TYPE_RENDERER) { Exception cause = e.getRendererException(); if (cause instanceof MediaCodecRenderer.DecoderInitializationException) { @@ -503,8 +505,12 @@ class ReactExoplayerView extends FrameLayout implements } } } + else if (e.type == ExoPlaybackException.TYPE_SOURCE) { + ex = e.getSourceException(); + errorString = getResources().getString(R.string.unrecognized_media_format); + } if (errorString != null) { - eventEmitter.error(errorString, e); + eventEmitter.error(errorString, ex); } playerNeedsSource = true; if (isBehindLiveWindow(e)) { From cf9a5fc63596d6095506b01a988af7067e907205 Mon Sep 17 00:00:00 2001 From: Andy Stanberry Date: Wed, 31 Jan 2018 17:53:37 -0500 Subject: [PATCH 024/148] Document poster prop --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 597b71ec..9a6da0f4 100644 --- a/README.md +++ b/README.md @@ -152,6 +152,7 @@ using System.Collections.Generic; // on a single screen if you like.