Can't pause in react native video - react-native

I want to play an audio file, But it's playing automaticaly and I can't pause That.
How Can I Fix That?
That Must be Paused at the begin
My Code:
import Video from 'react-native-video';
export default class Android extends Component {
constructor(props) {
super(props)
this.state = {
paused: true,
}
}
video: Video;
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
<Text style={styles.instructions}>
To get started, edit index.ios.js
</Text>
<Text style={styles.instructions}>
Press Cmd+R to reload,{'\n'}
Cmd+D or shake for dev menu
</Text>
<Video
ref={(ref: Video) => { this.video = ref }}
source={{ uri: "http://s3.picofile.com/d/7376893331/8b7bc5b4-4b5e-47c4-96dd-b0c13fd18157/Sara_Diba_Delbare_Man.mp3", mainVer: 1, patchVer: 0 }}
paused={this.state.paused}
/>
</View>
);
}
}

There's currently a bug in react-native-video where the pause flag is ignored when the component is first loaded. You have to change pause AFTER the component has loaded.
First, make sure your this.state.pause = false. Then:
<Video
paused={this.state.paused}
onLoad={() => {
this.setState({
paused: true
});
}}
</Video>
Context: https://github.com/react-native-community/react-native-video/issues/494#issuecomment-281853423

Use ref attribute to create a link to the video and using that reference we can able to use video controls on the video component
Try this code,
import React from "react";
class VideoDemo extends React.Component {
getVideo = elem => {
this.video = elem
}
playVideo = () => {
// You can use the play method as normal on your video ref
this.video.play()
};
pauseVideo = () => {
// Pause as well
this.video.pause();
};
render = () => {
return (
<div>
<video
ref={this.getVideo}
src="http://techslides.com/demos/sample-videos/small.mp4"
type="video/mp4"
/>
<div>
<button onClick={this.playVideo}>
Play!
</button>
<button onClick={this.pauseVideo}>
Pause!
</button>
</div>
</div>
);
};
}
export default VideoDemo;

Related

How to use OS video controls for react-native-video?

Is there any way to use the built in iOS/Android video controls for video playback in React Native?
For example, here is what it would look like on iOS
I used expo-av library to do this. You can also use this library in bare project as well. (https://github.com/expo/expo/tree/master/packages/expo-av)
All you need to do to get the native video controls is pass in useNativeControls. Heres there code and example (https://snack.expo.dev/#heytony01/video)
import * as React from 'react';
import { View, StyleSheet, Button } from 'react-native';
import { Video, AVPlaybackStatus } from 'expo-av';
export default function App() {
const video = React.useRef(null);
const [status, setStatus] = React.useState({});
return (
<View style={styles.container}>
<Video
ref={video}
style={styles.video}
source={{
uri: 'http://d23dyxeqlo5psv.cloudfront.net/big_buck_bunny.mp4',
}}
useNativeControls
resizeMode="contain"
isLooping
onPlaybackStatusUpdate={status => setStatus(() => status)}
/>
<View style={styles.buttons}>
<Button
title={status.isPlaying ? 'Pause' : 'Play'}
onPress={() =>
status.isPlaying ? video.current.pauseAsync() : video.current.playAsync()
}
/>
</View>
</View>
);
}

How to play a video with react native video and pause other in flatlist

I am making a video app like tiktok / instagram reel and i have a flatlist as below
All my videos play automatically and i have it set so that its paused on render (at the moment), I am tying to play a video when it is visible on the screen and pause the other vodeos, but it doesn't work i can't seem to see anything online on how i can pause the other videos or possibly just render one video until i scroll but all videos are set to true no matter what i do.
how can i get the video that is visible to play and then pause when user scrolls and then play the other visible video?
I have been at this for 2 days and my head is Fried, any help would be appreciated :(
PostScreen.js
const [state, setState] = useState({
isVisible: false,
})
const videoData [
{
id: 1,
video: videourl
},
{
id: 2,
video: videourl
},
];
const _onViewableItemsChanged = useCallback(({ viewableItems }) => {
if(viewableItems[0]){
if(viewableItems[0].isViewable){
setState({...state, isVisible: true})
}
}
}, []);
const _viewabilityConfig = {
itemVisiblePercentThreshold: 50
}
<FlatList
data={videosData}
decelerationRate={'fast'}
showsVerticalScrollIndicator={false}
snapToInterval={Dimensions.get('window').height}
snapToAlignment={"start"}
initialScrollIndex={0}
disableIntervalMomentum
onViewableItemsChanged={_onViewableItemsChanged}
viewabilityConfig={_viewabilityConfig}
renderItem={ ({ item }) => (
<View>
<VideoPlayerComponent data={item} />
</View>
)}
/>
VideoPlayerComponent
const [data] = useState(props.data)
const [paused, setPaused] = useState(true);
return(
<View>
<TouchableWithoutFeedback
onPress={() => setPaused(!paused)}
>
<View>
<Video
style={styles.fullScreen}
source={data.video}
resizeMode="cover"
paused={paused}
repeat
/>
{
paused ? (
<View style={styles.pausedIcon}>
<Icon name="play" type="ionicon" color="white" size={68} />
</View>
): null
}
</View>
</TouchableWithoutFeedback>
</View>
)
friends I have solved the issue for my react native video project.
the issue was that all videos are playing in Flatlist but we need to play only singal video on the current viewport and pause the rest.
just do the following steps to solve all videos playing issue
1: npm install #svanboxel/visibility-sensor-react-native
2: import VisibilitySensor from '#svanboxel/visibility-sensor-react-native'
3: do this
import VisibilitySensor from '#svanboxel/visibility-sensor-react-native'
const video = ()=>{
const [paused, setpaused] = useState(true)
return(
<VisibilitySensor onChange={(isVisible)=>{
return(
console.log(isVisible),
isVisible?setpaused(false):setpaused(true)
)
}
}
>
<View>
<Video
source={{uri: 'https://d8vywknz0hvjw.cloudfront.net/fitenium-media-prod/videos/45fee890-a74f-11ea-8725-311975ea9616/proccessed_720.mp4'}}
style={styles.video}
onError={(e) => console.log(e)}
resizeMode={'cover'}
repeat={true}
paused={paused}
/>
</View>
</VisibilitySensor>
)
}
4: I have just given you the basic structure you can add styling stuff as your requirements.
5: remember that always add your view/video elements between the VisibilitySensor tags, otherwise it will not work.
6: this code will give you true when your video component will render in flatlist viewport and remainig will give you false. with this you can manage play/pause state of video element.
thanks...
I managed to use the inviewport library
using this snippiti managed to convert to functional class
in my functional class i just passed a flatlist as it was.
<FlatList
data={videos}
decelerationRate={'fast'}
showsVerticalScrollIndicator={false}
snapToInterval={Dimensions.get('window').height}
snapToAlignment={"start"}
initialScrollIndex={0}
disableIntervalMomentum
renderItem={ ({ item }) => (
<View>
<VideoPlayerComponent data={item}/>
</View>
)}
/>
then in my VideoPlayerComponent i do this
const video = useRef(ref)
const playVideo = () => {
if(video) {
setPaused(false);
}
}
const pauseVideo = () => {
if(video) {
setPaused(true);
}
}
const handlePlaying = (isVisible) => {
isVisible ? playVideo() : pauseVideo();
}
return (
<View>
<Video
ref={ ref => {video.current = ref}}
style={styles.fullScreen}
source={data.video}
paused={paused}
resizeMode="cover"
repeat
/>
</View>
)
This will play the video that is in. view and will pause the other based on the ref passed to it.
Hope this helps anyone stuck as i was stuck for a few days :)

React Native Expo Video av-expo -- Directly play as fullscreen

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)}
/>

React Native Expo Video av-expo

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

How to I send a message from the WebView to React Native?

I’ve successfully managed to send a message from React Native (RN) to a WebView.
What I’m struggling with, is getting the message back from the WebView to RN. There’s no errors showing - it’s just that the message never gets through.
Here is the code which I’m using:
React Native code
<WebView
source={Platform.OS === 'ios' ?
{ uri: RNFS.LibraryDirectoryPath + "/offlineplayer/index.html" } :
{ uri: 'file:///android_asset/offlineplayer/index.html' }
}
ref={(webView) => this.webView = webView}
originWhitelist={["*"]}
javaScriptEnabled={true}
domStorageEnabled={true}
startInLoadingState={true}
useWebKit={true}
//scrollEnabled={false}
onLoad={() => this.sendPostMessage()}
allowFileAccess={true}
allowUniversalAccessFromFileURLs={true}
allowFileAccessFromFileURLs={true}
allowingReadAccessToURL={RNFS.LibraryDirectoryPath}
onMessage={this.onMessage}
/>
onMessage(event) {
alert(event.nativeEvent.data);
}
WebView Code
window.postMessage("Post message from web", "*");
The only way to communicate the web with react native is by using window.ReactNativeWebView.postMessage and the onMessage prop.
but window.ReactNativeWebView.postMessage only accepts one argument, which must be a string.
So change window.postMessage to window.ReactNativeWebView.postMessage to fix your issue.
For more information check this sample code
import React, { Component } from 'react';
import { View } from 'react-native';
import { WebView } from 'react-native-webview';
export default class App extends Component {
render() {
const html = `
<html>
<head></head>
<body>
<script>
setTimeout(function () {
window.ReactNativeWebView.postMessage("Hello!")
}, 2000)
</script>
</body>
</html>
`;
return (
<View style={{ flex: 1 }}>
<WebView
source={{ html }}
onMessage={event => {
alert(event.nativeEvent.data);
}}
/>
</View>
);
}
}
Hope this helps you. Feel free for doubts.