Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge caching changes into master #1204

Merged
merged 52 commits into from
Aug 28, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
c820a90
Move example to examples dir and rename to basic
n1ru4l Feb 28, 2018
434b2b0
Add submodule for SPTPersistentCache
n1ru4l Feb 28, 2018
125225b
Initialize VideoCaching project
n1ru4l Feb 28, 2018
159dd15
Add simple http server
n1ru4l Feb 28, 2018
8b010f8
'Disable' example for non iOS devices
n1ru4l Feb 28, 2018
30c437f
Update dependencies
n1ru4l Feb 28, 2018
6b2c104
Use ranges
n1ru4l Feb 28, 2018
438aa79
Add cache property; Make playerItemForSource in 'RCTVideoManager.m' a…
n1ru4l Feb 28, 2018
05feefa
Change SPTPersistentCache version to 1.1.1
n1ru4l Mar 1, 2018
a2de590
Add SPTPersistentCache as a dependency
n1ru4l Mar 1, 2018
e65a0b3
Add DVAssetLoaderDelegate as a submodule
n1ru4l Mar 1, 2018
d5e012b
Add DVAssetLoaderDelegate to project
n1ru4l Mar 1, 2018
c926d8b
First iteration implementing video caching
n1ru4l Mar 1, 2018
4b5ac43
Update example
n1ru4l Mar 1, 2018
e918c02
Add some contributing guide
n1ru4l Mar 1, 2018
e71b89d
Fix header search paths
n1ru4l Mar 1, 2018
c0ab21e
Link project with example
n1ru4l Mar 2, 2018
4bf56cd
Remove debug info
n1ru4l Mar 2, 2018
d05b575
Install dependendencies via cocoapods
n1ru4l Mar 4, 2018
4021996
Schedule cache garbage collector
n1ru4l Mar 4, 2018
5281796
Fix error handling
n1ru4l Mar 5, 2018
6cfea3a
Merge branch 'master' into implement-ios-caching
n1ru4l Jul 17, 2018
5d7b296
update example project and fix build errors
n1ru4l Jul 17, 2018
4c76763
remove duplicated code block
n1ru4l Jul 17, 2018
4f386d2
make video cache feature optional
n1ru4l Jul 19, 2018
f0f1883
remove obsolete contributer instructions
n1ru4l Jul 19, 2018
1110793
update changelog
n1ru4l Jul 19, 2018
82edb95
remove cache property
n1ru4l Jul 19, 2018
4cc984d
add instructions for CocoaPods setup
n1ru4l Jul 19, 2018
201f61b
Merge branch 'master' into implement-ios-caching
n1ru4l Jul 19, 2018
2260ae5
Merge remote-tracking branch 'upstream/master' into implement-ios-cac…
n1ru4l Jul 30, 2018
b83f3a5
fix xcode project paths
n1ru4l Jul 31, 2018
685133e
remove cache property
n1ru4l Jul 31, 2018
6b55d8a
update basic sample to newest react-native version
n1ru4l Jul 31, 2018
9f2cb8f
Merge remote-tracking branch 'upstream/master' into implement-ios-cac…
n1ru4l Jul 31, 2018
c9e2ba0
Fix URLs with query strings at the end, e.g. ?size=large
n1ru4l Aug 5, 2018
38ba373
add information about caching restrictions
n1ru4l Aug 6, 2018
8fcdc6e
Merge remote-tracking branch 'upstream/master' into implement-ios-cac…
n1ru4l Aug 6, 2018
8d5f81a
add missing enum
n1ru4l Aug 6, 2018
ca3e49a
Merge pull request #955 from n1ru4l/implement-ios-caching
cobarx Aug 6, 2018
53c5afe
Merge branch 'develop' of https://github.com/react-native-community/r…
cobarx Aug 8, 2018
9d22835
Rework logic for extension detection
cobarx Aug 8, 2018
8084b16
Code style cleanups
cobarx Aug 8, 2018
86d655c
Refactor to move caching code into a single block
cobarx Aug 8, 2018
994da82
Reorganize README to put more links in the table of contents
cobarx Aug 27, 2018
444581d
Merge pull request #1203 from react-native-community/chore/ios-doc-cl…
cobarx Aug 27, 2018
a26dc26
Bypass cache when sideloaded text tracks are specified
cobarx Aug 28, 2018
b6ee8f7
Simplify text track + cache bypass code
cobarx Aug 28, 2018
67a3889
Add debug message when disabling caching due to text tracks
cobarx Aug 28, 2018
152978d
Provide info about caching not working with text tracks
cobarx Aug 28, 2018
b6512e4
Remove old test var
cobarx Aug 28, 2018
03734bb
Merge pull request #1172 from react-native-community/bugfix/ios-cache…
cobarx Aug 28, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,13 @@ local.properties
# node.js
#
node_modules/
npm-debug.log
*.log

# yarn
yarn.lock

# editor workspace settings
.vscode

# BUCK
buck-out/
Expand Down
2 changes: 1 addition & 1 deletion .npmignore
Original file line number Diff line number Diff line change
@@ -1 +1 @@
/example
/examples
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
### Next Version
* Partial support for timed metadata on Android MediaPlayer [#707](https://github.com/react-native-community/react-native-video/pull/707)
* Update to ExoPlayer 2.8.2. Android SDK 26 now required [#1170](https://github.com/react-native-community/react-native-video/pull/1170)
* Support video caching for iOS [#955](https://github.com/react-native-community/react-native-video/pull/955)

### Version 3.2.0
* Basic fullscreen support for Android MediaPlayer [#1138](https://github.com/react-native-community/react-native-video/pull/1138)
Expand Down
66 changes: 50 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ Version 4.0.0 now requires Android SDK 26 or higher to use ExoPlayer. This is th
### 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
Expand All @@ -31,26 +34,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>
Expand Down Expand Up @@ -716,17 +730,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.

Expand Down
22 changes: 22 additions & 0 deletions docs/caching.md
Original file line number Diff line number Diff line change
@@ -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.
17 changes: 0 additions & 17 deletions example/package.json

This file was deleted.

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,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 */
Expand Down Expand Up @@ -349,6 +426,8 @@
children = (
139FDEF41B06529B00C62182 /* libRCTWebSocket.a */,
3DAD3E991DF850E9000B6D8A /* libRCTWebSocket-tvOS.a */,
D1107C5A2111145500073188 /* libfishhook.a */,
D1107C5C2111145500073188 /* libfishhook-tvOS.a */,
);
name = Products;
sourceTree = "<group>";
Expand Down Expand Up @@ -378,6 +457,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>";
Expand Down Expand Up @@ -453,6 +540,7 @@
isa = PBXGroup;
children = (
8C2A0F791E25608300E31596 /* libRCTVideo.a */,
D1107C542111145500073188 /* libRCTVideo.a */,
);
name = Products;
sourceTree = "<group>";
Expand Down Expand Up @@ -738,7 +826,7 @@
5E9157351DD0AC6500FF2AA8 /* libRCTAnimation-tvOS.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = "libRCTAnimation-tvOS.a";
path = libRCTAnimation.a;
remoteRef = 5E9157341DD0AC6500FF2AA8 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
Expand All @@ -763,6 +851,83 @@
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 */
Expand Down Expand Up @@ -797,7 +962,7 @@
);
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";
};
/* End PBXShellScriptBuildPhase section */

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading