I am Developing Sample Application, in this Application, When i was start or run the application,Splash Video Comes every time when i was run the application Or reload the Application .But, I don't need to be Splash Video every time.
this is my code
class SplashPage extends Component {
componentWillMount () {
var navigator = this.props.navigator;
setTimeout (() => {
navigator.replace({
component: LoginScreen,
// <-- This is the View you go to
});
}, 8700); //<-- Time until it jumps to "MainView"
}
render () {
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<Video source={require('./images/splashVideo.mp4')}
rate={1.0}
volume={1.0}
muted={false}
paused={false}
resizeMode="cover"
repeat={false}
onError={this.videoError}
style={styles.backgroundVideo} />
<View>{StatusBar.setBackgroundColor('black', true)}</View>
</View>
);
}
}
Thanks in Advance
Yes I got it, This either Splash Screen/ Video no need to Every time.
Just you will be add in this lines in MainActivity.java file Add this lines.
#Override
public void invokeDefaultOnBackPressed() {
moveTaskToBack(true);
}
Related
I'm working on a game using Expo/React Native. I need to play back sound effects with as low latency as possible. For button presses and such.
For now I've tried it using expo-av. It works, but the latency is too high. Below is my implementation (trying to only load audio once, and then replay it).
function DetailsScreen() {
const [sound, setSound] = useState<Audio.Sound>();
async function playSound() {
if (!sound) return;
await sound.replayAsync();
}
useEffect(() => {
const loadSound = async () => {
const { sound } = await Audio.Sound.createAsync(
require('assets/sounds/Tink.aiff')
);
setSound(sound);
};
loadSound();
return sound
? () => {
sound.unloadAsync();
}
: undefined;
}, [sound, setSound]);
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
<Button title="Play sound" onPress={playSound} />
</View>
);
}
When I develop natively for iOS I've used the AudioServicesPlaySystemSound API to play sound effects with very low latency. Is there any wrapper for this API for React Native? Or other ways to reduce latency?
I wanted to ask what would be the best way to handle loading for videos on Expo / React Native.
Expo has good documentation on the Video and AV components to handle video / audio:
https://docs.expo.io/versions/latest/sdk/video/
https://docs.expo.io/versions/latest/sdk/av/
I've tried two things so far: '
Using posterSource in a Video component. The problem here is that the poster image doesn't format properly.
This is what my Video component looks like:
const videoStyle = { width: '100%', height: '100%', display: display};
return (
<Video
ref={playbackObject}
source={{uri: source}}
posterSource={require('path/to/file')}
rate={1.0}
volume={1.0}
isMuted={isMuted}
resizeMode="cover"
usePoster={true}
shouldPlay={shouldPlay}
onPlaybackStatusUpdate={_onPlaybackStatusUpdate}
progressUpdateIntervalMillis={50}
isLooping
style={videoStyle}
posterStyle={videoStyle}
>
</Video>
)
I’ve also tried using playbackStatus to see if the video is loaded or buffering and have an activity indicator when the video is loaded or buffering, but because I use states, there is some lag.
My implementation for (2) looks like this:
const [loaded, setLoaded] = useState(false);
const _onPlaybackStatusUpdate = playbackStatus => {
if(playbackStatus.isBuffering){
if(loaded){
setLoaded(false);
}
} else {
if(!loaded){
setLoaded(true);
}
}
}
If loaded = true, we do not show an activity indicator. Else, we do show an activity indicator. The main problem here is there is a lag, which is not great UI.
So with that in mind, what would be people’s recommendation of handling loading for videos? Thanks!!
What you can do is to render an <ActivityIndicator /> as background and when it finishes loading the asset, it will get behind the video (or you could just check if the asset was loaded or not -> optionally rendering it inside <Video />.
<Video
ref={handleVideoRef}
>
<ActivityIndicator size="large" />
</Video>
const handleVideoRef = async component => {
const playbackObject = component;
if (playbackObject) {
await playbackObject.loadAsync(
{ uri: currentVideoURI },
);
}
};
here's my solution for that :
Video component has onLoadStart and onReadyForDisplay props, which indicate when the loading starts and when it's finished.
So we could create a custom component, which would support loading indicator using the Video component imported from expo. So in the end, this would looksomething like this :
import React, {useState} from "react";
import { ActivityIndicator } from "react-native";
import { Video } from "expo-av";
const AppVideo = ({style, ...rest}) => {
return (
<View style={style}>
{isPreloading &&
<ActivityIndicator
animating
color={"gray"}
size="large"
style={{ flex: 1, position:"absolute", top:"50%", left:"45%" }}
/>
}
<Video
{...rest}
onLoadStart={() => setIsPreloading(true)}
useNativeControls
onReadyForDisplay={() => setIsPreloading(false)}
resizeMode="contain"
isLooping
/>
</View>
);
}
export default AppVideo;
I'm trying to do this by react-native using the av-expo video.
What I'm trying to do is to launch the video directly in full screen without going through the "Video" stack (without the double loading of the MediaPlayerScreen stack + the native fullScreen stack).
If the user mutes the full screen by the native fullScreen output button, then we go back directly to a stack
The idea is to use only the native fullscreen stack to display the video. Is this possible?
I don't know if I'm clear, if it can help to understand, here is the code of my MediaPlayerScreen component
export class MediaPlayerScreen extends Component {
static navigationOptions = {
//header: null,
headerTitle: '',
headerTransparent: false,
headerTintColor: 'white',
}
constructor(props) {
super(props)
this.AG = AG.instance
this.filePath =
this.AG.getFilePath() + props.navigation.state.params.file
this.windowWidth = Dimensions.get('window').width
this.windowHeight = Dimensions.get('window').height
}
//
onPlaybackStatusUpdate = (playbackStatus) => {
if (playbackStatus.didJustFinish) {
this.props.navigation.goBack()
}
}
//
_handleVideoRef = async (component) => {
const playbackObject = component
if (playbackObject) {
await playbackObject.loadAsync({
uri: this.filePath,
shouldPlay: false,
posterSource: this.poster,
})
// todo: Trigger fullScreen without videoStack loading
//playbackObject.presentFullscreenPlayer();
playbackObject.playAsync()
//playbackObject.setOnPlaybackStatusUpdate(this.onPlaybackStatusUpdate);
}
}
componentDidMount() {
ScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.LANDSCAPE)
}
componentWillUnmount() {
//playbackObject.dismissFullscreenPlayer();
//this.props.navigation.goBack();
ScreenOrientation.lockAsync(
ScreenOrientation.OrientationLock.PORTRAIT_UP
)
}
onFullscreenUpdate = ({ fullscreenUpdate, status }) => {
console.log(fullscreenUpdate, status)
switch (fullscreenUpdate) {
case Video.FULLSCREEN_UPDATE_PLAYER_WILL_PRESENT:
console.log(' the fullscreen player is about to present')
break
case Video.FULLSCREEN_UPDATE_PLAYER_DID_PRESENT:
console.log('the fullscreen player just finished presenting')
break
case Video.FULLSCREEN_UPDATE_PLAYER_WILL_DISMISS:
console.log('the fullscreen player is about to dismiss')
break
case Video.FULLSCREEN_UPDATE_PLAYER_DID_DISMISS:
console.log('the fullscreen player just finished dismissing')
}
}
render() {
return (
<SafeAreaView style={styles.container}>
<Video
ref={this._handleVideoRef}
useNativeControls
rate={1.0}
resizeMode="contain"
onPlaybackStatusUpdate={(playbackStatus) =>
this.onPlaybackStatusUpdate(playbackStatus)
}
onFullscreenUpdate={this.onFullscreenUpdate}
style={{
width: this.windowHeight,
height: this.windowWidth,
}}
/>
</SafeAreaView>
)
}
}
Thanks for your help,
Meums/
hey if I am not getting you wrong you want to load the player fullscreen by default.you can follow this approach:
const videoRef = useRef(null);
<Video
ref={videoRef}
useNativeControls={false}
style={styles.container}
isLooping
source={{
uri: videoUri,
}}
onLoad={()=>{
videoRef?.current?.presentFullscreenPlayer();
}
resizeMode="contain"
onPlaybackStatusUpdate={(status) => setStatus(() => status)}
/>
I'm trying to do this in react native using av-expo.
When the button is pressed, a video component is rendered in fullscreen mode, portrait orientation.
When exiting from fullscreen, the video component is hidden.
I'm not able to:
show it in fullscreen mode
detect the exiting event from the fullscreen mode.
function showVideo(){
<Video
source={{ uri:'http://d23dyxeqlo5psv.cloudfront.net/big_buck_bunny.mp4' }}
resizeMode="cover"
useNativeControls
style={{ width: 300, height: 300 }}/>
}
export default function App(){
const[state,setState]=useState(0)
return(
<View>
{state ? showVideo() : null}
<Button onPress={=>(setState(1)}/>
<View>
)
}
Would anyone please help me?
Since you use av-expo; there are FullScreen APIs for you.
The following methods are available on the component's ref:
videoRef.presentFullscreenPlayer(); use this to present Video in the fullscreen mode.
videoRef.dismissFullscreenPlayer()
and use onPlaybackStatusUpdate, a function to be called regularly with the onFullscreenUpdate, a function to be called when the state of the native iOS fullscreen view changes (controlled via the presentFullscreenPlayer() and dismissFullscreenPlayer() methods on the Video's ref.
export default class App extends React. Component{
_videoRef;
showVideoInFullscreen = async () => {
// PlaybackStatus https://docs.expo.io/versions/latest/sdk/av/
const status = await this._videoRef.presentFullscreenPlayer();
console.log(status)
}
dismissVideoFromFullscreen = async () => {
const status = await this._videoRef.dismissFullscreenPlayer();
console.log(status);
}
onFullscreenUpdate = ({fullscreenUpdate, status}) => {
console.log(fullscreenUpdate, status)
switch (fullscreenUpdate) {
case Video.FULLSCREEN_UPDATE_PLAYER_WILL_PRESENT:
console.log(' the fullscreen player is about to present');
break;
case Video.FULLSCREEN_UPDATE_PLAYER_DID_PRESENT:
console.log('the fullscreen player just finished presenting');
break;
case Video.FULLSCREEN_UPDATE_PLAYER_WILL_DISMISS:
console.log('the fullscreen player is about to dismiss');
break;
case Video.FULLSCREEN_UPDATE_PLAYER_DID_DISMISS:
console.log('the fullscreen player just finished dismissing');
}
}
render () {
return (
<View style={styles.container}>
<Video
ref={(ref) => (this._videoRef = ref)}
source={{ uri: 'http://d23dyxeqlo5psv.cloudfront.net/big_buck_bunny.mp4' }}
resizeMode="cover"
useNativeControls
onFullscreenUpdate={this.onFullscreenUpdate}
style={{ width: 300, height: 300 }}
/>
<Button
title={'show video'}
onPress={() => {
this.showVideoInFullscreen();
}}
/>
</View>
);
}
}
output
the fullscreen player is about to present
the fullscreen player just finished presenting
the fullscreen player is about to dismiss
the fullscreen player just finished dismissing
I am trying to display something fetched via graphql in my react-native was-amplify mobile app. I can't figure out how to pass that fetched data to my render method. Here's the source code. I need to be able to show the contents of the singletour object inside render. React throws an error when I try to reference this.props.singletour inside the render method. Another thing I can't figure out is how to pass the parameter received by navigation inside render to the GetTournament graphql query. Ideally I want the id: inside GetTournament to contain navigation.getParam('itemId', 'NO-ID') and not the hardcoded id. Again, react throws an error when I access this parameter inside the async method call...ANY help would be greatly appreciated!!
class DetailsScreen extends React.Component {
async componentDidMount() {
try {
const graphqldata = await API.graphql(graphqlOperation(GetTournament, { id: "4e00bfe4-6348-47e7-9231-a8b2e722c990" }))
console.log('graphqldata:', graphqldata)
this.setState({ singletour: graphqldata.data.getTournament })
console.log('singletour:', this.state.singletour)
} catch (err) {
console.log('error: ', err)
}
}
render() {
/* 2. Get the param, provide a fallback value if not available */
const { navigation } = this.props;
const itemId = navigation.getParam('itemId', 'NO-ID');
const otherParam = navigation.getParam('otherParam', 'some default value');
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
<Text>itemId: {JSON.stringify(itemId)}</Text>
<Text>otherParam: {JSON.stringify(otherParam)}</Text>
<Button
title="Go to Home"
onPress={() => this.props.navigation.navigate('Home')}
/>
<Button
title="Go back"
onPress={() => this.props.navigation.goBack()}
/>
</View>
);
}
}
I think I know what you are trying to do, and it can be achieved with a refactor of your code.
This is what I would do:
Capture your navigation parameters in the constructor of your component and save them to state.
Set up an initial value for singleTour in state. Set a value for loaded in state. The loaded value will allow us to determine whether the data has come back successfully or not.
Refactor your componentDidMount so that it uses the itemId that is now stored in the state.
Refactor your console.log that checks whether you have set the state, as that is not being performed correctly.
In the render pull the values from state and handle wether the data has been loaded or not. You may wish to show some loading screen or not want to handle it at all.
Here is the refactor:
class DetailsScreen extends React.Component {
constructor (props) {
super(props);
// capture the values that you have passed via your navigation in the constructor
const { navigation } = props;
const itemId = navigation.getParam('itemId', 'NO-ID');
const otherParam = navigation.getParam('otherParam', 'some default value');
this.state = {
itemId: itemId,
otherParam: otherParam,
loaded: false,
singletour: [] // you don't state what singletour is but you should set a default value here
};
}
async componentDidMount () {
try {
// we can now use the state value for itemId as we captured it in the constructor of the component
const graphqldata = await API.graphql(graphqlOperation(GetTournament, { id: this.state.itemId }));
console.log('graphqldata:', graphqldata);
// this is a bad way to access state after it has been set,
// state is asynchronous and takes time to set.
// You would need to access set by using the callback method
// this.setState({ singletour: graphqldata.data.getTournament });
// console.log('singletour:', this.state.singletour); // <- you should never do this after you setState
// this is how you should access state after you have set it
// this will guarantee that the state has been set before the
// console.log is called, so it should show the correct value of state
this.setState({
singletour: graphqldata.data.getTournament,
loaded: true // we are going to use the loaded value to handle our render
}, () => console.log('singletour:', this.state.singletour));
} catch (err) {
console.log('error: ', err);
// you may want to show an error message on the screen.
}
}
render () {
// access the passed parameters from state
const { itemId, otherParam, loaded, singletour } = this.state;
if (loaded) {
// if once the data is loaded we can show screen
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
<Text>itemId: {JSON.stringify(itemId)}</Text>
<Text>otherParam: {JSON.stringify(otherParam)}</Text>
<Text>singletour: {JSON.stringify(singletour)}</Text>
<Button
title="Go to Home"
onPress={() => this.props.navigation.navigate('Home')}
/>
<Button
title="Go back"
onPress={() => this.props.navigation.goBack()}
/>
</View>
);
} else {
// while we are waiting for the data to load we could show a placeholder screen
// or we could show null. The choice is yours.
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Data not loaded</Text>
</View>
);
}
}
}
Note that componentDidMount get called after the first render occurs, this is why we have the loaded value in state. By using loaded it allows us to handle what is presented to the user rather than presenting a screen where the data hasn't finished loading.
This is clearly one possible refactor of your code. There are many other ways that it could be refactored.
Here are some great articles on setting state
https://medium.learnreact.com/setstate-is-asynchronous-52ead919a3f0
https://medium.learnreact.com/setstate-takes-a-callback-1f71ad5d2296
https://medium.learnreact.com/setstate-takes-a-function-56eb940f84b6