ExoPlayer (#426)
This commit is contained in:
committed by
Matt Apperson
parent
cd53e389a0
commit
9a936c9e8f
@@ -2,7 +2,20 @@
|
||||
; We fork some components by platform
|
||||
.*/*[.]android.js
|
||||
|
||||
; Ignore "BUCK" generated dirs
|
||||
# We fork some components by platform.
|
||||
.*/*[.]android.js
|
||||
|
||||
# Ignore templates with `@flow` in header
|
||||
.*/local-cli/generator.*
|
||||
|
||||
# Ignore malformed json
|
||||
.*/node_modules/y18n/test/.*\.json
|
||||
|
||||
# Ignore the website subdir
|
||||
<PROJECT_ROOT>/website/.*
|
||||
|
||||
# Ignore BUCK generated dirs
|
||||
|
||||
<PROJECT_ROOT>/\.buckd/
|
||||
|
||||
; Ignore unexpected extra "@providesModule"
|
||||
@@ -41,4 +54,5 @@ suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
|
||||
unsafe.enable_getters_and_setters=true
|
||||
|
||||
[version]
|
||||
|
||||
^0.36.0
|
||||
|
@@ -106,6 +106,7 @@ android {
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
signingConfig signingConfigs.debug
|
||||
minifyEnabled enableProguardInReleaseBuilds
|
||||
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
|
||||
}
|
||||
@@ -126,10 +127,10 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':react-native-video')
|
||||
compile fileTree(dir: "libs", include: ["*.jar"])
|
||||
compile "com.android.support:appcompat-v7:23.0.1"
|
||||
compile "com.facebook.react:react-native:+" // From node_modules
|
||||
compile project(':react-native-video')
|
||||
// compile project(':react-native-video-exoplayer') // uncomment to use exoplayer
|
||||
}
|
||||
|
||||
// Run this once to be able to run the application with BUCK
|
||||
|
@@ -1,11 +1,9 @@
|
||||
package com.videoplayer;
|
||||
|
||||
import android.app.Application;
|
||||
import android.util.Log;
|
||||
|
||||
import com.facebook.react.ReactApplication;
|
||||
import com.brentvatne.react.ReactVideoPackage;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.ReactApplication;
|
||||
import com.facebook.react.ReactNativeHost;
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.shell.MainReactPackage;
|
||||
@@ -16,13 +14,23 @@ import java.util.List;
|
||||
|
||||
public class MainApplication extends Application implements ReactApplication {
|
||||
|
||||
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
|
||||
@Override
|
||||
protected boolean getUseDeveloperSupport() {
|
||||
return BuildConfig.DEBUG;
|
||||
}
|
||||
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
|
||||
@Override
|
||||
protected boolean getUseDeveloperSupport() {
|
||||
return BuildConfig.DEBUG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<ReactPackage> getPackages() {
|
||||
return Arrays.asList(
|
||||
new MainReactPackage(),
|
||||
new ReactVideoPackage()
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
|
||||
protected List<ReactPackage> getPackages() {
|
||||
return Arrays.<ReactPackage>asList(
|
||||
new MainReactPackage(),
|
||||
|
@@ -5,7 +5,7 @@ buildscript {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:1.3.1'
|
||||
classpath 'com.android.tools.build:gradle:2.2.3'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
@@ -1,5 +1,6 @@
|
||||
#Sat Oct 08 18:53:26 BST 2016
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
|
||||
|
@@ -1,5 +1,12 @@
|
||||
rootProject.name = 'VideoPlayer'
|
||||
|
||||
include ':app'
|
||||
include ':react-native-video'
|
||||
include ':app',
|
||||
':react-native-video',
|
||||
':react-native-video-exoplayer'
|
||||
|
||||
// Quick Local Development
|
||||
//project(':react-native-video').projectDir = new File(rootProject.projectDir, '../../android')
|
||||
//project(':react-native-video-exoplayer').projectDir = new File(rootProject.projectDir, '../../android-exoplayer')
|
||||
|
||||
project(':react-native-video').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-video/android')
|
||||
project(':react-native-video-exoplayer').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-video/android-exoplayer')
|
||||
|
@@ -15,11 +15,6 @@ import {
|
||||
import Video from 'react-native-video';
|
||||
|
||||
class VideoPlayer extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.onLoad = this.onLoad.bind(this);
|
||||
this.onProgress = this.onProgress.bind(this);
|
||||
}
|
||||
|
||||
state = {
|
||||
rate: 1,
|
||||
@@ -28,42 +23,57 @@ class VideoPlayer extends Component {
|
||||
resizeMode: 'contain',
|
||||
duration: 0.0,
|
||||
currentTime: 0.0,
|
||||
paused: true,
|
||||
};
|
||||
|
||||
onLoad(data) {
|
||||
this.setState({duration: data.duration});
|
||||
}
|
||||
video: Video;
|
||||
|
||||
onProgress(data) {
|
||||
this.setState({currentTime: data.currentTime});
|
||||
}
|
||||
onLoad = (data) => {
|
||||
this.setState({ duration: data.duration });
|
||||
};
|
||||
|
||||
onProgress = (data) => {
|
||||
this.setState({ currentTime: data.currentTime });
|
||||
};
|
||||
|
||||
onEnd = () => {
|
||||
this.setState({ paused: true })
|
||||
this.video.seek(0)
|
||||
};
|
||||
|
||||
onAudioBecomingNoisy = () => {
|
||||
this.setState({ paused: true })
|
||||
};
|
||||
|
||||
onAudioFocusChanged = (event: { hasAudioFocus: boolean }) => {
|
||||
this.setState({ paused: !event.hasAudioFocus })
|
||||
};
|
||||
|
||||
getCurrentTimePercentage() {
|
||||
if (this.state.currentTime > 0) {
|
||||
return parseFloat(this.state.currentTime) / parseFloat(this.state.duration);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
renderRateControl(rate) {
|
||||
const isSelected = (this.state.rate == rate);
|
||||
const isSelected = (this.state.rate === rate);
|
||||
|
||||
return (
|
||||
<TouchableOpacity onPress={() => { this.setState({rate: rate}) }}>
|
||||
<Text style={[styles.controlOption, {fontWeight: isSelected ? "bold" : "normal"}]}>
|
||||
<TouchableOpacity onPress={() => { this.setState({ rate }) }}>
|
||||
<Text style={[styles.controlOption, { fontWeight: isSelected ? 'bold' : 'normal' }]}>
|
||||
{rate}x
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
renderResizeModeControl(resizeMode) {
|
||||
const isSelected = (this.state.resizeMode == resizeMode);
|
||||
const isSelected = (this.state.resizeMode === resizeMode);
|
||||
|
||||
return (
|
||||
<TouchableOpacity onPress={() => { this.setState({resizeMode: resizeMode}) }}>
|
||||
<Text style={[styles.controlOption, {fontWeight: isSelected ? "bold" : "normal"}]}>
|
||||
<TouchableOpacity onPress={() => { this.setState({ resizeMode }) }}>
|
||||
<Text style={[styles.controlOption, { fontWeight: isSelected ? 'bold' : 'normal' }]}>
|
||||
{resizeMode}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
@@ -71,11 +81,11 @@ class VideoPlayer extends Component {
|
||||
}
|
||||
|
||||
renderVolumeControl(volume) {
|
||||
const isSelected = (this.state.volume == volume);
|
||||
const isSelected = (this.state.volume === volume);
|
||||
|
||||
return (
|
||||
<TouchableOpacity onPress={() => { this.setState({volume: volume}) }}>
|
||||
<Text style={[styles.controlOption, {fontWeight: isSelected ? "bold" : "normal"}]}>
|
||||
<TouchableOpacity onPress={() => { this.setState({ volume }) }}>
|
||||
<Text style={[styles.controlOption, { fontWeight: isSelected ? 'bold' : 'normal' }]}>
|
||||
{volume * 100}%
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
@@ -88,18 +98,29 @@ class VideoPlayer extends Component {
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<TouchableOpacity style={styles.fullScreen} onPress={() => {this.setState({paused: !this.state.paused})}}>
|
||||
<Video source={{uri: "broadchurch"}}
|
||||
style={styles.fullScreen}
|
||||
rate={this.state.rate}
|
||||
paused={this.state.paused}
|
||||
volume={this.state.volume}
|
||||
muted={this.state.muted}
|
||||
resizeMode={this.state.resizeMode}
|
||||
onLoad={this.onLoad}
|
||||
onProgress={this.onProgress}
|
||||
onEnd={() => { console.log('Done!') }}
|
||||
repeat={true} />
|
||||
<TouchableOpacity
|
||||
style={styles.fullScreen}
|
||||
onPress={() => this.setState({ paused: !this.state.paused })}
|
||||
>
|
||||
<Video
|
||||
ref={(ref: Video) => { this.video = ref }}
|
||||
/* For ExoPlayer */
|
||||
/* source={require('./broadchurch.mp4')} */
|
||||
/* source={{ uri: 'http://www.youtube.com/api/manifest/dash/id/bf5bb2419360daf1/source/youtube?as=fmp4_audio_clear,fmp4_sd_hd_clear&sparams=ip,ipbits,expire,source,id,as&ip=0.0.0.0&ipbits=0&expire=19000000000&signature=51AF5F39AB0CEC3E5497CD9C900EBFEAECCCB5C7.8506521BFC350652163895D4C26DEE124209AA9E&key=ik0', type: 'mpd' }} */
|
||||
source={{ uri: 'broadchurch', type: 'mp4' }}
|
||||
style={styles.fullScreen}
|
||||
rate={this.state.rate}
|
||||
paused={this.state.paused}
|
||||
volume={this.state.volume}
|
||||
muted={this.state.muted}
|
||||
resizeMode={this.state.resizeMode}
|
||||
onLoad={this.onLoad}
|
||||
onProgress={this.onProgress}
|
||||
onEnd={this.onEnd}
|
||||
onAudioBecomingNoisy={this.onAudioBecomingNoisy}
|
||||
onAudioFocusChanged={this.onAudioFocusChanged}
|
||||
repeat={false}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
|
||||
<View style={styles.controls}>
|
||||
@@ -127,8 +148,8 @@ class VideoPlayer extends Component {
|
||||
|
||||
<View style={styles.trackingControls}>
|
||||
<View style={styles.progress}>
|
||||
<View style={[styles.innerProgressCompleted, {flex: flexCompleted}]} />
|
||||
<View style={[styles.innerProgressRemaining, {flex: flexRemaining}]} />
|
||||
<View style={[styles.innerProgressCompleted, { flex: flexCompleted }]} />
|
||||
<View style={[styles.innerProgressRemaining, { flex: flexRemaining }]} />
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
@@ -153,7 +174,7 @@ const styles = StyleSheet.create({
|
||||
right: 0,
|
||||
},
|
||||
controls: {
|
||||
backgroundColor: "transparent",
|
||||
backgroundColor: 'transparent',
|
||||
borderRadius: 5,
|
||||
position: 'absolute',
|
||||
bottom: 20,
|
||||
@@ -200,7 +221,7 @@ const styles = StyleSheet.create({
|
||||
controlOption: {
|
||||
alignSelf: 'center',
|
||||
fontSize: 11,
|
||||
color: "white",
|
||||
color: 'white',
|
||||
paddingLeft: 2,
|
||||
paddingRight: 2,
|
||||
lineHeight: 12,
|
||||
|
@@ -19,6 +19,7 @@ class VideoPlayer extends Component {
|
||||
super(props);
|
||||
this.onLoad = this.onLoad.bind(this);
|
||||
this.onProgress = this.onProgress.bind(this);
|
||||
this.onBuffer = this.onBuffer.bind(this);
|
||||
}
|
||||
state = {
|
||||
rate: 1,
|
||||
@@ -29,7 +30,8 @@ class VideoPlayer extends Component {
|
||||
currentTime: 0.0,
|
||||
controls: false,
|
||||
paused: true,
|
||||
skin: 'custom'
|
||||
skin: 'custom',
|
||||
isBuffering: false,
|
||||
};
|
||||
|
||||
onLoad(data) {
|
||||
@@ -41,6 +43,10 @@ class VideoPlayer extends Component {
|
||||
this.setState({currentTime: data.currentTime});
|
||||
}
|
||||
|
||||
onBuffer({ isBuffering }: { isBuffering: boolean }) {
|
||||
this.setState({ isBuffering });
|
||||
}
|
||||
|
||||
getCurrentTimePercentage() {
|
||||
if (this.state.currentTime > 0) {
|
||||
return parseFloat(this.state.currentTime) / parseFloat(this.state.duration);
|
||||
@@ -116,6 +122,7 @@ class VideoPlayer extends Component {
|
||||
muted={this.state.muted}
|
||||
resizeMode={this.state.resizeMode}
|
||||
onLoad={this.onLoad}
|
||||
onBuffer={this.onBuffer}
|
||||
onProgress={this.onProgress}
|
||||
onEnd={() => { AlertIOS.alert('Done!') }}
|
||||
repeat={true}
|
||||
@@ -175,6 +182,7 @@ class VideoPlayer extends Component {
|
||||
muted={this.state.muted}
|
||||
resizeMode={this.state.resizeMode}
|
||||
onLoad={this.onLoad}
|
||||
onBuffer={this.onBuffer}
|
||||
onProgress={this.onProgress}
|
||||
onEnd={() => { AlertIOS.alert('Done!') }}
|
||||
repeat={true}
|
||||
|
@@ -802,6 +802,7 @@
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "export NODE_BINARY=node\n../node_modules/react-native/packager/react-native-xcode.sh";
|
||||
showEnvVarsInLog = 1;
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
@@ -881,8 +882,10 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEAD_CODE_STRIPPING = NO;
|
||||
|
||||
INFOPLIST_FILE = VideoPlayer/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -898,8 +901,10 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
|
||||
INFOPLIST_FILE = VideoPlayer/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -979,6 +984,7 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
|
@@ -6,12 +6,14 @@
|
||||
"start": "node_modules/react-native/packager/packager.sh"
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
"react": "15.4.2",
|
||||
"react-native": "^0.40.0",
|
||||
|
||||
"react-native-video": "file:../",
|
||||
"react-native-windows": "^0.33.4"
|
||||
"react-native-windows": "~0.38.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"rnpm-plugin-windows": "^0.2.3"
|
||||
"rnpm-plugin-windows": "~0.2.3"
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user