Created
April 29, 2021 21:49
-
-
Save ajsmth/299d3530d55f95c65c59ecc4277b8c3e to your computer and use it in GitHub Desktop.
Expo Camera Codec
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Camera } from 'expo-camera'; | |
import React, { useState, useEffect, useRef } from 'react'; | |
import { | |
StyleSheet, | |
Text, | |
View, | |
TouchableOpacity, | |
SafeAreaView, | |
Alert, | |
ScrollView, | |
} from 'react-native'; | |
export default function App() { | |
const [hasPermission, setHasPermission] = useState(null); | |
const [type] = useState(Camera.Constants.Type.back); | |
const camera = useRef<Camera | null>(null); | |
const [isRecording, setIsRecording] = useState(false); | |
const [selectedCodec, setSelectedCodec] = useState(); | |
const [availableCodecs, setAvilableCodecs] = useState([]); | |
useEffect(() => { | |
(async () => { | |
const { status } = await Camera.requestPermissionsAsync(); | |
setHasPermission(status === 'granted'); | |
const codecs = await Camera.getAvailableVideoCodecsAsync(); | |
setAvilableCodecs(codecs); | |
console.log({ codecs }); | |
})(); | |
}, []); | |
async function onRecordPress() { | |
if (isRecording) { | |
camera.current?.stopRecording(); | |
} else { | |
setIsRecording(true); | |
camera.current | |
?.recordAsync({ codec: selectedCodec }) | |
.then(recording => { | |
setIsRecording(false); | |
Alert.alert(JSON.stringify(recording, null, '\t')); | |
}) | |
.catch(error => { | |
setIsRecording(false); | |
console.log({ error }); | |
Alert.alert(`${error.message}\nAvailable codes: ${availableCodecs}`); | |
}); | |
} | |
} | |
if (hasPermission === null) { | |
return <View />; | |
} | |
if (hasPermission === false) { | |
return <Text>No access to camera</Text>; | |
} | |
return ( | |
<SafeAreaView style={styles.container}> | |
<ScrollView style={{ flex: 1 }}> | |
<Camera style={styles.camera} type={type} ref={camera} /> | |
<View style={{ flexDirection: 'row', flexWrap: 'wrap' }}> | |
<SelectCodec | |
text="H264" | |
isActive={selectedCodec === Camera.Constants.VideoCodec.H264} | |
onSelect={() => setSelectedCodec(Camera.Constants.VideoCodec.H264)} | |
/> | |
<SelectCodec | |
text="HEVC" | |
isActive={selectedCodec === Camera.Constants.VideoCodec.HEVC} | |
onSelect={() => setSelectedCodec(Camera.Constants.VideoCodec.HEVC)} | |
/> | |
<SelectCodec | |
text="JPEG" | |
isActive={selectedCodec === Camera.Constants.VideoCodec.JPEG} | |
onSelect={() => setSelectedCodec(Camera.Constants.VideoCodec.JPEG)} | |
/> | |
<SelectCodec | |
text="AppleProRes422" | |
isActive={selectedCodec === Camera.Constants.VideoCodec.AppleProRes422} | |
onSelect={() => setSelectedCodec(Camera.Constants.VideoCodec.AppleProRes422)} | |
/> | |
<SelectCodec | |
text="AppleProRes4444" | |
isActive={selectedCodec === Camera.Constants.VideoCodec.AppleProRes4444} | |
onSelect={() => setSelectedCodec(Camera.Constants.VideoCodec.AppleProRes4444)} | |
/> | |
</View> | |
<View style={{ height: 60, marginVertical: 12 }}> | |
<TouchableOpacity style={styles.button} onPress={onRecordPress}> | |
<Text style={styles.text}> {isRecording ? 'Stop' : 'Start'} Recording </Text> | |
</TouchableOpacity> | |
</View> | |
</ScrollView> | |
</SafeAreaView> | |
); | |
} | |
function SelectCodec({ text, onSelect, isActive }) { | |
return ( | |
<TouchableOpacity | |
style={{ | |
margin: 4, | |
padding: 4, | |
borderWidth: isActive ? 0 : 1, | |
flex: 1, | |
height: 50, | |
minWidth: '33%', | |
justifyContent: 'center', | |
alignItems: 'center', | |
backgroundColor: isActive ? 'coral' : 'white', | |
}} | |
onPress={onSelect}> | |
<Text | |
style={{ | |
textAlign: 'center', | |
color: isActive ? 'white' : 'black', | |
fontWeight: '600', | |
fontSize: 16, | |
}}> | |
{text} | |
</Text> | |
</TouchableOpacity> | |
); | |
} | |
const styles = StyleSheet.create({ | |
container: { | |
flex: 1, | |
backgroundColor: '#fff', | |
}, | |
camera: { | |
height: 400, | |
marginBottom: 16, | |
}, | |
button: { | |
flex: 1, | |
justifyContent: 'center', | |
alignItems: 'center', | |
backgroundColor: '#fff', | |
borderWidth: 1, | |
}, | |
text: { | |
fontSize: 16, | |
}, | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment