Search code examples
reactjsexporeact-nativeexpo-camera

[Unhandled promise rejection: TypeError: undefined is not an object (evaluating '_expoMediaLibrary.MediaLibrary.createAssetAsync')]


I using expo-camera to record video and save it in my device, but even on stop recording it has video uri, the .MediaLibrary.createAssetAsync is giving the above error, also the recording gets stopped from the first even if I have used setTimeout to stop the recording, this is my code for the camera:

import React, { useState, useEffect, useRef } from 'react';
import { Text, View } from 'react-native';
import { Camera } from 'expo-camera';
import { MediaLibrary } from 'expo-media-library';
import { Audio } from 'expo-av';

export default function App() {
  const [hasPermission, setHasPermission] = useState(null);
  const [camera, setCamera] = useState(null);
  const [recording, setRecording] = useState(false);
  const [video, setVideo] = useState(null);
  const [stop, setStop] = useState(false);

  const recordingVideo = async () => {
    const video = await camera.recordAsync();
    console.log(video);
    setVideo(video);
  }

  const saveVideo = async () => {
    console.log('uri', video.uri);
    const asset = await MediaLibrary.createAssetAsync(video.uri);
    if (asset) {
      console.log('asset', asset);
      setVideo(null);
    }
  };

  useEffect(() => {
    console.log('recoring', recording);
    if (recording && camera) recordingVideo();
  }, [recording, camera]);

  useEffect(() => {
    console.log('stop', stop);

    if (stop) {
      setRecording(false);
      camera.stopRecording();
      saveVideo();
    }
  }, [stop]);

  useEffect(() => {
    (async () => {
      const { status } = await Camera.requestPermissionsAsync();
      const audioPerm = await Audio.requestPermissionsAsync();
      setHasPermission(status === 'granted' && audioPerm.status === 'granted');
    })();
  }, []);

  useEffect(() => {
    if(camera) {
      console.log('ref');
      setRecording(true);

      setTimeout(() => {
        setStop(true);
      }, 10000);
    }
  }, [camera]);

  if (hasPermission === null) {
    return <View />;
  }

  if (hasPermission === false) {
    return <Text>No access to camera or audio</Text>;
  }

  return (
    <View style={{ flex: 1 }}>
      <Camera style={{ flex: 1 }} type={Camera.Constants.Type.front} ref={ref => setCamera(ref)}>
        <View style={{ flex: 1, backgroundColor: '#00000000', justifyContent: 'center' }}>
          <Text style={{ marginHorizontal: 40 }}>{recording ? 'Recording' : !stop ? 'Waiting for recording' : 'recording finished' }</Text>
        </View>
      </Camera>
    </View>
  );
}

I searched in expo-media-library docs and logged the video.uri that is exactly some matching parameter but cannot understand why it is working like that.


Solution

  • I was having the same problem in my Camera App. I solved by changing my import

    // Change from this
    import { MediaLibrary } from 'expo-media-library';
    // To this
    import * as MediaLibrary from 'expo-media-library';