[React Native] react-native-vision-camera


๐Ÿ”ฅ 1. ๊ฐœ๋ฐœ ์…‹ํŒ…

yarn add react-native-vision-camera
cd ios && pod install && cd ..

๐Ÿ”ฅ 2. ๊ถŒํ•œ ์„ค์ •

(1) : IOS

//Info.plist

<!-- ์นด๋ฉ”๋ผ ๊ถŒํ•œ -->
<key>NSCameraUsageDescription</key>
<string>$(PRODUCT_NAME) needs access to your Camera.</string>

<!-- ๋งˆ์ดํฌ ๊ถŒํ•œ -->
<key>NSMicrophoneUsageDescription</key>
<string>$(PRODUCT_NAME) needs access to your Microphone.</string>

(2) : AOS

//AndroidManifest.xml

<!-- ์นด๋ฉ”๋ผ ๊ถŒํ•œ -->
<uses-permission android:name="android.permission.CAMERA" />

<!-- ๋งˆ์ดํฌ ๊ถŒํ•œ -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />

(3) : ๊ถŒํ•œ ๊ฐ€์ ธ์˜ค๊ธฐ / ๊ถŒํ•œ ์š”์ฒญ ํ•˜๊ธฐ

(1) : ๊ถŒํ•œ ๊ฐ€์ ธ์˜ค๊ธฐ : ์‚ฌ์šฉ์ž๊ฐ€ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ–ˆ๋Š”์ง€ ์ฒดํฌ

const cameraPermission = await Camera.getCameraPermissionStatus();
const microphonePermission = await Camera.getMicrophonePermissionStatus();

(2) : ๊ถŒํ•œ ์š”์ฒญํ•˜๊ธฐ : ์‚ฌ์šฉ์ž์—๊ฒŒ ๊ถŒํ•œ์„ ์š”์ฒญ

const newCameraPermission = await Camera.requestCameraPermission();
const newMicrophonePermission = await Camera.requestMicrophonePermission();

๐Ÿ”ฅ 3. ์˜ˆ์‹œ

(1) : ๊ถŒํ•œ ํ™•์ธ / ์š”์ฒญ

useEffect(() => {
  const checkPermission = async () => {
    // ์นด๋ฉ”๋ผ ๊ถŒํ•œ ํ™•์ธ
    const cameraPermission = await Camera.getCameraPermissionStatus();

    switch (cameraPermission) {
      case "authorized":
        // ์นด๋ฉ”๋ผ ๊ถŒํ•œ์ด ์žˆ์„๋•Œ ์‹คํ–‰ํ•  ๋กœ์ง
        break;

      case "not-determined":
        // ์•„์ง ๊ถŒํ•œ ์š”์ฒญ์„ ํ•˜์ง€ ์•Š์€ ์ƒํƒœ๋กœ ์ƒˆ๋กญ๊ฒŒ ๊ถŒํ•œ ์š”์ฒญํ•˜๊ธฐ
        const newCameraPermission = await Camera.requestCameraPermission();

        if (newCameraPermission === "authorized") {
          // ์นด๋ฉ”๋ผ ๊ถŒํ•œ์ด ์žˆ์„๋•Œ ์‹คํ–‰ํ•  ๋กœ์ง
        } else if (newCameraPermission === "denied") {
          // ๊ถŒํ•œ ์š”์ฒญ์„ ํ–ˆ์ง€๋งŒ ๊ฑฐ๋ถ€๋์„๋•Œ ์‹คํ–‰ํ•  ๋กœ์ง
          // ex) ์„ค์ •์œผ๋กœ ์ด๋™, ๊ถŒํ•œ์ด ์—†์œผ๋ฉด ์นด๋ฉ”๋ผ ์‹คํ–‰ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ์•Œ๋ฆผ์ฐฝ ๋“ฑ๋“ฑ
          await Linking.openSettings();
        }
        break;

      case "denied":
        // ๊ถŒํ•œ ์š”์ฒญ์„ ํ–ˆ์ง€๋งŒ ๊ฑฐ๋ถ€๋์„๋•Œ ์‹คํ–‰ํ•  ๋กœ์ง
        // ex) ์„ค์ •์œผ๋กœ ์ด๋™, ๊ถŒํ•œ์ด ์—†์œผ๋ฉด ์นด๋ฉ”๋ผ ์‹คํ–‰ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ์•Œ๋ฆผ์ฐฝ ๋“ฑ๋“ฑ
        await Linking.openSettings();
        break;
    }
  };

  checkPermission();
}, []);

(2) : Camera ํƒœ๊ทธ ๋ฐ props

function App() {
  const devices = useCameraDevices();
  const device = devices.back;

  if (device == null) return <LoadingView />;
  return (
    <Camera
      style={StyleSheet.absoluteFill}
      device={device}
      photo={true}
      video={false}
      audio={false} // ์„ ํƒ์‚ฌํ•ญ
      isActive={true}
    />
  );
}
  • **style : ๋‚ด๊ฐ€ ์›ํ•˜๋Š” ์นด๋ฉ”๋ผ์˜ ์Šคํƒ€์ผ์„ ์ง€์ •. StyleSheet.absoluteFill์„ ์‚ฌ์šฉํ–ˆ์„๋•Œ๋Š” ํ™”๋ฉด ์ „์ฒด๊ฐ€ ์นด๋ฉ”๋ผ๋กœ ๊ฝ‰ ์ฐจ๊ฒŒ๋Œ**
  • **useCameraDevices() : ํ˜„์žฌ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ๊ธฐ๊ธฐ์˜ ์นด๋ฉ”๋ผ ์ •๋ณด. ๊ฐ์ฒด๋กœ ์ด๋ฃจ์–ด์ ธ์žˆ์œผ๋ฉฐ ๋ณดํ†ต ์•ž, ๋’ท๋ฉด(front, back) ์นด๋ฉ”๋ผ์˜ ์ •๋ณด๊ฐ€ ๋‹ด๊ฒจ ์žˆ์Œ.**
  • **deviceuseCameraDevices()ย : ํ˜„์žฌ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ๊ธฐ๊ธฐ์˜ ์นด๋ฉ”๋ผ๋“ค์˜ ์ •๋ณด. ๊ฐ์ฒด๋กœ ์ด๋ฃจ์–ด์ ธ์žˆ์œผ๋ฉฐ ๋ณดํ†ต ์•ž, ๋’ท๋ฉด(front, back) ์นด๋ฉ”๋ผ์˜ ์ •๋ณด, back์—์„œ back์ž๋ฆฌ๋ฅผ state๋กœ ๊ด€๋ฆฌํ•ด, ์นด๋ฉ”๋ผ ์ „ํ™˜๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„๋•Œ front์™€ back์œผ๋กœ ๋ณ€๊ฒฝ๋˜๋Š” ํ˜•์‹์œผ๋กœ ์–ด๋–ค ์นด๋ฉ”๋ผ๋ฅผ ์‚ฌ์šฉํ• ์ง€ ์„ ํƒํ•  ์ˆ˜ ์žˆ์Œ**
  • **photo : ์‚ฌ์ง„ ์ดฌ์˜ํ•  ๋•Œ true๋กœ ์„ค์ •๋˜์–ด์•ผ ์ดฌ์˜์ด ๊ฐ€๋Šฅ**
  • **video,ย audio : ์˜์ƒ ์ดฌ์˜๊ณผ ๋งˆ์ดํฌ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ true๋กœ ์„ค์ •๋˜์–ด์•ผ ์ดฌ์˜์ด ๊ฐ€๋Šฅ**
  • **isActive : true์ผ ๋•Œ ์นด๋ฉ”๋ผ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ.**