-
Notifications
You must be signed in to change notification settings - Fork 316
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
Android fullscreen via bridging #38
base: master
Are you sure you want to change the base?
Changes from all commits
5a9f1b9
d8a1edf
582dba1
8198002
bc255de
c9216e1
e42c2d7
28267f5
d8a12a8
fac09c2
833df3e
84ce1a9
39ca8ac
42412a3
e868405
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package com.my.package; | ||
|
||
import android.content.Context; | ||
import android.content.Intent; | ||
|
||
import com.facebook.react.bridge.NativeModule; | ||
import com.facebook.react.bridge.ReactApplicationContext; | ||
import com.facebook.react.bridge.ReactContext; | ||
import com.facebook.react.bridge.ReactContextBaseJavaModule; | ||
import com.facebook.react.bridge.ReactMethod; | ||
|
||
public class BridgeModule extends ReactContextBaseJavaModule{ | ||
public BridgeModule(ReactApplicationContext reactContext) { | ||
super(reactContext); | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
return "BridgeModule"; | ||
} | ||
@ReactMethod | ||
public void showFullscreen(String videoUri) { | ||
Context context = getReactApplicationContext(); | ||
Intent intent = new Intent(context, VideoActivity.class); // mContext got from your overriden constructor | ||
intent.putExtra("VIDEO_URL",videoUri); | ||
getCurrentActivity().startActivity(intent); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package com.my.package; | ||
|
||
|
||
import com.facebook.react.ReactPackage; | ||
import com.facebook.react.bridge.JavaScriptModule; | ||
import com.facebook.react.bridge.NativeModule; | ||
import com.facebook.react.bridge.ReactApplicationContext; | ||
import com.facebook.react.uimanager.ViewManager; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.List; | ||
|
||
public class BridgePackage implements ReactPackage { | ||
|
||
@Override | ||
public List<Class<? extends JavaScriptModule>> createJSModules() { | ||
return Collections.emptyList(); | ||
} | ||
|
||
@Override | ||
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { | ||
return Collections.emptyList(); | ||
} | ||
|
||
@Override | ||
public List<NativeModule> createNativeModules( | ||
ReactApplicationContext reactContext) { | ||
List<NativeModule> modules = new ArrayList<>(); | ||
|
||
modules.add(new BridgeModule(reactContext)); | ||
|
||
return modules; | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package com.my.package; | ||
|
||
import android.app.ProgressDialog; | ||
import android.content.Intent; | ||
import android.content.pm.ActivityInfo; | ||
import android.graphics.PixelFormat; | ||
import android.media.MediaPlayer; | ||
import android.net.Uri; | ||
import android.support.v7.app.AppCompatActivity; | ||
import android.os.Bundle; | ||
import android.util.Log; | ||
import android.widget.MediaController; | ||
import android.widget.Toast; | ||
import android.widget.VideoView; | ||
|
||
public class VideoActivity extends AppCompatActivity { | ||
private String videoPath; | ||
|
||
private static ProgressDialog progressDialog; | ||
VideoView myVideoView; | ||
|
||
@Override | ||
protected void onCreate(Bundle savedInstanceState) { | ||
super.onCreate(savedInstanceState); | ||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE); | ||
setContentView(R.layout.player_fullscreen); | ||
Intent i = getIntent(); | ||
if(i != null){ | ||
myVideoView = (VideoView) findViewById(R.id.videoView); | ||
videoPath = i.getStringExtra("VIDEO_URL"); | ||
progressDialog = ProgressDialog.show(VideoActivity.this, "", "Buffering video...", true); | ||
progressDialog.setCancelable(true); | ||
PlayVideo(); | ||
} | ||
else{ | ||
Toast.makeText(VideoActivity.this, "VideoURL not found", Toast.LENGTH_SHORT).show(); | ||
} | ||
|
||
|
||
} | ||
|
||
private void PlayVideo() { | ||
try { | ||
getWindow().setFormat(PixelFormat.TRANSLUCENT); | ||
MediaController mediaController = new MediaController(VideoActivity.this); | ||
mediaController.setAnchorView(myVideoView); | ||
|
||
Uri video = Uri.parse(videoPath); | ||
myVideoView.setMediaController(mediaController); | ||
myVideoView.setVideoURI(video); | ||
myVideoView.requestFocus(); | ||
myVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { | ||
public void onPrepared(MediaPlayer mp) { | ||
progressDialog.dismiss(); | ||
myVideoView.start(); | ||
} | ||
}); | ||
|
||
|
||
} catch (Exception e) { | ||
progressDialog.dismiss(); | ||
System.out.println("Video Play Error :" + e.toString()); | ||
finish(); | ||
} | ||
|
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
xmlns:app="http://schemas.android.com/apk/res-auto" | ||
xmlns:tools="http://schemas.android.com/tools" | ||
android:layout_width="match_parent" | ||
android:layout_height="match_parent" | ||
tools:context=".VideoActivity"> | ||
|
||
<VideoView | ||
android:id="@+id/videoView" | ||
android:layout_width="fill_parent" | ||
android:layout_height="fill_parent" | ||
android:layout_alignParentTop="true" | ||
android:layout_alignParentBottom="true" | ||
android:layout_alignParentLeft="true" | ||
android:layout_alignParentRight="true" | ||
/> | ||
</RelativeLayout> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,7 @@ | ||
import React, { Component } from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import { Image, Platform, StyleSheet, TouchableOpacity, View, ViewPropTypes } from 'react-native'; | ||
import React, { Component, PropTypes } from 'react'; | ||
import { View, StyleSheet, Image, TouchableOpacity, Platform, NativeModules } from 'react-native'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any specific reasons for changing to use the built-in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. built-in PropTypes are breaking since react does not support them, we should use separate prop-types library. |
||
import Icon from 'react-native-vector-icons/MaterialIcons'; | ||
import Video from 'react-native-video'; // eslint-disable-line | ||
|
||
import Video from 'react-native-video'; | ||
const styles = StyleSheet.create({ | ||
preloadingPlaceholder: { | ||
backgroundColor: 'black', | ||
|
@@ -26,7 +24,7 @@ const styles = StyleSheet.create({ | |
playArrow: { | ||
color: 'white', | ||
}, | ||
video: { | ||
video: Platform.Version >= 24 ? {} : { | ||
backgroundColor: 'black', | ||
}, | ||
controls: { | ||
|
@@ -84,6 +82,9 @@ const styles = StyleSheet.create({ | |
}); | ||
|
||
export default class VideoPlayer extends Component { | ||
|
||
|
||
|
||
constructor(props) { | ||
super(props); | ||
|
||
|
@@ -131,6 +132,14 @@ export default class VideoPlayer extends Component { | |
} | ||
} | ||
|
||
stop() { | ||
//console.log('this in the video', this); | ||
//this.player.seek(0); | ||
this.setState({ | ||
isPlaying: false, | ||
}); | ||
} | ||
|
||
onLayout(event) { | ||
const { width } = event.nativeEvent.layout; | ||
this.setState({ | ||
|
@@ -139,16 +148,15 @@ export default class VideoPlayer extends Component { | |
} | ||
|
||
onStartPress() { | ||
if (this.props.onStart) { | ||
this.props.onStart(); | ||
} | ||
|
||
this.setState({ | ||
isPlaying: true, | ||
isStarted: true, | ||
}); | ||
|
||
this.hideControls(); | ||
if(this.props.onStartPress){ | ||
this.props.onStartPress(this); | ||
}; | ||
} | ||
|
||
onProgress(event) { | ||
|
@@ -172,8 +180,6 @@ export default class VideoPlayer extends Component { | |
this.setState({ isStarted: false }); | ||
} | ||
|
||
this.setState({ progress: 1 }); | ||
|
||
this.player.seek(0); | ||
if (!this.props.loop) { | ||
this.setState({ | ||
|
@@ -192,14 +198,14 @@ export default class VideoPlayer extends Component { | |
} | ||
|
||
onPlayPress() { | ||
if (this.props.onPlayPress) { | ||
this.props.onPlayPress(); | ||
} | ||
|
||
console.log('onPlayPress :: videoComponent') | ||
this.setState({ | ||
isPlaying: !this.state.isPlaying, | ||
}); | ||
this.showControls(); | ||
if(this.props.onPlayPress){ | ||
this.props.onPlayPress(); | ||
}; | ||
} | ||
|
||
onMutePress() { | ||
|
@@ -210,7 +216,15 @@ export default class VideoPlayer extends Component { | |
} | ||
|
||
onToggleFullScreen() { | ||
this.player.presentFullscreenPlayer(); | ||
if(Platform.OS === "android") | ||
{ | ||
var uri = this.props.video.uri; | ||
NativeModules.BridgeModule.showFullscreen(uri); | ||
} | ||
else | ||
{ | ||
this.player.presentFullscreenPlayer(); | ||
} | ||
} | ||
|
||
onSeekBarLayout({ nativeEvent }) { | ||
|
@@ -277,10 +291,6 @@ export default class VideoPlayer extends Component { | |
} | ||
|
||
hideControls() { | ||
if (this.props.onHideControls) { | ||
this.props.onHideControls(); | ||
} | ||
|
||
if (this.props.disableControlsAutoHide) { | ||
return; | ||
} | ||
|
@@ -295,10 +305,6 @@ export default class VideoPlayer extends Component { | |
} | ||
|
||
showControls() { | ||
if (this.props.onShowControls) { | ||
this.props.onShowControls(); | ||
} | ||
|
||
this.setState({ | ||
isControlsVisible: true, | ||
}); | ||
|
@@ -404,15 +410,13 @@ export default class VideoPlayer extends Component { | |
/> | ||
</TouchableOpacity> | ||
)} | ||
{(Platform.OS === 'android' || this.props.disableFullscreen) ? null : ( | ||
<TouchableOpacity onPress={this.onToggleFullScreen} style={customStyles.controlButton}> | ||
<Icon | ||
style={[styles.extraControl, customStyles.controlIcon]} | ||
name="fullscreen" | ||
size={32} | ||
/> | ||
</TouchableOpacity> | ||
)} | ||
<TouchableOpacity onPress={this.onToggleFullScreen} style={customStyles.controlButton}> | ||
<Icon | ||
style={[styles.extraControl, customStyles.controlIcon]} | ||
name="fullscreen" | ||
size={32} | ||
/> | ||
</TouchableOpacity> | ||
</View> | ||
); | ||
} | ||
|
@@ -492,40 +496,35 @@ VideoPlayer.propTypes = { | |
autoplay: PropTypes.bool, | ||
defaultMuted: PropTypes.bool, | ||
muted: PropTypes.bool, | ||
style: ViewPropTypes.style, | ||
style: View.propTypes.style, | ||
controlsTimeout: PropTypes.number, | ||
disableControlsAutoHide: PropTypes.bool, | ||
disableFullscreen: PropTypes.bool, | ||
loop: PropTypes.bool, | ||
resizeMode: Video.propTypes.resizeMode, | ||
hideControlsOnStart: PropTypes.bool, | ||
endWithThumbnail: PropTypes.bool, | ||
customStyles: PropTypes.shape({ | ||
wrapper: ViewPropTypes.style, | ||
wrapper: View.propTypes.style, | ||
video: Video.propTypes.style, | ||
videoWrapper: ViewPropTypes.style, | ||
controls: ViewPropTypes.style, | ||
videoWrapper: View.propTypes.style, | ||
controls: View.propTypes.style, | ||
playControl: TouchableOpacity.propTypes.style, | ||
controlButton: TouchableOpacity.propTypes.style, | ||
controlIcon: Icon.propTypes.style, | ||
playIcon: Icon.propTypes.style, | ||
seekBar: ViewPropTypes.style, | ||
seekBarFullWidth: ViewPropTypes.style, | ||
seekBarProgress: ViewPropTypes.style, | ||
seekBarKnob: ViewPropTypes.style, | ||
seekBarKnobSeeking: ViewPropTypes.style, | ||
seekBarBackground: ViewPropTypes.style, | ||
seekBar: View.propTypes.style, | ||
seekBarFullWidth: View.propTypes.style, | ||
seekBarProgress: View.propTypes.style, | ||
seekBarKnob: View.propTypes.style, | ||
seekBarKnobSeeking: View.propTypes.style, | ||
seekBarBackground: View.propTypes.style, | ||
thumbnail: Image.propTypes.style, | ||
playButton: TouchableOpacity.propTypes.style, | ||
playArrow: Icon.propTypes.style, | ||
}), | ||
onEnd: PropTypes.func, | ||
onProgress: PropTypes.func, | ||
onLoad: PropTypes.func, | ||
onStart: PropTypes.func, | ||
onPlayPress: PropTypes.func, | ||
onHideControls: PropTypes.func, | ||
onShowControls: PropTypes.func, | ||
}; | ||
|
||
VideoPlayer.defaultProps = { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
from RN 0.47.x on the
createJSModules()
method has been removed and thus the@Override
implement here will fail the gradle compilation. Simply remove the@Override
and keep the method call should resolve this issue.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks man!