Merge branch 'master' of git://github.com/react-native-community/react-native-video into react-native-community-master
Merge branch 'master' of git://github.com/react-native-community/react-native-video into react-native-community-master
20
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
Thanks for opening a PR!
|
||||
Since this is a volunteer project and is very active, anything you can do to reduce the amount of time needed to review and merge your PR is appreciated.
|
||||
The following steps will help get your PR merged quickly:
|
||||
|
||||
#### Update the documentation
|
||||
If you've added new functionality, update the README.md with an entry for your prop or event.
|
||||
The entry should be inserted in alphabetical order.
|
||||
|
||||
#### Update the changelog
|
||||
After you open the PR, update the CHANGELOG.md file with an entry pointing to your PR.
|
||||
|
||||
#### Provide an example of how to test the change
|
||||
If the PR requires special testing setup provide all the relevant instructions and files. This may include a sample video file or URL, configuration, or setup steps.
|
||||
|
||||
#### Focus the PR on only one area
|
||||
Testing multiple features takes longer than isolated changes and if there is a bug in one feature, prevents the other parts of your PR from getting merged until it gets fixed.
|
||||
If you're touching multiple different areas that aren't related, break the changes up into multiple PRs.
|
||||
|
||||
#### Describe the changes
|
||||
Add a note describing what your PR does. If there is a change to the behavior of the code, explain why it needs to be updated.
|
8
.gitignore
vendored
@ -33,7 +33,13 @@ local.properties
|
||||
# node.js
|
||||
#
|
||||
node_modules/
|
||||
npm-debug.log
|
||||
*.log
|
||||
|
||||
# yarn
|
||||
yarn.lock
|
||||
|
||||
# editor workspace settings
|
||||
.vscode
|
||||
|
||||
# BUCK
|
||||
buck-out/
|
||||
|
@ -1 +0,0 @@
|
||||
/example
|
12
CHANGELOG.md
@ -2,7 +2,19 @@
|
||||
|
||||
### Next Version
|
||||
* Partial support for timed metadata on Android MediaPlayer [#707](https://github.com/react-native-community/react-native-video/pull/707)
|
||||
* Support video caching for iOS [#955](https://github.com/react-native-community/react-native-video/pull/955)
|
||||
* Video caching cleanups [#1172](https://github.com/react-native-community/react-native-video/pull/1172)
|
||||
* Add ipod-library support [#926](https://github.com/react-native-community/react-native-video/pull/926/files)
|
||||
* Fix crash on ExoPlayer when there are no audio tracks [#1233](https://github.com/react-native-community/react-native-video/pull/1233)
|
||||
* Reduce package size [#1231](https://github.com/react-native-community/react-native-video/pull/1231)
|
||||
* Remove unnecessary import in TextTrackType [#1229](https://github.com/react-native-community/react-native-video/pull/1229)
|
||||
* Prevent flash between poster and video [#1167](https://github.com/react-native-community/react-native-video/pull/1167)
|
||||
* Support react-native-dom [#1253](https://github.com/react-native-community/react-native-video/pull/1253)
|
||||
* Update to ExoPlayer 2.8.2. Android SDK 26 now required [#1170](https://github.com/react-native-community/react-native-video/pull/1170)
|
||||
* Update to ExoPlayer 2.8.4 [#1266](https://github.com/react-native-community/react-native-video/pull/1266)
|
||||
* Add fullscreenOrientation option for iOS [#1215](https://github.com/react-native-community/react-native-video/pull/1215)
|
||||
* Update to ExoPlayer 2.9.0 [#1285](https://github.com/react-native-community/react-native-video/pull/1285)
|
||||
* Switch useTextureView to default to `true` [#1286](https://github.com/react-native-community/react-native-video/pull/1286)
|
||||
|
||||
### Version 3.2.0
|
||||
* Basic fullscreen support for Android MediaPlayer [#1138](https://github.com/react-native-community/react-native-video/pull/1138)
|
||||
|
289
README.md
@ -3,18 +3,27 @@
|
||||
A `<Video>` component for react-native, as seen in
|
||||
[react-native-login](https://github.com/brentvatne/react-native-login)!
|
||||
|
||||
Requires react-native >= 0.40.0
|
||||
Version 4.x requires react-native >= 0.57.0
|
||||
|
||||
Version 3.x requires react-native >= 0.40.0
|
||||
|
||||
### Version 4.0.0 breaking changes
|
||||
Version 4.0.0 now requires Android SDK 26 or higher to use ExoPlayer. This is the default version as of React Native 0.56 and will be required by Google for all apps in October 2018.
|
||||
Version 4.0.0 changes some behaviors and may require updates to your Gradle files. See [Updating](#updating) for details.
|
||||
|
||||
Version 4.0.0 now requires Android SDK 26+ and Gradle 3 plugin in order to support ExoPlayer 2.9.0. Google is dropping support for apps using SDKs older than 26 as of October 2018 and Gradle 2 as of January 2019. React Native 0.57 defaults to Gradle 3 & SDK 27.
|
||||
|
||||
If you need to support an older React Native version, you should use react-native-video 3.2.1.
|
||||
|
||||
### Version 3.0.0 breaking changes
|
||||
Version 3.0 features a number of changes to existing behavior. See [Updating](#updating) for changes.
|
||||
|
||||
## TOC
|
||||
## Table of Contents
|
||||
|
||||
* [Installation](#installation)
|
||||
* [Usage](#usage)
|
||||
* [iOS App Transport Security](#ios-app-transport-security)
|
||||
* [Audio Mixing](#audio-mixing)
|
||||
* [Android Expansion File Usage](#android-expansion-file-usage)
|
||||
* [Updating](#updating)
|
||||
|
||||
## Installation
|
||||
@ -31,26 +40,37 @@ or using yarn:
|
||||
yarn add react-native-video
|
||||
```
|
||||
|
||||
Then follow the instructions for your platform to link react-native-video into your project:
|
||||
|
||||
<details>
|
||||
<summary>iOS</summary>
|
||||
|
||||
### Standard Method
|
||||
|
||||
Run `react-native link react-native-video` to link the react-native-video library.
|
||||
|
||||
If you would like to allow other apps to play music over your video component, add:
|
||||
### Using CocoaPods (required to enable caching)
|
||||
|
||||
**AppDelegate.m**
|
||||
Setup your Podfile like it is described in the [react-native documentation](https://facebook.github.io/react-native/docs/integration-with-existing-apps#configuring-cocoapods-dependencies).
|
||||
|
||||
```objective-c
|
||||
#import <AVFoundation/AVFoundation.h> // import
|
||||
Depending on your requirements you have to choose between the two possible subpodspecs:
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
...
|
||||
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil]; // allow
|
||||
...
|
||||
}
|
||||
Video only:
|
||||
|
||||
```diff
|
||||
pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
|
||||
+ `pod 'react-native-video', :path => '../node_modules/react-native-video/react-native-video.podspec'`
|
||||
end
|
||||
```
|
||||
Note: you can also use the `ignoreSilentSwitch` prop, shown below.
|
||||
|
||||
Video with caching ([more info](docs/caching.md)):
|
||||
|
||||
```diff
|
||||
pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
|
||||
+ `pod 'react-native-video/VideoCaching', :path => '../node_modules/react-native-video/react-native-video.podspec'`
|
||||
end
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
@ -178,6 +198,31 @@ using System.Collections.Generic;
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>react-native-dom</summary>
|
||||
|
||||
Make the following additions to the given files manually:
|
||||
|
||||
**dom/bootstrap.js**
|
||||
|
||||
Import RCTVideoManager and add it to the list of nativeModules:
|
||||
|
||||
```javascript
|
||||
import { RNDomInstance } from "react-native-dom";
|
||||
import { name as appName } from "../app.json";
|
||||
import RCTVideoManager from 'react-native-video/dom/RCTVideoManager'; // Add this
|
||||
|
||||
// Path to RN Bundle Entrypoint ================================================
|
||||
const rnBundlePath = "./entry.bundle?platform=dom&dev=true";
|
||||
|
||||
// React Native DOM Runtime Options =============================================
|
||||
const ReactNativeDomOptions = {
|
||||
enableHotReload: false,
|
||||
nativeModules: [RCTVideoManager] // Add this
|
||||
};
|
||||
```
|
||||
</details>
|
||||
|
||||
## Usage
|
||||
|
||||
```javascript
|
||||
@ -194,7 +239,6 @@ import Video from 'react-native-video';
|
||||
this.player = ref
|
||||
}} // Store reference
|
||||
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
|
||||
style={styles.backgroundVideo} />
|
||||
|
||||
@ -214,6 +258,11 @@ var styles = StyleSheet.create({
|
||||
* [allowsExternalPlayback](#allowsexternalplayback)
|
||||
* [audioOnly](#audioonly)
|
||||
* [bufferConfig](#bufferconfig)
|
||||
* [controls](#controls)
|
||||
* [fullscreen](#fullscreen)
|
||||
* [fullscreenOrientation](#fullscreenorientation)
|
||||
* [headers](#headers)
|
||||
* [id](#id)
|
||||
* [ignoreSilentSwitch](#ignoresilentswitch)
|
||||
* [muted](#muted)
|
||||
* [paused](#paused)
|
||||
@ -227,6 +276,7 @@ var styles = StyleSheet.create({
|
||||
* [resizeMode](#resizemode)
|
||||
* [selectedAudioTrack](#selectedaudiotrack)
|
||||
* [selectedTextTrack](#selectedtexttrack)
|
||||
* [source](#source)
|
||||
* [stereoPan](#stereopan)
|
||||
* [textTracks](#texttracks)
|
||||
* [useTextureView](#usetextureview)
|
||||
@ -234,6 +284,8 @@ var styles = StyleSheet.create({
|
||||
|
||||
### Event props
|
||||
* [onAudioBecomingNoisy](#onaudiobecomingnoisy)
|
||||
* [onEnd](#onend)
|
||||
* [onExternalPlaybackChange](#onexternalplaybackchange)
|
||||
* [onFullscreenPlayerWillPresent](#onfullscreenplayerwillpresent)
|
||||
* [onFullscreenPlayerDidPresent](#onfullscreenplayerdidpresent)
|
||||
* [onFullscreenPlayerWillDismiss](#onfullscreenplayerwilldismiss)
|
||||
@ -290,6 +342,55 @@ bufferConfig={{
|
||||
|
||||
Platforms: Android ExoPlayer
|
||||
|
||||
#### controls
|
||||
Determines whether to show player controls.
|
||||
* ** false (default)** - Don't show player controls
|
||||
* **true** - Show player controls
|
||||
|
||||
Note on iOS, controls are always shown when in fullscreen mode.
|
||||
|
||||
Platforms: iOS, react-native-dom
|
||||
|
||||
#### fullscreen
|
||||
Controls whether the player enters fullscreen on play.
|
||||
* **false (default)** - Don't display the video in fullscreen
|
||||
* **true** - Display the video in fullscreen
|
||||
|
||||
Platforms: iOS
|
||||
|
||||
#### fullscreenOrientation
|
||||
|
||||
* **all (default)** -
|
||||
* **landscape**
|
||||
* **portrait**
|
||||
|
||||
Platforms: iOS
|
||||
|
||||
#### headers
|
||||
Pass headers to the HTTP client. Can be used for authorization.
|
||||
|
||||
To enable this on iOS, you will need to manually edit RCTVideo.m and uncomment the header code in the playerItemForSource function. This is because the code used a private API and may cause your app to be rejected by the App Store. Use at your own risk.
|
||||
|
||||
Example:
|
||||
```
|
||||
headers={{
|
||||
Authorization: 'bearer some-token-value',
|
||||
'X-Custom-Header': 'some value'
|
||||
}}
|
||||
```
|
||||
|
||||
Platforms: Android ExoPlayer
|
||||
|
||||
#### id
|
||||
Set the DOM id element so you can use document.getElementById on web platforms. Accepts string values.
|
||||
|
||||
Example:
|
||||
```
|
||||
id="video"
|
||||
```
|
||||
|
||||
Platforms: react-native-dom
|
||||
|
||||
#### ignoreSilentSwitch
|
||||
Controls the iOS silent switch behavior
|
||||
* **"inherit" (default)** - Use the default AVPlayer behavior
|
||||
@ -442,6 +543,63 @@ If a track matching the specified Type (and Value if appropriate) is unavailable
|
||||
|
||||
Platforms: Android ExoPlayer, iOS
|
||||
|
||||
#### source
|
||||
Sets the media source. You can pass an asset loaded via require or an object with a uri.
|
||||
|
||||
The docs for this prop are incomplete and will be updated as each option is investigated and tested.
|
||||
|
||||
##### Asset loaded via require
|
||||
|
||||
Example:
|
||||
```
|
||||
const sintel = require('./sintel.mp4');
|
||||
|
||||
source={sintel}
|
||||
```
|
||||
|
||||
##### URI string
|
||||
|
||||
A number of URI schemes are supported by passing an object with a `uri` attribute.
|
||||
|
||||
###### Web address (http://, https://)
|
||||
|
||||
Example:
|
||||
```
|
||||
source={ uri: 'https://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_10mb.mp4' }
|
||||
```
|
||||
|
||||
Platforms: all
|
||||
|
||||
###### File path (file://)
|
||||
|
||||
Example:
|
||||
```
|
||||
source={ uri: 'file:///sdcard/Movies/sintel.mp4' }
|
||||
```
|
||||
|
||||
Note: Your app will need to request permission to read external storage if you're accessing a file outside your app.
|
||||
|
||||
Platforms: Android ExoPlayer, Android MediaPlayer, possibly others
|
||||
|
||||
###### iPod Library (ipod-library://)
|
||||
|
||||
Path to a sound file in your iTunes library. Typically shared from iTunes to your app.
|
||||
|
||||
Example:
|
||||
```
|
||||
source={ uri: 'ipod-library:///path/to/music.mp3' }
|
||||
```
|
||||
|
||||
Note: Using this feature adding an entry for NSAppleMusicUsageDescription to your Info.plist file as described [here](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html)
|
||||
|
||||
Platforms: iOS
|
||||
|
||||
###### Other protocols
|
||||
|
||||
The following other types are supported on some platforms, but aren't fully documented yet:
|
||||
`content://, ms-appx://, ms-appdata://, assets-library://`
|
||||
|
||||
|
||||
#### stereoPan
|
||||
Adjust the balance of the left and right audio channels. Any value between –1.0 and 1.0 is accepted.
|
||||
* **-1.0** - Full left
|
||||
@ -486,14 +644,16 @@ textTracks={[
|
||||
Platforms: Android ExoPlayer, iOS
|
||||
|
||||
#### useTextureView
|
||||
Output to a TextureView instead of the default SurfaceView. In general, you will want to use SurfaceView because it is more efficient and provides better performance. However, SurfaceViews has two limitations:
|
||||
Controls whether to output to a TextureView or SurfaceView.
|
||||
|
||||
SurfaceView is more efficient and provides better performance but has two limitations:
|
||||
* It can't be animated, transformed or scaled
|
||||
* You can't overlay multiple SurfaceViews
|
||||
|
||||
useTextureView can only be set at same time you're setting the source.
|
||||
|
||||
* **false (default)** - Use a SurfaceView
|
||||
* **true** - Use a TextureView
|
||||
* **true (default)** - Use a TextureView
|
||||
* **false** - Use a SurfaceView
|
||||
|
||||
Platforms: Android ExoPlayer
|
||||
|
||||
@ -514,6 +674,31 @@ Payload: none
|
||||
|
||||
Platforms: Android ExoPlayer, iOS
|
||||
|
||||
#### onEnd
|
||||
Callback function that is called when the player reaches the end of the media.
|
||||
|
||||
Payload: none
|
||||
|
||||
Platforms: all
|
||||
|
||||
#### onExternalPlaybackChange
|
||||
Callback function that is called when external playback mode for current playing video has changed. Mostly useful when connecting/disconnecting to Apple TV – it's called on connection/disconnection.
|
||||
|
||||
Payload:
|
||||
|
||||
Property | Type | Description
|
||||
--- | --- | ---
|
||||
isExternalPlaybackActive | boolean | Boolean indicating whether external playback mode is active
|
||||
|
||||
Example:
|
||||
```
|
||||
{
|
||||
isExternalPlaybackActive: true
|
||||
}
|
||||
```
|
||||
|
||||
Platforms: iOS
|
||||
|
||||
#### onFullscreenPlayerWillPresent
|
||||
Callback function that is called when the player is about to enter fullscreen mode.
|
||||
|
||||
@ -608,10 +793,10 @@ Example:
|
||||
Platforms: all
|
||||
|
||||
#### onProgress
|
||||
Callback function that is called every progressInterval seconds with info about which position the media is currently playing.
|
||||
Callback function that is called every progressUpdateInterval seconds with info about which position the media is currently playing.
|
||||
|
||||
Property | Description
|
||||
--- | ---
|
||||
Property | Type | Description
|
||||
--- | --- | ---
|
||||
currentTime | number | Current position in seconds
|
||||
playableDuration | number | Position to where the media can be played to using just the buffer in seconds
|
||||
seekableDuration | number | Position to where the media can be seeked to in seconds. Typically, the total length of the media
|
||||
@ -625,6 +810,8 @@ Example:
|
||||
}
|
||||
```
|
||||
|
||||
Platforms: all
|
||||
|
||||
#### onTimedMetadata
|
||||
Callback function that is called when timed metadata becomes available
|
||||
|
||||
@ -670,7 +857,7 @@ this.player.dismissFullscreenPlayer();
|
||||
|
||||
Platforms: Android ExoPlayer, Android MediaPlayer, iOS
|
||||
|
||||
#### FullscreenPlayer
|
||||
#### presentFullscreenPlayer
|
||||
`presentFullscreenPlayer()`
|
||||
|
||||
Put the player in fullscreen mode.
|
||||
@ -716,17 +903,37 @@ this.player.seek(120, 50); // Seek to 2 minutes with +/- 50 milliseconds accurac
|
||||
Platforms: iOS
|
||||
|
||||
|
||||
### Additional props
|
||||
### iOS App Transport Security
|
||||
|
||||
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.
|
||||
|
||||
- By default, iOS 9+ will only load encrypted HTTPS urls. If you need to load content from a webserver that only supports HTTP, you will need to modify your Info.plist file and add the following entry:
|
||||
- By default, iOS will only load encrypted (https) urls. If you want to load content from an unencrypted (http) source, you will need to modify your Info.plist file and add the following entry:
|
||||
|
||||
<img src="./docs/AppTransportSecuritySetting.png" width="50%">
|
||||
|
||||
For more detailed info check this [article](https://cocoacasts.com/how-to-add-app-transport-security-exception-domains)
|
||||
</details>
|
||||
|
||||
### Audio Mixing
|
||||
|
||||
At some point in the future, react-native-video will include an Audio Manager for configuring how videos mix with other apps playing sounds on the device.
|
||||
|
||||
On iOS, if you would like to allow other apps to play music over your video component, make the following change:
|
||||
|
||||
**AppDelegate.m**
|
||||
|
||||
```objective-c
|
||||
#import <AVFoundation/AVFoundation.h> // import
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
...
|
||||
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil]; // allow
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
You can also use the [ignoreSilentSwitch](ignoresilentswitch) prop.
|
||||
</details>
|
||||
|
||||
### Android Expansion File Usage
|
||||
Expansions files allow you to ship assets that exceed the 100MB apk size limit and don't need to be updated each time you push an app update.
|
||||
|
||||
@ -775,7 +982,35 @@ To enable audio to play in background on iOS the audio session needs to be set t
|
||||
|
||||
## Updating
|
||||
|
||||
### Version 3.0
|
||||
### Version 4.0.0
|
||||
|
||||
#### Gradle 3 and SDK 26 requirement
|
||||
In order to support ExoPlayer 2.9.0, you must use version 3 or higher of the Gradle plugin. This is included by default in React Native 0.57. ExoPlayer
|
||||
|
||||
#### ExoPlayer 2.9.0 Java 1.8 requirement
|
||||
ExoPlayer 2.9.0 uses some Java 1.8 features, so you may need to enable support for Java 1.8 in your app/build.gradle file. If you get an error, compiling with ExoPlayer like:
|
||||
`Default interface methods are only supported starting with Android N (--min-api 24)`
|
||||
|
||||
Add the following to your app/build.gradle file:
|
||||
```
|
||||
android {
|
||||
... // Various other settings go here
|
||||
compileOptions {
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### ExoPlayer no longer detaches
|
||||
When using a router like the react-navigation TabNavigator, switching between tab routes would previously cause ExoPlayer to detach causing the video player to pause. We now don't detach the view, allowing the video to continue playing in a background tab. This matches the behavior for iOS. Android MediaPlayer will crash if it detaches when switching routes, so its behavior has not been changed.
|
||||
|
||||
#### useTextureView now defaults to true
|
||||
The SurfaceView, which ExoPlayer has been using by default has a number of quirks that people are unaware of and often cause issues. This includes not supporting animations or scaling. It also causes strange behavior if you overlay two videos on top of each other, because the SurfaceView will [punch a hole](https://developer.android.com/reference/android/view/SurfaceView) through other views. Since TextureView doesn't have these issues and behaves in the way most developers expect, it makes sense to make it the default.
|
||||
|
||||
TextureView is not as fast as SurfaceView, so you may still want to enable SurfaceView support. To do this, you can set `useTextureView={false}`.
|
||||
|
||||
|
||||
### Version 3.0.0
|
||||
|
||||
#### All platforms now auto-play
|
||||
Previously, on Android ExoPlayer if the paused prop was not set, the media would not automatically start playing. The only way it would work was if you set `paused={false}`. This has been changed to automatically play if paused is not set so that the behavior is consistent across platforms.
|
||||
|
@ -1,5 +1,3 @@
|
||||
import keyMirror from 'keymirror';
|
||||
|
||||
export default {
|
||||
SRT: 'application/x-subrip',
|
||||
TTML: 'application/ttml+xml',
|
||||
|
44
Video.js
@ -179,6 +179,12 @@ export default class Video extends Component {
|
||||
}
|
||||
};
|
||||
|
||||
_onExternalPlaybackChange = (event) => {
|
||||
if (this.props.onExternalPlaybackChange) {
|
||||
this.props.onExternalPlaybackChange(event.nativeEvent);
|
||||
}
|
||||
}
|
||||
|
||||
_onAudioBecomingNoisy = () => {
|
||||
if (this.props.onAudioBecomingNoisy) {
|
||||
this.props.onAudioBecomingNoisy();
|
||||
@ -207,7 +213,7 @@ export default class Video extends Component {
|
||||
}
|
||||
|
||||
const isNetwork = !!(uri && uri.match(/^https?:/));
|
||||
const isAsset = !!(uri && uri.match(/^(assets-library|file|content|ms-appx|ms-appdata):/));
|
||||
const isAsset = !!(uri && uri.match(/^(assets-library|ipod-library|file|content|ms-appx|ms-appdata):/));
|
||||
|
||||
let nativeResizeMode;
|
||||
if (resizeMode === VideoResizeMode.stretch) {
|
||||
@ -243,6 +249,7 @@ export default class Video extends Component {
|
||||
onBandwidthUpdate: this._onBandwidthUpdate,
|
||||
onTimedMetadata: this._onTimedMetadata,
|
||||
onVideoAudioBecomingNoisy: this._onAudioBecomingNoisy,
|
||||
onVideoExternalPlaybackChange: this._onExternalPlaybackChange,
|
||||
onVideoFullscreenPlayerWillPresent: this._onFullscreenPlayerWillPresent,
|
||||
onVideoFullscreenPlayerDidPresent: this._onFullscreenPlayerDidPresent,
|
||||
onVideoFullscreenPlayerWillDismiss: this._onFullscreenPlayerWillDismiss,
|
||||
@ -255,35 +262,21 @@ export default class Video extends Component {
|
||||
onAudioBecomingNoisy: this._onAudioBecomingNoisy,
|
||||
});
|
||||
|
||||
if (this.props.poster && this.state.showPoster) {
|
||||
const posterStyle = {
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
top: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
resizeMode: this.props.posterResizeMode || 'contain'
|
||||
...StyleSheet.absoluteFillObject,
|
||||
resizeMode: this.props.posterResizeMode || 'contain',
|
||||
};
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<RCTVideo ref={this._assignRoot} {...nativeProps} />
|
||||
{this.props.poster &&
|
||||
this.state.showPoster && (
|
||||
<View style={nativeProps.style}>
|
||||
<RCTVideo
|
||||
ref={this._assignRoot}
|
||||
{...nativeProps}
|
||||
/>
|
||||
<Image
|
||||
style={posterStyle}
|
||||
source={{uri: this.props.poster}}
|
||||
/>
|
||||
<Image style={posterStyle} source={{ uri: this.props.poster }} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<RCTVideo
|
||||
ref={this._assignRoot}
|
||||
{...nativeProps}
|
||||
/>
|
||||
)}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -306,6 +299,7 @@ Video.propTypes = {
|
||||
onVideoEnd: PropTypes.func,
|
||||
onTimedMetadata: PropTypes.func,
|
||||
onVideoAudioBecomingNoisy: PropTypes.func,
|
||||
onVideoExternalPlaybackChange: PropTypes.func,
|
||||
onVideoFullscreenPlayerWillPresent: PropTypes.func,
|
||||
onVideoFullscreenPlayerDidPresent: PropTypes.func,
|
||||
onVideoFullscreenPlayerWillDismiss: PropTypes.func,
|
||||
@ -377,6 +371,7 @@ Video.propTypes = {
|
||||
controls: PropTypes.bool,
|
||||
audioOnly: PropTypes.bool,
|
||||
currentTime: PropTypes.number,
|
||||
fullscreenOrientation: PropTypes.oneOf(['all','landscape','portrait']),
|
||||
progressUpdateInterval: PropTypes.number,
|
||||
useTextureView: PropTypes.bool,
|
||||
onLoadStart: PropTypes.func,
|
||||
@ -396,6 +391,7 @@ Video.propTypes = {
|
||||
onPlaybackRateChange: PropTypes.func,
|
||||
onAudioFocusChanged: PropTypes.func,
|
||||
onAudioBecomingNoisy: PropTypes.func,
|
||||
onExternalPlaybackChange: PropTypes.func,
|
||||
|
||||
/* Required by react-native */
|
||||
scaleX: PropTypes.number,
|
||||
|
@ -17,20 +17,19 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
//noinspection GradleDynamicVersion
|
||||
provided "com.facebook.react:react-native:${safeExtGet('reactNativeVersion', '+')}"
|
||||
compile('com.google.android.exoplayer:exoplayer:2.8.2') {
|
||||
compileOnly "com.facebook.react:react-native:${safeExtGet('reactNativeVersion', '+')}"
|
||||
implementation('com.google.android.exoplayer:exoplayer:2.9.0') {
|
||||
exclude group: 'com.android.support'
|
||||
}
|
||||
|
||||
// All support libs must use the same version
|
||||
compile "com.android.support:support-annotations:${safeExtGet('supportLibVersion', '+')}"
|
||||
compile "com.android.support:support-compat:${safeExtGet('supportLibVersion', '+')}"
|
||||
compile "com.android.support:support-media-compat:${safeExtGet('supportLibVersion', '+')}"
|
||||
implementation "com.android.support:support-annotations:${safeExtGet('supportLibVersion', '+')}"
|
||||
implementation "com.android.support:support-compat:${safeExtGet('supportLibVersion', '+')}"
|
||||
implementation "com.android.support:support-media-compat:${safeExtGet('supportLibVersion', '+')}"
|
||||
|
||||
compile('com.google.android.exoplayer:extension-okhttp:2.8.2') {
|
||||
implementation('com.google.android.exoplayer:extension-okhttp:2.9.0') {
|
||||
exclude group: 'com.squareup.okhttp3', module: 'okhttp'
|
||||
}
|
||||
compile 'com.squareup.okhttp3:okhttp:3.11.0'
|
||||
implementation 'com.squareup.okhttp3:okhttp:3.11.0'
|
||||
|
||||
}
|
||||
|
@ -225,7 +225,10 @@ class ReactExoplayerView extends FrameLayout implements
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
stopPlayback();
|
||||
/* We want to be able to continue playing audio when switching tabs.
|
||||
* Leave this here in case it causes issues.
|
||||
*/
|
||||
// stopPlayback();
|
||||
}
|
||||
|
||||
// LifecycleEventListener implementation
|
||||
|
@ -244,7 +244,7 @@ public class ReactExoplayerViewManager extends ViewGroupManager<ReactExoplayerVi
|
||||
videoView.setFullscreen(fullscreen);
|
||||
}
|
||||
|
||||
@ReactProp(name = PROP_USE_TEXTURE_VIEW, defaultBoolean = false)
|
||||
@ReactProp(name = PROP_USE_TEXTURE_VIEW, defaultBoolean = true)
|
||||
public void setUseTextureView(final ReactExoplayerView videoView, final boolean useTextureView) {
|
||||
videoView.setUseTextureView(useTextureView);
|
||||
}
|
||||
|
@ -21,6 +21,6 @@ android {
|
||||
|
||||
dependencies {
|
||||
//noinspection GradleDynamicVersion
|
||||
provided "com.facebook.react:react-native:${safeExtGet('reactNativeVersion', '+')}"
|
||||
compile 'com.yqritc:android-scalablevideoview:1.0.4'
|
||||
compileOnly "com.facebook.react:react-native:${safeExtGet('reactNativeVersion', '+')}"
|
||||
implementation 'com.yqritc:android-scalablevideoview:1.0.4'
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.brentvatne.react;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.content.res.AssetFileDescriptor;
|
||||
import android.graphics.Matrix;
|
||||
|
22
docs/caching.md
Normal file
@ -0,0 +1,22 @@
|
||||
# Caching
|
||||
|
||||
Caching is currently only supported on `iOS` platforms with a CocoaPods setup.
|
||||
|
||||
# Technology
|
||||
|
||||
The cache is backed by [SPTPersistentCache](https://github.com/spotify/SPTPersistentCache) and [DVAssetLoaderDelegate](https://github.com/vdugnist/DVAssetLoaderDelegate).
|
||||
|
||||
# How Does It Work
|
||||
|
||||
The caching is based on the url of the asset.
|
||||
SPTPersistentCache is a LRU ([Least Recently Used](https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU))) cache.
|
||||
|
||||
# Restrictions
|
||||
|
||||
Currently, caching is only supported for URLs that end in a `.mp4`, `.m4v`, or `.mov` extension. In future versions, URLs that end in a query string (e.g. test.mp4?resolution=480p) will be support once dependencies allow access to the `Content-Type` header. At this time, HLS playlists (.m3u8) and videos that sideload text tracks are not supported and will bypass the cache.
|
||||
|
||||
You will also receive warnings in the Xcode logs by using the `debug` mode. So if you are not 100% sure if your video is cached, check your Xcode logs!
|
||||
|
||||
By default files expire after 30 days and the maxmimum cache size is 100mb.
|
||||
|
||||
In a future release the cache might have more configurable options.
|
9
dom/LICENSE.md
Normal file
@ -0,0 +1,9 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Vincent Riemer
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
272
dom/RCTVideo.js
Normal file
@ -0,0 +1,272 @@
|
||||
// @flow
|
||||
|
||||
import { RCTEvent, RCTView, type RCTBridge } from "react-native-dom";
|
||||
import shaka from "shaka-player";
|
||||
|
||||
import resizeModes from "./resizeModes";
|
||||
import type { VideoSource } from "./types";
|
||||
import RCTVideoEvent from "./RCTVideoEvent";
|
||||
|
||||
class RCTVideo extends RCTView {
|
||||
playPromise: Promise<void> = Promise.resolve();
|
||||
progressTimer: number;
|
||||
videoElement: HTMLVideoElement;
|
||||
|
||||
onEnd: boolean = false;
|
||||
onLoad: boolean = false;
|
||||
onLoadStart: boolean = false;
|
||||
onProgress: boolean = false;
|
||||
|
||||
_paused: boolean = false;
|
||||
_progressUpdateInterval: number = 250.0;
|
||||
_savedVolume: number = 1.0;
|
||||
|
||||
constructor(bridge: RCTBridge) {
|
||||
super(bridge);
|
||||
|
||||
this.eventDispatcher = bridge.getModuleByName("EventDispatcher");
|
||||
|
||||
shaka.polyfill.installAll();
|
||||
|
||||
this.onEnd = this.onEnd.bind(this);
|
||||
this.onLoad = this.onLoad.bind(this);
|
||||
this.onLoadStart = this.onLoadStart.bind(this);
|
||||
this.onPlay = this.onPlay.bind(this);
|
||||
this.onProgress = this.onProgress.bind(this);
|
||||
|
||||
this.videoElement = this.initializeVideoElement();
|
||||
this.videoElement.addEventListener("ended", this.onEnd);
|
||||
this.videoElement.addEventListener("loadeddata", this.onLoad);
|
||||
this.videoElement.addEventListener("loadstart", this.onLoadStart);
|
||||
this.videoElement.addEventListener("pause", this.onPause);
|
||||
this.videoElement.addEventListener("play", this.onPlay);
|
||||
this.player = new shaka.Player(this.videoElement);
|
||||
|
||||
this.muted = false;
|
||||
this.rate = 1.0;
|
||||
this.volume = 1.0;
|
||||
this.childContainer.appendChild(this.videoElement);
|
||||
}
|
||||
|
||||
detachFromView(view: UIView) {
|
||||
this.videoElement.removeEventListener("ended", this.onEnd);
|
||||
this.videoElement.removeEventListener("loadeddata", this.onLoad);
|
||||
this.videoElement.removeEventListener("loadstart", this.onLoadStart);
|
||||
this.videoElement.removeEventListener("pause", this.onPause);
|
||||
this.videoElement.removeEventListener("play", this.onPlay);
|
||||
|
||||
this.stopProgressTimer();
|
||||
}
|
||||
|
||||
initializeVideoElement() {
|
||||
const elem = document.createElement("video");
|
||||
|
||||
Object.assign(elem.style, {
|
||||
display: "block",
|
||||
position: "absolute",
|
||||
top: "0",
|
||||
left: "0",
|
||||
width: "100%",
|
||||
height: "100%"
|
||||
});
|
||||
|
||||
return elem;
|
||||
}
|
||||
|
||||
presentFullscreenPlayer() {
|
||||
this.videoElement.webkitRequestFullScreen();
|
||||
}
|
||||
|
||||
set controls(value: boolean) {
|
||||
this.videoElement.controls = value;
|
||||
this.videoElement.style.pointerEvents = value ? "auto" : "";
|
||||
}
|
||||
|
||||
set id(value: string) {
|
||||
this.videoElement.id = value;
|
||||
}
|
||||
|
||||
set muted(value: boolean) {
|
||||
this.videoElement.muted = true;
|
||||
}
|
||||
|
||||
set paused(value: boolean) {
|
||||
if (value) {
|
||||
this.videoElement.pause();
|
||||
} else {
|
||||
this.requestPlay();
|
||||
}
|
||||
this._paused = value;
|
||||
}
|
||||
|
||||
set progressUpdateInterval(value: number) {
|
||||
this._progressUpdateInterval = value;
|
||||
this.stopProgressTimer();
|
||||
if (!this._paused) {
|
||||
this.startProgressTimer();
|
||||
}
|
||||
}
|
||||
|
||||
set rate(value: number) {
|
||||
this.videoElement.defaultPlaybackRate = value; // playbackRate doesn't work on Chrome
|
||||
this.videoElement.playbackRate = value;
|
||||
}
|
||||
|
||||
set repeat(value: boolean) {
|
||||
this.videoElement.loop = value;
|
||||
}
|
||||
|
||||
set resizeMode(value: number) {
|
||||
switch (value) {
|
||||
case resizeModes.ScaleNone: {
|
||||
this.videoElement.style.objectFit = "none";
|
||||
break;
|
||||
}
|
||||
case resizeModes.ScaleToFill: {
|
||||
this.videoElement.style.objectFit = "fill";
|
||||
break;
|
||||
}
|
||||
case resizeModes.ScaleAspectFit: {
|
||||
this.videoElement.style.objectFit = "contain";
|
||||
break;
|
||||
}
|
||||
case resizeModes.ScaleAspectFill: {
|
||||
this.videoElement.style.objectFit = "cover";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set seek(value: number) {
|
||||
this.videoElement.currentTime = value;
|
||||
}
|
||||
|
||||
set source(value: VideoSource) {
|
||||
let uri = value.uri;
|
||||
|
||||
if (uri.startsWith("blob:")) {
|
||||
let blob = this.bridge.blobManager.resolveURL(uri);
|
||||
if (blob.type === "text/xml") {
|
||||
blob = new Blob([blob], { type: "video/mp4" });
|
||||
}
|
||||
uri = URL.createObjectURL(blob);
|
||||
}
|
||||
|
||||
if (!shaka.Player.isBrowserSupported()) { // primarily iOS WebKit
|
||||
this.videoElement.setAttribute("src", uri);
|
||||
if (!this._paused) {
|
||||
this.requestPlay();
|
||||
}
|
||||
} else {
|
||||
this.player.load(uri)
|
||||
.then(() => {
|
||||
if (!this._paused) {
|
||||
this.requestPlay();
|
||||
}
|
||||
})
|
||||
.catch(this.onError);
|
||||
}
|
||||
}
|
||||
|
||||
set volume(value: number) {
|
||||
if (value === 0) {
|
||||
this.muted = true;
|
||||
} else {
|
||||
this.videoElement.volume = value;
|
||||
this.muted = false;
|
||||
}
|
||||
}
|
||||
|
||||
onEnd = () => {
|
||||
this.onProgress();
|
||||
this.sendEvent("topVideoEnd", null);
|
||||
this.stopProgressTimer();
|
||||
}
|
||||
|
||||
onError = error => {
|
||||
console.warn("topVideoError", error);
|
||||
}
|
||||
|
||||
onLoad = () => {
|
||||
// height & width are safe with audio, will be 0
|
||||
const height = this.videoElement.videoHeight;
|
||||
const width = this.videoElement.videoWidth;
|
||||
const payload = {
|
||||
currentPosition: this.videoElement.currentTime,
|
||||
duration: this.videoElement.duration,
|
||||
naturalSize: {
|
||||
width,
|
||||
height,
|
||||
orientation: width >= height ? "landscape" : "portrait"
|
||||
}
|
||||
};
|
||||
this.sendEvent("topVideoLoad", payload);
|
||||
}
|
||||
|
||||
onLoadStart = () => {
|
||||
const src = this.videoElement.currentSrc;
|
||||
const payload = {
|
||||
isNetwork: !src.match(/^https?:\/\/localhost/), // require is served from localhost
|
||||
uri: this.videoElement.currentSrc
|
||||
};
|
||||
this.sendEvent("topVideoLoadStart", payload);
|
||||
}
|
||||
|
||||
onPause = () => {
|
||||
this.stopProgressTimer();
|
||||
}
|
||||
|
||||
onPlay = () => {
|
||||
this.startProgressTimer();
|
||||
}
|
||||
|
||||
onProgress = () => {
|
||||
const payload = {
|
||||
currentTime: this.videoElement.currentTime,
|
||||
seekableDuration: this.videoElement.duration
|
||||
};
|
||||
this.sendEvent("topVideoProgress", payload);
|
||||
}
|
||||
|
||||
onRejectedAutoplay = () => {
|
||||
this.sendEvent("topVideoRejectedAutoplay", null);
|
||||
}
|
||||
|
||||
requestPlay() {
|
||||
const playPromise = this.videoElement.play();
|
||||
if (playPromise) {
|
||||
playPromise
|
||||
.then(() => {})
|
||||
.catch(e => {
|
||||
/* This is likely one of:
|
||||
* name: NotAllowedError - autoplay is not supported
|
||||
* name: NotSupportedError - format is not supported
|
||||
*/
|
||||
this.onError({ code: e.name, message: e.message });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
sendEvent(eventName, payload) {
|
||||
const event = new RCTVideoEvent(eventName, this.reactTag, 0, payload);
|
||||
this.eventDispatcher.sendEvent(event);
|
||||
}
|
||||
|
||||
startProgressTimer() {
|
||||
if (!this.progressTimer && this._progressUpdateInterval) {
|
||||
this.onProgress();
|
||||
this.progressTimer = setInterval(this.onProgress, this._progressUpdateInterval);
|
||||
}
|
||||
}
|
||||
|
||||
stopProgressTimer() {
|
||||
if (this.progressTimer) {
|
||||
clearInterval(this.progressTimer);
|
||||
this.progressTimer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("rct-video", RCTVideo);
|
||||
|
||||
export default RCTVideo;
|
56
dom/RCTVideoEvent.js
Normal file
@ -0,0 +1,56 @@
|
||||
// import { RCTEvent } from "react-native-dom";
|
||||
|
||||
interface RCTEvent {
|
||||
viewTag: number;
|
||||
eventName: string;
|
||||
coalescingKey: number;
|
||||
|
||||
canCoalesce(): boolean;
|
||||
coalesceWithEvent(event: RCTEvent): RCTEvent;
|
||||
|
||||
moduleDotMethod(): string;
|
||||
arguments(): Array<any>;
|
||||
}
|
||||
|
||||
export default class RCTVideoEvent implements RCTEvent {
|
||||
viewTag: number;
|
||||
eventName: string;
|
||||
coalescingKey: number;
|
||||
|
||||
constructor(
|
||||
eventName: string,
|
||||
reactTag: number,
|
||||
coalescingKey: number,
|
||||
data: ?Object
|
||||
) {
|
||||
this.viewTag = reactTag;
|
||||
this.eventName = eventName;
|
||||
this.coalescingKey = coalescingKey;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
canCoalesce(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
coalesceWithEvent(event: RCTEvent): RCTEvent {
|
||||
return;
|
||||
}
|
||||
|
||||
moduleDotMethod(): string {
|
||||
return "RCTEventEmitter.receiveEvent";
|
||||
}
|
||||
|
||||
arguments(): Array<any> {
|
||||
const args = [
|
||||
this.viewTag,
|
||||
this.eventName,
|
||||
this.data
|
||||
];
|
||||
return args;
|
||||
}
|
||||
|
||||
coalescingKey(): number {
|
||||
return this.coalescingKey;
|
||||
}
|
||||
}
|
87
dom/RCTVideoManager.js
Normal file
@ -0,0 +1,87 @@
|
||||
// @flow
|
||||
|
||||
import { RCTViewManager } from "react-native-dom";
|
||||
|
||||
import RCTVideo from "./RCTVideo";
|
||||
import resizeModes from "./resizeModes";
|
||||
|
||||
import type { VideoSource } from "./types";
|
||||
|
||||
class RCTVideoManager extends RCTViewManager {
|
||||
static moduleName = "RCTVideoManager";
|
||||
|
||||
view() {
|
||||
return new RCTVideo(this.bridge);
|
||||
}
|
||||
|
||||
describeProps() {
|
||||
return super
|
||||
.describeProps()
|
||||
.addBooleanProp("controls", this.setControls)
|
||||
.addStringProp("id", this.setId)
|
||||
.addBooleanProp("muted", this.setMuted)
|
||||
.addBooleanProp("paused", this.setPaused)
|
||||
.addNumberProp("progressUpdateInterval", this.setProgressUpdateInterval)
|
||||
.addBooleanProp("rate", this.setRate)
|
||||
.addBooleanProp("repeat", this.setRepeat)
|
||||
.addNumberProp("resizeMode", this.setResizeMode)
|
||||
.addNumberProp("seek", this.setSeek)
|
||||
.addObjectProp("src", this.setSource)
|
||||
.addNumberProp("volume", this.setVolume)
|
||||
.addDirectEvent("onVideoEnd")
|
||||
.addDirectEvent("onVideoError")
|
||||
.addDirectEvent("onVideoLoad")
|
||||
.addDirectEvent("onVideoLoadStart")
|
||||
.addDirectEvent("onVideoProgress");
|
||||
}
|
||||
|
||||
dismissFullscreenPlayer() {
|
||||
// not currently working
|
||||
}
|
||||
|
||||
presentFullscreenPlayer() {
|
||||
// not currently working
|
||||
}
|
||||
|
||||
setControls(view: RCTVideo, value: boolean) {
|
||||
view.controls = value;
|
||||
}
|
||||
|
||||
setId(view: RCTVideo, value: string) {
|
||||
view.id = value;
|
||||
}
|
||||
|
||||
setMuted(view: RCTVideo, value: boolean) {
|
||||
view.muted = value;
|
||||
}
|
||||
|
||||
setPaused(view: RCTVideo, value: boolean) {
|
||||
view.paused = value;
|
||||
}
|
||||
|
||||
setRate(view: RCTVideo, value: number) {
|
||||
view.rate = value;
|
||||
}
|
||||
|
||||
setRepeat(view: RCTVideo, value: boolean) {
|
||||
view.repeat = value;
|
||||
}
|
||||
|
||||
setResizeMode(view: RCTVideo, value: number) {
|
||||
view.resizeMode = value;
|
||||
}
|
||||
|
||||
setSeek(view: RCTVideo, value: number) {
|
||||
view.seek = value;
|
||||
}
|
||||
|
||||
setSource(view: RCTVideo, value: VideoSource) {
|
||||
view.source = value;
|
||||
}
|
||||
|
||||
constantsToExport() {
|
||||
return { ...resizeModes };
|
||||
}
|
||||
}
|
||||
|
||||
export default RCTVideoManager;
|
3
dom/index.js
Normal file
@ -0,0 +1,3 @@
|
||||
// @flow
|
||||
|
||||
module.exports = require("./RCTVideoManager");
|
8
dom/resizeModes.js
Normal file
@ -0,0 +1,8 @@
|
||||
// @flow
|
||||
|
||||
export default {
|
||||
ScaleNone: 0,
|
||||
ScaleToFill: 1,
|
||||
ScaleAspectFit: 2,
|
||||
ScaleAspectFill: 3,
|
||||
};
|
10
dom/types.js
Normal file
@ -0,0 +1,10 @@
|
||||
// @flow
|
||||
|
||||
export type VideoSource = {
|
||||
uri: string,
|
||||
type: string,
|
||||
mainVer: number,
|
||||
patchVer: number,
|
||||
isNetwork: boolean,
|
||||
isAsset: boolean,
|
||||
};
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"name": "VideoPlayer",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "node_modules/react-native/packager/packager.sh"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "15.4.2",
|
||||
"react-native": "^0.42.0",
|
||||
"react-native-video": "file:../",
|
||||
"react-native-windows": "^0.40.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"rnpm-plugin-windows": "~0.2.3"
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 7.5 KiB |
53
examples/basic/ios/VideoPlayer-tvOS.plist
Normal file
@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSExceptionDomains</key>
|
||||
<dict>
|
||||
<key>localhost</key>
|
||||
<dict>
|
||||
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
<string></string>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
@ -12,7 +12,6 @@
|
||||
00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */; };
|
||||
00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; };
|
||||
00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; };
|
||||
00E356F31AD99517003FC87E /* VideoPlayerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* VideoPlayerTests.m */; };
|
||||
133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; };
|
||||
139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; };
|
||||
139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */; };
|
||||
@ -20,11 +19,21 @@
|
||||
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||
140ED2AC1D01E1AD002B40FF /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; };
|
||||
146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; };
|
||||
5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */; };
|
||||
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
|
||||
8C2A0F841E2560A100E31596 /* libRCTVideo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C2A0F791E25608300E31596 /* libRCTVideo.a */; };
|
||||
FA3566AB216D5D7000E01ABD /* libRCTImage-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E841DF850E9000B6D8A /* libRCTImage-tvOS.a */; };
|
||||
FA3566AC216D5D7000E01ABD /* libRCTLinking-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E881DF850E9000B6D8A /* libRCTLinking-tvOS.a */; };
|
||||
FA3566AD216D5D7000E01ABD /* libRCTNetwork-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E8C1DF850E9000B6D8A /* libRCTNetwork-tvOS.a */; };
|
||||
FA3566AE216D5D7000E01ABD /* libRCTSettings-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E901DF850E9000B6D8A /* libRCTSettings-tvOS.a */; };
|
||||
FA3566AF216D5D7000E01ABD /* libRCTText-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E941DF850E9000B6D8A /* libRCTText-tvOS.a */; };
|
||||
FA3566B0216D5D7000E01ABD /* libRCTWebSocket-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E991DF850E9000B6D8A /* libRCTWebSocket-tvOS.a */; };
|
||||
FA3566C8216D5DA900E01ABD /* libRCTVideo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D1107C542111145500073188 /* libRCTVideo.a */; };
|
||||
FA8681B8216D5C6D0010C92A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
|
||||
FA8681B9216D5C6D0010C92A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||
FA8681C8216D5C6D0010C92A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||
FA8B47A5216D777200AB07CF /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3EA31DF850E9000B6D8A /* libReact.a */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@ -63,13 +72,6 @@
|
||||
remoteGlobalIDString = 832C81801AAF6DEF007FA2F7;
|
||||
remoteInfo = RCTVibration;
|
||||
};
|
||||
00E356F41AD99517003FC87E /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 13B07F861A680F5B00A75B9A;
|
||||
remoteInfo = VideoPlayer;
|
||||
};
|
||||
139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */;
|
||||
@ -217,6 +219,83 @@
|
||||
remoteGlobalIDString = 134814201AA4EA6300B7C361;
|
||||
remoteInfo = RCTVideo;
|
||||
};
|
||||
D1107C532111145500073188 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 8C2A0F651E25608300E31596 /* RCTVideo.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 641E28441F0EEC8500443AF6;
|
||||
remoteInfo = "RCTVideo-tvOS";
|
||||
};
|
||||
D1107C592111145500073188 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 3DBE0D001F3B181A0099AA32;
|
||||
remoteInfo = fishhook;
|
||||
};
|
||||
D1107C5B2111145500073188 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 3DBE0D0D1F3B181C0099AA32;
|
||||
remoteInfo = "fishhook-tvOS";
|
||||
};
|
||||
D1107C6D2111145500073188 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = EBF21BDC1FC498900052F4D5;
|
||||
remoteInfo = jsinspector;
|
||||
};
|
||||
D1107C6F2111145500073188 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = EBF21BFA1FC4989A0052F4D5;
|
||||
remoteInfo = "jsinspector-tvOS";
|
||||
};
|
||||
D1107C712111145500073188 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 139D7ECE1E25DB7D00323FB7;
|
||||
remoteInfo = "third-party";
|
||||
};
|
||||
D1107C732111145500073188 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 3D383D3C1EBD27B6005632C8;
|
||||
remoteInfo = "third-party-tvOS";
|
||||
};
|
||||
D1107C752111145500073188 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 139D7E881E25C6D100323FB7;
|
||||
remoteInfo = "double-conversion";
|
||||
};
|
||||
D1107C772111145500073188 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 3D383D621EBD27B9005632C8;
|
||||
remoteInfo = "double-conversion-tvOS";
|
||||
};
|
||||
D1107C792111145500073188 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 9936F3131F5F2E4B0010BF04;
|
||||
remoteInfo = privatedata;
|
||||
};
|
||||
D1107C7B2111145500073188 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 9936F32F1F5F2E5B0010BF04;
|
||||
remoteInfo = "privatedata-tvOS";
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
@ -226,9 +305,6 @@
|
||||
00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = "../node_modules/react-native/Libraries/Image/RCTImage.xcodeproj"; sourceTree = "<group>"; };
|
||||
00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = "../node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj"; sourceTree = "<group>"; };
|
||||
00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = "../node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj"; sourceTree = "<group>"; };
|
||||
00E356EE1AD99517003FC87E /* VideoPlayerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = VideoPlayerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
00E356F21AD99517003FC87E /* VideoPlayerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VideoPlayerTests.m; sourceTree = "<group>"; };
|
||||
139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = "../node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj"; sourceTree = "<group>"; };
|
||||
139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = "../node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj"; sourceTree = "<group>"; };
|
||||
13B07F961A680F5B00A75B9A /* VideoPlayer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VideoPlayer.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
@ -239,28 +315,24 @@
|
||||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = VideoPlayer/Info.plist; sourceTree = "<group>"; };
|
||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = VideoPlayer/main.m; sourceTree = "<group>"; };
|
||||
146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = "<group>"; };
|
||||
39CBB10045CEBFA9BBB9645E /* libPods-VideoPlayer.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-VideoPlayer.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAnimation.xcodeproj; path = "../node_modules/react-native/Libraries/NativeAnimation/RCTAnimation.xcodeproj"; sourceTree = "<group>"; };
|
||||
627363E07276C06249D7CEBF /* libPods-VideoPlayer-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-VideoPlayer-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = "<group>"; };
|
||||
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = "<group>"; };
|
||||
8C2A0F651E25608300E31596 /* RCTVideo.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVideo.xcodeproj; path = "../node_modules/react-native-video/ios/RCTVideo.xcodeproj"; sourceTree = "<group>"; };
|
||||
FA8681CE216D5C6D0010C92A /* VideoPlayer-tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "VideoPlayer-tvOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
FA8681D0216D5C6E0010C92A /* VideoPlayer-tvOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "VideoPlayer-tvOS.plist"; path = "/Users/amishra/Development/react-native-video-nfb/examples/basic/ios/VideoPlayer-tvOS.plist"; sourceTree = "<absolute>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
00E356EB1AD99517003FC87E /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
140ED2AC1D01E1AD002B40FF /* libReact.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
13B07F8C1A680F5B00A75B9A /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
8C2A0F841E2560A100E31596 /* libRCTVideo.a in Frameworks */,
|
||||
5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */,
|
||||
146834051AC3E58100842450 /* libReact.a in Frameworks */,
|
||||
5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */,
|
||||
8C2A0F841E2560A100E31596 /* libRCTVideo.a in Frameworks */,
|
||||
00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */,
|
||||
00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */,
|
||||
00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */,
|
||||
@ -273,6 +345,21 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
FA8681BA216D5C6D0010C92A /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
FA8B47A5216D777200AB07CF /* libReact.a in Frameworks */,
|
||||
FA3566AB216D5D7000E01ABD /* libRCTImage-tvOS.a in Frameworks */,
|
||||
FA3566AC216D5D7000E01ABD /* libRCTLinking-tvOS.a in Frameworks */,
|
||||
FA3566AD216D5D7000E01ABD /* libRCTNetwork-tvOS.a in Frameworks */,
|
||||
FA3566AE216D5D7000E01ABD /* libRCTSettings-tvOS.a in Frameworks */,
|
||||
FA3566AF216D5D7000E01ABD /* libRCTText-tvOS.a in Frameworks */,
|
||||
FA3566B0216D5D7000E01ABD /* libRCTWebSocket-tvOS.a in Frameworks */,
|
||||
FA3566C8216D5DA900E01ABD /* libRCTVideo.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
@ -318,23 +405,6 @@
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
00E356EF1AD99517003FC87E /* VideoPlayerTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
00E356F21AD99517003FC87E /* VideoPlayerTests.m */,
|
||||
00E356F01AD99517003FC87E /* Supporting Files */,
|
||||
);
|
||||
path = VideoPlayerTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
00E356F01AD99517003FC87E /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
00E356F11AD99517003FC87E /* Info.plist */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
139105B71AF99BAD00B5F7CC /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -349,6 +419,8 @@
|
||||
children = (
|
||||
139FDEF41B06529B00C62182 /* libRCTWebSocket.a */,
|
||||
3DAD3E991DF850E9000B6D8A /* libRCTWebSocket-tvOS.a */,
|
||||
D1107C5A2111145500073188 /* libfishhook.a */,
|
||||
D1107C5C2111145500073188 /* libfishhook-tvOS.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@ -378,6 +450,14 @@
|
||||
3DAD3EAB1DF850E9000B6D8A /* libcxxreact.a */,
|
||||
3DAD3EAD1DF850E9000B6D8A /* libjschelpers.a */,
|
||||
3DAD3EAF1DF850E9000B6D8A /* libjschelpers.a */,
|
||||
D1107C6E2111145500073188 /* libjsinspector.a */,
|
||||
D1107C702111145500073188 /* libjsinspector-tvOS.a */,
|
||||
D1107C722111145500073188 /* libthird-party.a */,
|
||||
D1107C742111145500073188 /* libthird-party.a */,
|
||||
D1107C762111145500073188 /* libdouble-conversion.a */,
|
||||
D1107C782111145500073188 /* libdouble-conversion.a */,
|
||||
D1107C7A2111145500073188 /* libprivatedata.a */,
|
||||
D1107C7C2111145500073188 /* libprivatedata-tvOS.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@ -386,7 +466,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */,
|
||||
5E9157351DD0AC6500FF2AA8 /* libRCTAnimation-tvOS.a */,
|
||||
5E9157351DD0AC6500FF2AA8 /* libRCTAnimation.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@ -431,10 +511,11 @@
|
||||
83CBB9F61A601CBA00E9B192 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FA8681CF216D5C6D0010C92A /* Resources-iPad */,
|
||||
13B07FAE1A68108700A75B9A /* VideoPlayer */,
|
||||
832341AE1AAA6A7D00B99B32 /* Libraries */,
|
||||
00E356EF1AD99517003FC87E /* VideoPlayerTests */,
|
||||
83CBBA001A601CBA00E9B192 /* Products */,
|
||||
FA35669C216D5D7000E01ABD /* Frameworks */,
|
||||
);
|
||||
indentWidth = 2;
|
||||
sourceTree = "<group>";
|
||||
@ -444,7 +525,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13B07F961A680F5B00A75B9A /* VideoPlayer.app */,
|
||||
00E356EE1AD99517003FC87E /* VideoPlayerTests.xctest */,
|
||||
FA8681CE216D5C6D0010C92A /* VideoPlayer-tvOS.app */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@ -453,31 +534,31 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8C2A0F791E25608300E31596 /* libRCTVideo.a */,
|
||||
D1107C542111145500073188 /* libRCTVideo.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FA35669C216D5D7000E01ABD /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
39CBB10045CEBFA9BBB9645E /* libPods-VideoPlayer.a */,
|
||||
627363E07276C06249D7CEBF /* libPods-VideoPlayer-tvOS.a */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FA8681CF216D5C6D0010C92A /* Resources-iPad */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FA8681D0216D5C6E0010C92A /* VideoPlayer-tvOS.plist */,
|
||||
);
|
||||
name = "Resources-iPad";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
00E356ED1AD99517003FC87E /* VideoPlayerTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "VideoPlayerTests" */;
|
||||
buildPhases = (
|
||||
00E356EA1AD99517003FC87E /* Sources */,
|
||||
00E356EB1AD99517003FC87E /* Frameworks */,
|
||||
00E356EC1AD99517003FC87E /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
00E356F51AD99517003FC87E /* PBXTargetDependency */,
|
||||
);
|
||||
name = VideoPlayerTests;
|
||||
productName = VideoPlayerTests;
|
||||
productReference = 00E356EE1AD99517003FC87E /* VideoPlayerTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
13B07F861A680F5B00A75B9A /* VideoPlayer */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "VideoPlayer" */;
|
||||
@ -496,6 +577,24 @@
|
||||
productReference = 13B07F961A680F5B00A75B9A /* VideoPlayer.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
FA8681B6216D5C6D0010C92A /* VideoPlayer-tvOS */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = FA8681CB216D5C6D0010C92A /* Build configuration list for PBXNativeTarget "VideoPlayer-tvOS" */;
|
||||
buildPhases = (
|
||||
FA8681B7216D5C6D0010C92A /* Sources */,
|
||||
FA8681BA216D5C6D0010C92A /* Frameworks */,
|
||||
FA8681C7216D5C6D0010C92A /* Resources */,
|
||||
FA8681CA216D5C6D0010C92A /* Bundle React Native code and images */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = "VideoPlayer-tvOS";
|
||||
productName = "Hello World";
|
||||
productReference = FA8681CE216D5C6D0010C92A /* VideoPlayer-tvOS.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
@ -504,12 +603,6 @@
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0610;
|
||||
ORGANIZATIONNAME = Facebook;
|
||||
TargetAttributes = {
|
||||
00E356ED1AD99517003FC87E = {
|
||||
CreatedOnToolsVersion = 6.2;
|
||||
TestTargetID = 13B07F861A680F5B00A75B9A;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "VideoPlayer" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
@ -575,7 +668,7 @@
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
13B07F861A680F5B00A75B9A /* VideoPlayer */,
|
||||
00E356ED1AD99517003FC87E /* VideoPlayerTests */,
|
||||
FA8681B6216D5C6D0010C92A /* VideoPlayer-tvOS */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
@ -735,10 +828,10 @@
|
||||
remoteRef = 5E9157321DD0AC6500FF2AA8 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
5E9157351DD0AC6500FF2AA8 /* libRCTAnimation-tvOS.a */ = {
|
||||
5E9157351DD0AC6500FF2AA8 /* libRCTAnimation.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = "libRCTAnimation-tvOS.a";
|
||||
path = libRCTAnimation.a;
|
||||
remoteRef = 5E9157341DD0AC6500FF2AA8 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
@ -763,16 +856,86 @@
|
||||
remoteRef = 8C2A0F781E25608300E31596 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
D1107C542111145500073188 /* libRCTVideo.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRCTVideo.a;
|
||||
remoteRef = D1107C532111145500073188 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
D1107C5A2111145500073188 /* libfishhook.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libfishhook.a;
|
||||
remoteRef = D1107C592111145500073188 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
D1107C5C2111145500073188 /* libfishhook-tvOS.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = "libfishhook-tvOS.a";
|
||||
remoteRef = D1107C5B2111145500073188 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
D1107C6E2111145500073188 /* libjsinspector.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libjsinspector.a;
|
||||
remoteRef = D1107C6D2111145500073188 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
D1107C702111145500073188 /* libjsinspector-tvOS.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = "libjsinspector-tvOS.a";
|
||||
remoteRef = D1107C6F2111145500073188 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
D1107C722111145500073188 /* libthird-party.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = "libthird-party.a";
|
||||
remoteRef = D1107C712111145500073188 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
D1107C742111145500073188 /* libthird-party.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = "libthird-party.a";
|
||||
remoteRef = D1107C732111145500073188 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
D1107C762111145500073188 /* libdouble-conversion.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = "libdouble-conversion.a";
|
||||
remoteRef = D1107C752111145500073188 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
D1107C782111145500073188 /* libdouble-conversion.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = "libdouble-conversion.a";
|
||||
remoteRef = D1107C772111145500073188 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
D1107C7A2111145500073188 /* libprivatedata.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libprivatedata.a;
|
||||
remoteRef = D1107C792111145500073188 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
D1107C7C2111145500073188 /* libprivatedata-tvOS.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = "libprivatedata-tvOS.a";
|
||||
remoteRef = D1107C7B2111145500073188 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
/* End PBXReferenceProxy section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
00E356EC1AD99517003FC87E /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
13B07F8E1A680F5B00A75B9A /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@ -782,6 +945,14 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
FA8681C7216D5C6D0010C92A /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
FA8681C8216D5C6D0010C92A /* Images.xcassets in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
@ -797,19 +968,25 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "export NODE_BINARY=node\n../node_modules/react-native/packager/react-native-xcode.sh";
|
||||
shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh\n";
|
||||
};
|
||||
FA8681CA216D5C6D0010C92A /* Bundle React Native code and images */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Bundle React Native code and images";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh\n";
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
00E356EA1AD99517003FC87E /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
00E356F31AD99517003FC87E /* VideoPlayerTests.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
13B07F871A680F5B00A75B9A /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@ -819,15 +996,16 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
00E356F51AD99517003FC87E /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 13B07F861A680F5B00A75B9A /* VideoPlayer */;
|
||||
targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */;
|
||||
FA8681B7216D5C6D0010C92A /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
FA8681B8216D5C6D0010C92A /* AppDelegate.m in Sources */,
|
||||
FA8681B9216D5C6D0010C92A /* main.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = {
|
||||
@ -842,41 +1020,13 @@
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
00E356F61AD99517003FC87E /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
INFOPLIST_FILE = VideoPlayerTests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/VideoPlayer.app/VideoPlayer";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
00E356F71AD99517003FC87E /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
INFOPLIST_FILE = VideoPlayerTests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/VideoPlayer.app/VideoPlayer";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
13B07F941A680F5B00A75B9A /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEAD_CODE_STRIPPING = NO;
|
||||
HEADER_SEARCH_PATHS = "$(inherited)";
|
||||
INFOPLIST_FILE = VideoPlayer/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
OTHER_LDFLAGS = (
|
||||
@ -894,6 +1044,7 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
HEADER_SEARCH_PATHS = "$(inherited)";
|
||||
INFOPLIST_FILE = VideoPlayer/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
OTHER_LDFLAGS = (
|
||||
@ -982,18 +1133,54 @@
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
FA8681CC216D5C6D0010C92A /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEAD_CODE_STRIPPING = NO;
|
||||
INFOPLIST_FILE = "VideoPlayer-tvOS.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
"-lc++",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.VideoPlayer-tvOS";
|
||||
PRODUCT_NAME = "VideoPlayer-tvOS";
|
||||
SDKROOT = appletvos;
|
||||
SUPPORTED_PLATFORMS = "appletvsimulator appletvos";
|
||||
TARGETED_DEVICE_FAMILY = 3;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
FA8681CD216D5C6D0010C92A /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
INFOPLIST_FILE = "VideoPlayer-tvOS.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
"-lc++",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.VideoPlayer-tvOS";
|
||||
PRODUCT_NAME = "VideoPlayer-tvOS";
|
||||
SDKROOT = appletvos;
|
||||
SUPPORTED_PLATFORMS = "appletvsimulator appletvos";
|
||||
TARGETED_DEVICE_FAMILY = 3;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "VideoPlayerTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
00E356F61AD99517003FC87E /* Debug */,
|
||||
00E356F71AD99517003FC87E /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "VideoPlayer" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
@ -1012,6 +1199,15 @@
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
FA8681CB216D5C6D0010C92A /* Build configuration list for PBXNativeTarget "VideoPlayer-tvOS" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
FA8681CC216D5C6D0010C92A /* Debug */,
|
||||
FA8681CD216D5C6D0010C92A /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
@ -0,0 +1,105 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1000"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "NO"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "2D2A28121D9B038B00D4039D"
|
||||
BuildableName = "libReact.a"
|
||||
BlueprintName = "React-tvOS"
|
||||
ReferencedContainer = "container:../node_modules/react-native/React/React.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "FA8681B6216D5C6D0010C92A"
|
||||
BuildableName = "VideoPlayer-tvOS.app"
|
||||
BlueprintName = "VideoPlayer-tvOS"
|
||||
ReferencedContainer = "container:VideoPlayer.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "FA8681B6216D5C6D0010C92A"
|
||||
BuildableName = "VideoPlayer-tvOS.app"
|
||||
BlueprintName = "VideoPlayer-tvOS"
|
||||
ReferencedContainer = "container:VideoPlayer.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "FA8681B6216D5C6D0010C92A"
|
||||
BuildableName = "VideoPlayer-tvOS.app"
|
||||
BlueprintName = "VideoPlayer-tvOS"
|
||||
ReferencedContainer = "container:VideoPlayer.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "FA8681B6216D5C6D0010C92A"
|
||||
BuildableName = "VideoPlayer-tvOS.app"
|
||||
BlueprintName = "VideoPlayer-tvOS"
|
||||
ReferencedContainer = "container:VideoPlayer.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
@ -34,20 +34,6 @@
|
||||
ReferencedContainer = "container:VideoPlayer.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "NO"
|
||||
buildForArchiving = "NO"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "00E356ED1AD99517003FC87E"
|
||||
BuildableName = "VideoPlayerTests.xctest"
|
||||
BlueprintName = "VideoPlayerTests"
|
||||
ReferencedContainer = "container:VideoPlayer.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
@ -56,16 +42,6 @@
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "00E356ED1AD99517003FC87E"
|
||||
BuildableName = "VideoPlayerTests.xctest"
|
||||
BlueprintName = "VideoPlayerTests"
|
||||
ReferencedContainer = "container:VideoPlayer.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
21
examples/basic/package.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "VideoPlayer",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "node node_modules/react-native/local-cli/cli.js start",
|
||||
"test": "jest"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "16.4.1",
|
||||
"react-native": "0.56.0",
|
||||
"react-native-video": "file:../.."
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-jest": "22.4.1",
|
||||
"babel-preset-react-native": "5.0.2",
|
||||
"express": "^4.16.2",
|
||||
"jest": "22.4.2",
|
||||
"react-test-renderer": "16.2.0"
|
||||
}
|
||||
}
|
7
examples/basic/rn-cli.config.js
Normal file
@ -0,0 +1,7 @@
|
||||
const blacklist = require('metro').createBlacklist;
|
||||
|
||||
module.exports = {
|
||||
getBlacklistRE: function() {
|
||||
return blacklist([/node_modules\/react-native-video\/examples\/.*/]);
|
||||
}
|
||||
};
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 7.5 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
3
examples/video-caching/.babelrc
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"presets": ["react-native"]
|
||||
}
|
6
examples/video-caching/.buckconfig
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
[android]
|
||||
target = Google Inc.:Google APIs:23
|
||||
|
||||
[maven_repositories]
|
||||
central = https://repo1.maven.org/maven2
|
54
examples/video-caching/.flowconfig
Normal file
@ -0,0 +1,54 @@
|
||||
[ignore]
|
||||
; We fork some components by platform
|
||||
.*/*[.]android.js
|
||||
|
||||
; Ignore "BUCK" generated dirs
|
||||
<PROJECT_ROOT>/\.buckd/
|
||||
|
||||
; Ignore unexpected extra "@providesModule"
|
||||
.*/node_modules/.*/node_modules/fbjs/.*
|
||||
|
||||
; Ignore duplicate module providers
|
||||
; For RN Apps installed via npm, "Libraries" folder is inside
|
||||
; "node_modules/react-native" but in the source repo it is in the root
|
||||
.*/Libraries/react-native/React.js
|
||||
|
||||
; Ignore polyfills
|
||||
.*/Libraries/polyfills/.*
|
||||
|
||||
; Ignore metro
|
||||
.*/node_modules/metro/.*
|
||||
|
||||
[include]
|
||||
|
||||
[libs]
|
||||
node_modules/react-native/Libraries/react-native/react-native-interface.js
|
||||
node_modules/react-native/flow/
|
||||
node_modules/react-native/flow-github/
|
||||
|
||||
[options]
|
||||
emoji=true
|
||||
|
||||
module.system=haste
|
||||
|
||||
munge_underscores=true
|
||||
|
||||
module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub'
|
||||
|
||||
module.file_ext=.js
|
||||
module.file_ext=.jsx
|
||||
module.file_ext=.json
|
||||
module.file_ext=.native.js
|
||||
|
||||
suppress_type=$FlowIssue
|
||||
suppress_type=$FlowFixMe
|
||||
suppress_type=$FlowFixMeProps
|
||||
suppress_type=$FlowFixMeState
|
||||
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
|
||||
|
||||
[version]
|
||||
^0.63.0
|
1
examples/video-caching/.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
||||
*.pbxproj -text
|
57
examples/video-caching/.gitignore
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
# OSX
|
||||
#
|
||||
.DS_Store
|
||||
|
||||
# Xcode
|
||||
#
|
||||
build/
|
||||
*.pbxuser
|
||||
!default.pbxuser
|
||||
*.mode1v3
|
||||
!default.mode1v3
|
||||
*.mode2v3
|
||||
!default.mode2v3
|
||||
*.perspectivev3
|
||||
!default.perspectivev3
|
||||
xcuserdata
|
||||
*.xccheckout
|
||||
*.moved-aside
|
||||
DerivedData
|
||||
*.hmap
|
||||
*.ipa
|
||||
*.xcuserstate
|
||||
project.xcworkspace
|
||||
|
||||
# CocoaPods
|
||||
ios/Pods
|
||||
ios/*.xcworkspace
|
||||
|
||||
# Android/IntelliJ
|
||||
#
|
||||
build/
|
||||
.idea
|
||||
.gradle
|
||||
local.properties
|
||||
*.iml
|
||||
|
||||
# node.js
|
||||
#
|
||||
node_modules/
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
|
||||
# BUCK
|
||||
buck-out/
|
||||
\.buckd/
|
||||
*.keystore
|
||||
|
||||
# fastlane
|
||||
#
|
||||
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
|
||||
# screenshots whenever they are needed.
|
||||
# For more information about the recommended setup visit:
|
||||
# https://docs.fastlane.tools/best-practices/source-control/
|
||||
|
||||
*/fastlane/report.xml
|
||||
*/fastlane/Preview.html
|
||||
*/fastlane/screenshots
|
1
examples/video-caching/.watchmanconfig
Normal file
@ -0,0 +1 @@
|
||||
{}
|
48
examples/video-caching/App.ios.js
Normal file
@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Sample React Native App
|
||||
* https://github.com/facebook/react-native
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import React, { Component } from "react";
|
||||
import { StyleSheet, Text, View, Dimensions } from "react-native";
|
||||
import Video from "react-native-video";
|
||||
|
||||
const { height, width } = Dimensions.get("screen");
|
||||
|
||||
type Props = {};
|
||||
export default class App extends Component<Props> {
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Video
|
||||
source={{
|
||||
uri:
|
||||
"https://rawgit.com/mediaelement/mediaelement-files/master/big_buck_bunny.mp4"
|
||||
}}
|
||||
ref={player => {
|
||||
this.player = player;
|
||||
}}
|
||||
onEnd={() => {
|
||||
this.player.seek(0);
|
||||
}}
|
||||
style={{ flex: 1, height, width }}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
backgroundColor: "#F5FCFF"
|
||||
},
|
||||
welcome: {
|
||||
fontSize: 20,
|
||||
textAlign: "center",
|
||||
margin: 10
|
||||
}
|
||||
});
|
33
examples/video-caching/App.js
Normal file
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Sample React Native App
|
||||
* https://github.com/facebook/react-native
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import React, { Component } from "react";
|
||||
import { StyleSheet, Text, View } from "react-native";
|
||||
|
||||
type Props = {};
|
||||
export default class App extends Component<Props> {
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text style={styles.welcome}>Caching is only supported in iOS!</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
backgroundColor: "#F5FCFF"
|
||||
},
|
||||
welcome: {
|
||||
fontSize: 20,
|
||||
textAlign: "center",
|
||||
margin: 10
|
||||
}
|
||||
});
|
24
examples/video-caching/README.md
Normal file
@ -0,0 +1,24 @@
|
||||
# react-native-video caching example (currently only working on iOS)
|
||||
|
||||
# How to verify that caching is working (iOS)
|
||||
|
||||
1. run `./update.sh`
|
||||
2. open `ios/VideoCaching.xcworkspace`
|
||||
3. build and run project in simulator
|
||||
4. after the video is loaded -> disconnect from the internet
|
||||
5. kill the application
|
||||
6. start the application again -> the video is there despite being offline :)
|
||||
|
||||
# How to verify that you can build the project without the caching feature (iOS)
|
||||
|
||||
1. In `ios/Podfile` apply the following changes
|
||||
```diff
|
||||
- pod 'react-native-video/VideoCaching', :path => '../node_modules/react-native-video/react-native-video.podspec'
|
||||
+ pod 'react-native-video', :path => '../node_modules/react-native-video/react-native-video.podspec'
|
||||
```
|
||||
2. run `./update.sh`
|
||||
3. open `ios/VideoCaching.xcworkspace`
|
||||
4. build and run project in simulator
|
||||
5. after the video is loaded -> disconnect from the internet
|
||||
6. kill the application
|
||||
7. start the application again -> the video should not load
|
12
examples/video-caching/__tests__/App.js
Normal file
@ -0,0 +1,12 @@
|
||||
import 'react-native';
|
||||
import React from 'react';
|
||||
import App from '../App';
|
||||
|
||||
// Note: test renderer must be required after react-native.
|
||||
import renderer from 'react-test-renderer';
|
||||
|
||||
it('renders correctly', () => {
|
||||
const tree = renderer.create(
|
||||
<App />
|
||||
);
|
||||
});
|