A library that allows displaying Live Photos on iOS.
-Â
npx expo install expo-live-photo
If you are installing this in an existing React Native app, start by installing expo
in your project. Then, follow the additional instructions as mentioned by the library's README under "Installation in bare React Native projects" section.
Here's a simple example of expo-live-photo
usage combined with expo-image-picker
.
import * as ImagePicker from 'expo-image-picker';
import { LivePhotoAsset, LivePhotoView, LivePhotoViewType } from 'expo-live-photo';
import { useRef, useState } from 'react';
import { View, StyleSheet, Text, Button } from 'react-native';
export default function LivePhotoScreen() {
const viewRef = useRef<LivePhotoViewType>(null);
const [livePhoto, setLivePhoto] = useState<LivePhotoAsset | null>(null);
const pickImage = async () => {
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ['livePhotos'],
});
if (!result.canceled && result.assets[0].pairedVideoAsset?.uri) {
setLivePhoto({
photoUri: result.assets[0].uri,
pairedVideoUri: result.assets[0].pairedVideoAsset.uri,
});
} else {
console.error('Failed to pick a live photo');
}
};
if (!LivePhotoView.isAvailable()) {
return (
<View style={styles.container}>
<Text>expo-live-photo is not available on this platform 😕</Text>
</View>
);
}
return (
<View style={styles.container}>
<LivePhotoView
ref={viewRef}
source={livePhoto}
style={[styles.livePhotoView, { display: livePhoto ? 'flex' : 'none' }]}
onLoadComplete={() => {
console.log('Live photo loaded successfully!');
}}
onLoadError={error => {
console.error('Failed to load the live photo: ', error.message);
}}
/>
<View style={livePhoto ? styles.pickImageCollapsed : styles.pickImageExpanded}>
<Button title={livePhoto ? 'Change Image' : 'Pick an image'} onPress={pickImage} />
</View>
<Button title="Start Playback Hint" onPress={() => viewRef.current?.startPlayback('hint')} />
<Button title="Start Playback" onPress={() => viewRef.current?.startPlayback('full')} />
<Button title="Stop Playback" onPress={() => viewRef.current?.stopPlayback()} />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
paddingVertical: 20,
paddingHorizontal: 40,
},
livePhotoView: {
alignSelf: 'stretch',
height: 300,
},
pickImageExpanded: {
alignSelf: 'stretch',
height: 300,
justifyContent: 'center',
},
pickImageCollapsed: {
marginVertical: 10,
},
button: {
marginVertical: 10,
},
});
import { LivePhotoView } from 'expo-live-photo';
LivePhotoView
Type: React.Element<LivePhotoViewProps>
contentFit
ContentFit
 • Default: 'contain'
Determines how the image should be scaled to fit the container.
'contain'
- Scales the image so that its larger dimension fits the target size.'cover'
- Scales the image so that it completely fills the target size.isMuted
boolean
 • Default: true
Determines whether the live photo should also play audio.
onLoadComplete
() => void
Called when the live photo is loaded and ready to play.
onLoadError
(error: LivePhotoLoadError) => void
Called when an error occurred while loading.
onPreviewPhotoLoad
() => void
Called when the live photo preview photo is loaded.
useDefaultGestureRecognizer
boolean
 • Default: true
Determines whether the default iOS gesture recognizer should be used.
When true
the playback will start if the user presses and holds on the LivePhotoView
.
isAvailable()
Determines whether the current device is capable of displaying live photos.
boolean
LivePhotoViewStatics
LivePhotoViewStatics Methods
isAvailable()
Determines whether the current device is capable of displaying live photos.
boolean
ContentFit
Literal Type: string
Determines how the image should be scaled to fit the container.
'contain'
- Scales the image so that its larger dimension fits the target size.'cover'
- Scales the image so that it completely fills the target size.Acceptable values are: 'contain'
| 'cover'
LivePhotoAsset
A live photo asset.
Note: Due to native limitations, the photo and video parts of the live photo must come from a valid live photo file and be unaltered. When taken, the photo is paired with the video via metadata. If the pairing is broken, joining them into a live photo is impossible.
Name | Type | Description |
---|---|---|
pairedVideoUri | string | The URI of the video part of the live photo. |
photoUri | string | The URI of the photo part of the live photo. |
LivePhotoViewType
Name | Type | Description |
---|---|---|
startPlayback | (playbackStyle: PlaybackStyle) => void | Start the playback of the video part of the live photo. |
stopPlayback | () => void | Stop the playback of the video part of the live photo. |
PlaybackStyle
Literal Type: string
Determines what style to use when playing the live photo.
'hint'
- A short part of the video will be played to indicate that a live photo is being displayed.'full'
- The full video part will be played.Acceptable values are: 'hint'
| 'full'