Picache gif is a still image (Expo + ReactNative) - react-native

I'm trying to speed up loading a bunch of gifs, but a big limitation is that I'm using Expo, and don't want to detach. I found Picache, which states it can be used just like react native Image. When the page loads though, everything loads super fast now, but the gifs are still and not 'gify'.
<Picache
source={{uri: someURL.gif)}}
style={{height: 300, width: 300, borderRadius: 10}}
/>
I've spent so long trynig to figure out how to speed up loading a bunch of images without detaching. Is there a way to make Picache work with gifs, or a similar easy way to implement?
**Before someone suggests, I've already tried... react-native-fast-image-expo but unfortunately it requires detaching as well. That is the desired package though.

If you don't want to bring out the project, you can replace it with this.
Until Expo added the module,
example:
import {Image} from "react-native-expo-image-cache";
// preview can be a local image or a data uri
const preview = { uri: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==" };
const uri = "https://firebasestorage.googleapis.com/v0/b/react-native-e.appspot.com/o/b47b03a1e22e3f1fd884b5252de1e64a06a14126.png?alt=media&token=d636c423-3d94-440f-90c1-57c4de921641";
<Image style={{ height: 100, width: 100 }} {...{preview, uri}} />
Get the local image from a remote URI
import {CacheManager} from "react-native-expo-image-cache";
const {uri} = this.props;
const path = await CacheManager.get(uri).getPath();
// if path is undefined, the image download has failed

Related

React Native require video path from file | Dynamic Video Require

I'm working on this app that does not always hold the video content on the device.
The Video will be downloaded, and then a path to the video will be on json objects that need to be inputed into a require. (or thats how I do it right now)
This is the code for the video:
import jsonFileExercise from '../../../assets/controller/data/getNextExerciseBySectionId.json'
var videoPath = jsonFileExercise.content.path
return (
<Video
source={require(videoPath)}
rate={1.0}
volume={1.0}
isMuted={false}
resizeMode="cover"
//shouldPlay
useNativeControls
isLooping
style={styles.backgroundVideo}
/>
)
This is the JSON file
{
"exerciseId": 1,
"content": {
"type": "video",
"path": "../video/content/testvideo2.mp4"
}
}
I want to be able to change the path in the JSON file and then load a different video.
Does anyone know a better way of having Dynamic Video that is loaded from storage?
Another problem is going to be using images from asyncStorage, but the ideal solution would be something that uses both images from AsyncStorage and updating images dynamically.
Similar posts: React Native: require() with Dynamic String?
But it did not show a solution for the issue.

React Native Fast Image Caching

I am trying to cache profile pictures that are being fetched from an s3 bucket. On my backend I am able to fetch the url of each image. I then can loop through an array of profiles (which have the pictures' urls) and display the correct images, as used below.
{profiles && profiles.map((profile) => {
<FastImage
source={{
uri: profile.picture, // this is a URL string
cache: FastImage.cacheControl.immutable // Default cache
}}
/>
})}
When I change cache from 'immutable' to 'cacheOnly' the pictures are no longer rendered.
{profiles && profiles.map((profile) => {
<FastImage
source={{
uri: profile.picture, // this is a URL
cache: FastImage.cacheControl.cacheOnly // picture only renders if in cache
}}
/>
})}
But, if I substitute the picture variable with the actual URL string, the picture will render.
{profiles && profiles.map((profile) => {
<FastImage
source={{
uri: 'https://s3.aws.examplePictureKey'
cache: FastImage.cacheControl.immutable // Default cache
}}
/>
})}
Then if I change cache from 'immutable' to 'cacheOnly' the picture persists, telling me it has been cached. What I am wondering is:
Am I making a mistake here? All the documentation/resources I have read through do not have examples when looping through an array, but I am not sure why this would be the problem.
My understanding is that the image cached is based on the url string, if the url does not change FastImage just gets the image in the cache. But the url is not changing, so why wouldn't the image be saved in the cache?
The example above is slimmed down from what I am actually doing, the only difference though is that I am passing each profile element from a parent component before trying to render the image. Would this somehow prevent the image from being cached?
Documentation: https://www.npmjs.com/package/react-native-fast-image
Thanks!
The cache: FastImage.cacheControl.cacheOnly from FastImage means it wont do any network request, it will just try to find from the cache. Default(immutable) means it will only change when the url changes so on any subsequent re-render, if the url changes to anything by chance, it will do network request again. And you need to return the component from map as well and provide the width and height properties to FastImage style as well.
{Array.isArray(profiles) && profiles.map((profile) => {
return <FastImage
source={{
uri: profile.picture, // this is a URL string
// cache: FastImage.cacheControl.immutable // Default cache
}}
style={{width: 200, height: 200}}
/>
})}
Hope it helps.

Play Amazon S3 cloudefront video in React Native

Is there a way to play hosted video from Amazon to React Native application? I have tried with React Native Af Video player but could not play it.
The video URL is like this: https://d3codsxyyh2kcu.cloudfront.net/https?Expires=1547218475&Signature=MqxFm4cvR2IYfruCKEaM9JvaFDa7a-0ipdhK9QLxiRFIDcc1jHgvrpNLaPdId1nK5EXJND9hIGnAZvevdRhkA9Uocmd-I3QRdPNumv2BCuSBARgiMcu~lnwgQ24G9r1uO~ZlQ5CDhPTyJYFqC8DyFuzbGnHrTRfMTfPYIUZSi5lvk22oXGDOqARra~-KoAKk-vPXAxxUo1BjCXw3V06t6JNxCCrhaGiS3~OaRc28wGSRacm7F5A9rf~eEWSUWQ~17lUC-Jm6jnWAI9zqSqtyIk4ladboX7FNFi8N12wq39KWinYqvhMNkJcmxy1lGLCgEbabndfJc~yez7c2d17~Rw__&Key-Pair-Id=my_key_id
Please help me in this regard.
you can use react-native-video.
I have worked on projects that provides signed url for videos as list. These urls can be streamed / played using this pacakge.
Only thing to note is you need to generate signed S3 url so that video will play easily. One way to check this is you can directly copy paste the signed url on the browser and it should stream right away.
PS: I also had doubts that s3 urls might not be playable using react-native-video, But turns out, providing signedUrl video will work. you can use onError to debug issues. (Make sure the url is playing from chrome before eu test it on RNApp)
Sample Code
// Load the module
import Video from 'react-native-video';
<Video source={{uri: "s3 signed url"}} // Can be a URL or a local file.
ref={(ref) => {
this.player = ref
}} // Store reference
onBuffer={this.onBuffer} // Callback when remote video is buffering
onError={this.videoError} // Callback when video cannot be loaded
style={styles.backgroundVideo} />
// Later on in your styles..
var styles = StyleSheet.create({
backgroundVideo: {
position: 'absolute',
top: 0,
left: 0,
bottom: 0,
right: 0,
},
});

Why my images aren't showing in React Native

I'm trying to show some images in my React Native app. It's a simple app, only for Android. The app get informations from an API. The initial View is a list of items and when I click in one item, it gets more info from the API and show in a new page. I also get some urls that points to images that are kept in a S3 bucket in AWS.
This is how I show the images:
<ScrollView>
{this.state.urls.map(url => {
<Image
source={{uri: url}}
style={{width:400, height:200}}
/>
}
</ScrollView>
The problem is that it's not showing those images. I can see that there is a part of the page that is for the image. I can see that because if a put the image first and after that some text, the text will appear at the bottom of the page. I don't know what is going on that the image doesn't appear.
I searched for an answer, found something about using https instead of http (at least for iOS). Found that I need to set width and height. I already did those things and others but it's not working.
I also tried just picking a image from the internet and putting it url direct in uri but it still doesnt't work.
You're missing a return statement in your map function.
<ScrollView>
{this.state.urls.map(url => {
return <Image
source={{uri: url}}
style={{width:400, height:200}}
/>
}
</ScrollView>
UPDATE
I just tried the url that you provided in the above comment and it doesn't work on my device. I tried a different image from the internet this one and it works. There may also be something that is stopping you from accessing the images from within a mobile app.
To debug further I try would a single <Image .../> with the image hosted on AWS and see if you can get that to show. There may need to be some AWS configuration that you need to change to allow the image to be accessed from a mobile device.
Assuming your image URLs are accessible in your application.
The below code will show your images. Actually you forgot to return a component from the map which is a must have.
<ScrollView>
{this.state.urls.map(url => {
return <Image
source={{uri: url}}
style={{width:400, height:200}} /> }
}
</ScrollView>

Possibility of loading Google places images in react-native Image component?

I am trying to find a way to load image reference I get from places api into places photo API using Image component of react-native like below,
const imageLink = 'https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&photoreference=CmRaAAAAuZ36wzrMYCVNWM1smQkRKuQyXecPgRpcsMfrSqbJM0EUTXZ62j8Ljxtk8HsxohXbtAwZAwmj_F3HmDwLoQaH9qt2TZJhhA6EuXK41UFo0Ow750MJujtrr5hgHR2lF7EXEhCkWj_dZ4LefrYzLU1_5RF1GhTR7Ggem5IJ-v7V2U8fjKoU9tBUOg&key=--MyKey--'
return (
<View >
<TouchableHighlight >
<View>
<Image
style={{width:64, height:64,flex:1,backgroundColor:'red'}}
source={{uri: imageLink}}
/>
</View>
</TouchableHighlight>
</View>
);
I am getting only empty placeholder with above code. However, I am able to load this link in browser.One caveat is that google places photo's link is redirecting to some other url which then displays image in browser. Am I doing it right? or is there any other way I can accomplish the same. Note: I tried react-native-network-image library as well.
You can have a look at the ImagePrefetch function in googleplace module:
https://github.com/srirangan/googleplaces.js/blob/master/test/ImageFetchTest.js
However, I am having issue with the whole module at the moment because of the line var https = require("https"); called in this specific function.
Not sure if it's an issue with new version of RN (upgraded to 0.55 recently) or just some other error in my new setup.
This worked perfectly in previous RN (was running on 0.48)