'How to Display a Video Preview in React Native Expo?

I am using a file picker (expo-images-picker) in React Native (Expo) where users can select images or a video. I would like to be able to show a preview of the video, before upload, once a user has selected one. I can do this with images using the returned file reference(s), but I can't seem to get my video player to play the selecting video file using the same methodology.

I am using Expo-AV library to show videos, and this works fine for files with a URL from a database. However, the file selector returns a reference like this:

ph://70A1FE9D-F640-4569-8D6D-8B8329A5FDC9

Whereas if an image is selected the reference is a little more readable:

file:///Users/Library/Developer/CoreSimulator/Devices/C2120292-116D-463D-BB6F-78A3306C531B/.../2DB7FE67-0B32-4FEB-A718-4B53AC8F220C.png

This is the code for the video player

let previewVideo;
if (route.params) {
    if (route.params.selectedVideo) {
        previewVideo = route.params.selectedVideo;
    }
}

{previewVideo &&
    <View style={tailwind('mt-2')}>
        <Video
            ref={video}
            source={{ uri: previewVideo }}
            useNativeControls
            resizeMode="contain"
            isLooping={false}
            isMuted={false}
            style={tailwind('h-52 w-80')}
        />
   </View>
}

Is this actually possible to do, or would I need to upload the video first and show a thumbnail/placeholder or something instead? Any help very much appreciated.

EDIT:

The Video component comes from expo-av

import { Audio, Video } from 'expo-av';

EDIT TWO:

I use the expo-images-picker package for both images and video. The image picker is basically another screen, with the references of the files that are selected being sent back to the 'form' screen via navigation props

Code from the Image Browser Screen:

const widgetNavigator = useMemo(
    () => ({
        ...
        onSuccess: (data) => onSuccess(data),
    }),
    []
);


const onSuccess = async (data) => {
    // get the selected image's file references and send to the form photo grid
    const fileArray = [];
    for (let i = 0; i < data.length; i++) {
        fileArray.push(data[i].uri)
    }
    if (selector === 'photos') {
    navigation.navigate('AddPost', { selectedPhotos:fileArray });
    } else {
    navigation.navigate('AddPost', { selectedVideo:fileArray[0] });
    }
};

I pass a param to the file picker called selector which tells me if the user is selecting a video or images, if images we send them as params to AddPost, likewise with the Video if one is selected. Either way, whichever files are selected, their reference is passed as params to the AddPost screen. As I mentioned above, this works fine for images, but the reference for a video is a little odd.

EDIT 3: Extra data returned from expo-images-picker for the video file:

data:  Array [
   Object {
       "creationTime": 1639135793000,
       "duration": 23.423333333333332,
       "filename": "IMG_0016.MP4",
       "height": 360,
       "id": "70A1FE9D-F640-4569-8D6D-8B8329A5FDC9/L0/001",
       "mediaSubtypes": Array [],
       "mediaType": "video",
       "modificationTime": 1644649243588,
       "uri": "ph://70A1FE9D-F640-4569-8D6D-8B8329A5FDC9",
       "width": 640,
   },
]


Solution 1:[1]

Try using MediaLibrary.getAssetInfoAsync(id) to get accessible uri.
This function returns AssetInfo which includes localUri of the asset.
passing this "id": "70A1FE9D-F640-4569-8D6D-8B8329A5FDC9/L0/001" as an id and it should return uri like file:///Users/Library/Developer/... not ph://... then you can display the image or play video.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 foloinfo