Anyone knows how to only play the first few seconds, and repeat it in a react-native video?
I have a profile page which displays all the videos of the user. Currently its playing the whole video but i only want the first few seconds (something like Tiktok).
If you want to just loop the first seconds, just add an onProgress and send back to starting second when it passes a certain second:
class Video extends Component {
render() {
const {source, YOUR_VARIABLE_FOR_SECONDS} = this.props;
return <VideoPlayer
source={source}
ref={(ref) => {
this.player = ref
}}
onProgress={({currentTime}) => {
if (currentTime > YOUR_VARIABLE_FOR_SECONDS) {
this.player.seek(0)
}
}}
/>
}
}
There is no sense in doing it that way. Probably TikTok takes the "five seconds" and transforms it into GIF using something like a GIFIFY (https://github.com/jclem/gifify). If someone asked me to do this, I would certainly do so.
EDIT:
I think that you can create a code/component that displays only the X seconds, I think its possible
Related
I am trying to call an api base on scroll View current position but not sure how to I achieve that.
This is my code
<ScrollView
ref={scrollViewRef}
scrollEventThrottle={0}
onScroll={({nativeEvent}) => {
console.log(
nativeEvent.contentSize.height -
nativeEvent.layoutMeasurement.height,
);
console.log(nativeEvent.contentOffset);
}}>
I tried to call the api inside onScroll but that didnt work well.
Try adding an event listener at the particular scroll location you want the function to execute.
useEffect(() => {
Window.addEventListener(‘scroll’_.debounce(setScroll,1000));},[]);
I have solved the issue by using adding an if check. If the api data exist then the function wont execute anymore.
here's the code
const [apiData, setApiData] = useState();
onScroll={({nativeEvent}) => {
if (!apiData) {
if (
nativeEvent.contentSize.height -
nativeEvent.layoutMeasurement.height -
nativeEvent.contentOffset.y <
250
) {
getApiDataHandler();
}
}
}}
From some research, I've figured out that expo libraries like takePicturesAsync() are able to take a picture and save it to the app's cache. However, the default state for libraries like these is to save the whole image. Is there any way for me to save a specific part of the image (e.g. the 2500 pixels at the center of the screen)?
Thanks!
You can use the onPictureSaved event to grab & manipulate the image.
takePicture = () => {
if (this.camera) {
this.camera.takePictureAsync({ onPictureSaved: this.onPictureSaved });
}
};
onPictureSaved = photo => {
console.log(photo);
}
I am trying to make a video player App in React-native. I want a feature like start video from there where the user left before closing the Application. Any clue?
I am using React-native-video
You can get the current time from the video component by simply running videoRef.currentTime.
You can then store this in your localStorage
More specifically if you want to achieve this using store/local storage.Please check this out.
import Video from "react-native-video"
constructor(props) {
super(props)
this.progress = 0
this.onProgress = this.onProgress.bind(this)
//Here you can store this progress time to async storage or store.So that
when you navigate back to this screen you can either get the progress
from storage or from initial state = 0
}
onProgress = (data) => {
this.progress = data.currentTime
}
<Video
ref={(ref) => { this.player = ref }}
source={{ uri: '.....' }}
onProgress={this.onProgress}
onLoad={() => {
if (menuVideoProgress > 0)
this.player.seek(menuVideoProgress) //here recent progress times comes
from storage
}}
/>
I am trying to implement heremap api in react-native project.While searching got https://www.npmjs.com/package/react-native-heremaps .But there is no proper documents to use this library. I am new to react-native. Please give me some suggestions to implement this.
! if you don't use expo please comment and I'll change the answer a bit !
First of all, as you probably know you need to make an account at HERE Developer webiste.
After you have made an account, you have to create a project(you can get a Freemium plan for free and it has plenty of requests available for free, upgrade if you need more). After that you need to "Generate App" for REST & XYZ HUB API/CLI at your project page. With that, you will recieve APP ID and APP CODE. With all this, HERE Developer Account setup is complete.
Lets jump to React Native now.
First of all you need to install a npm package called react-native-maps which we will use to display data that HERE provides. You can see installation instructions here.
After this, lets assume you have already created a component that will show the map. You need to import this:
import { Marker, Polyline } from 'react-native-maps'
import { MapView } from 'expo'
With that we have our map almost ready.
I will use axios in this example but you can use fetch to make requests to HERE if you want.
So we import axios(if you never worked with it you can learn more about it here):
import axios from 'axios'
Now, you should have coordinates of those two locations ready in a state or somewhere, and it should look something like this:
constructor(props){
super(props)
this.state = {
startingLocation: {
latitude: "xx.x",
longitude: "yy.y",
},
finishLocation: {
latitude: "xx.x",
longitude: "yy.y",
}
}
}
With "xx.x" and "yy.y" being actual coordinates you want.
So now when you have coordinates of start and finish location you can make a request to you HERE API project. It's as easy as this(I got this api from here):
// I will create a function which will call this, you can call it whenever you want
_getRoute = () => {
// we are using parseFloat() because HERE API expects a float
let from_lat = parseFloat(this.state.startingLocation.latitude)
let from_long = parseFloat(this.state.startingLocation.longitude)
let to_lat = parseFloat(this.state.finishLocation.latitude)
let to_long = parseFloat(this.state.finishLocation.longitude)
// we will save all Polyline coordinates in this array
let route_coordinates = []
axios.get(`https://route.api.here.com/routing/7.2/calculateroute.json?app_id=PUT_YOUR_APP_ID_HERE&app_code=PUT_YOUR_APP_CODE_HERE&waypoint0=geo!${from_lat},${from_long}&waypoint1=geo!${to_lat},${to_long}&mode=fastest;bicycle;traffic:disabled&legAttributes=shape`).then(res => {
// here we are getting all route coordinates from API response
res.data.response.route[0].leg[0].shape.map(m => {
// here we are getting latitude and longitude in seperate variables because HERE sends it together, but we
// need it seperate for <Polyline/>
let latlong = m.split(',');
let latitude = parseFloat(latlong[0]);
let longitude = parseFloat(latlong[1]);
routeCoordinates.push({latitude: latitude, longitude: longitude});
}
this.setState({
routeForMap: routeCoordinates,
// here we can access route summary which will show us how long does it take to pass the route, distance etc.
summary: res.data.response.route[0].summary,
// NOTE just add this 'isLoading' field now, I'll explain it later
isLoading: false,
})
}).catch(err => {
console.log(err)
})
}
NOTE There are few things to note here. First is that you have to replace APP ID and APP CODE with acutal APP ID and APP CODE from your HERE project.
Second note that I added &legAttributes=shape at the end of the request URL but it is not in the documentation. I put it there so Polyline coordinates acutally have a correct shape, if you don't put it, it will just respond with coordinates of road turns and that polyline will go over buildings and stuff, it will just look bad.
OK. So now we have coordinates to make a Polyline, let's do that.
<MapView>
<Polyline coordinates={this.state.routeForMap} strokeWidth={7} strokeColor="red" geodesic={true}/>
<Marker coordinate={{latitude: this.state.startingLocation.latitude, longitude: this.state.startingLocation.longitude}} title="Starting location"/>
<Marker coordinate={{latitude: this.state.finishLocation.latitude, longitude: this.state.finishLocation.longitude}} title="Finishlocation"/>
</MapView>
Explanation:
Polyline.coordinates will map through all of the coordinates that we have provided and draw a Polyline. strokeWidth is just how thick you want your line to be, and strokeColor is obviously color of a line.
Now, you should add a region to your MapView component to let it know what is the initial region you want to show on the map. So I suggest you to do something like this:
In state, define a region field and make it the same coordinates as starting location, and then set delta to make a bit larger view.
// so in state just add this
region: {
latitude: parseFloat("xx.x"),
longitude: parseFloat("yy.y"),
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}
And now, add region={this.state.region} to MapView.
You would be done now, but let's make sure this works every time. You need to make sure that HERE API request is complete before the map renders. I would do it like this:
// in your state define field to control if loading is finished
isLoading: true,
Now, you would call the function _getRoute() we made before in componendDidMount() lifecycle function provided by React Native. Like this:
componentDidMount() {
// when this function is finished, we will set isLoading state to false to let program know that API request has finished and now we can render the map
this._getRoute()
}
So finally a final step is to control isLoading in your render() function:
render() {
if(this.state.isLoading) {
return (
<Text>Loading...(you could also use <ActivityIndicator/> or what ever you want to show while loading the request)</Text>
)
} else {
// just put everything we already did here + stuff you already have
}
}
So here it is. I tried to make it as detailed as possible to make it easy for you and other people that will need help with this.
Don't ever hesitate to ask me anything if something is unclear or it's not working or you need more help! I'm always happy to help :D
I'm using react-native-camera library in my React Native project.
But I have a problem when I try to take the photo. It takes 3-4 seconds before the photo is saved. When I click on the button to take the photo I hear sound but then it takes about 3-4 seconds to save the photo.
The render method is as follows:
return (
<View style={styles.container}>
<Camera ref={(cam) => {this.camera = cam;}}
style={styles.preview}
aspect={Camera.constants.Aspect.fill}>
{this.imageOverlay()}
<Text style={styles.capture} onPress={this.takePicture.bind(this, this.state.type)}>[CAPTURE]</Text>
</Camera>
</View>
)
And takePicture function is as follows:
takePicture(type){
let self = this;
this.camera.capture({target: Camera.constants.CaptureTarget.disk})
.then((data) => {
<!---------------------------------------------------------->
<!------------It takes 3-4 seconds to come here------------!>
<!---------------------------------------------------------->
let n_pictures = [];
each(this.state.pictures, function (picture){
if(picture.item !== type.item){
n_pictures.push(picture)
}else{
n_pictures.push({
title: type.title,
noImage: false,
imageOverlay: type.imageOverlay,
image: data.path,
imageIcon: type.imageIcon,
overlay: false,
item: type.item,
mandatory: type.mandatory
})
}
});
self.setState({pictures: n_pictures, showCamera: false})
})
.catch(err => console.error(err));
}
Any idea how to solve it?
Can I at least put an loading screen until the photo is saved?
So I had this same issue, and after a while of searching on the internet I could not find an answer to speed it up.
However, to answer your query about using a loading screen you may want to look into Javascript promises. For my app, I redirected the user immediately to a new screen and showed a loading picture while the promise was not resolved/rejected. Once it was resolved, the picture showed.
I know this is an old answer, but I'm going to put this here for anyone else who may have a similar issue.