Expo-Camera安卓端录制视频无法自动旋转(iOS正常,应用锁定竖屏)
解决Expo Camera锁定竖屏时Android端视频朝向错误问题
问题根源
Android与iOS的Expo Camera对视频朝向的处理逻辑存在差异:iOS会自动读取设备物理朝向并写入视频旋转元数据,不受应用屏幕锁定状态影响;但Android端当应用锁定为portrait-up时,Camera模块会强制沿用应用的方向配置,忽略设备实际物理姿态,导致视频没有正确的旋转信息,播放时出现方向错误。
可行解决方案
方案1:录制前临时解锁屏幕方向
核心思路是在录制开始前解除屏幕锁定,让Camera获取设备物理朝向,录制完成后重新锁定竖屏。此方法简单直接,适配性强。
示例代码:
import { Camera } from 'expo-camera'; import * as ScreenOrientation from 'expo-screen-orientation'; let isRecording = false; const camera = useRef(null); const startRecording = async () => { if (isRecording) return; isRecording = true; // 临时解锁屏幕方向 await ScreenOrientation.unlockAsync(); try { const recordResult = await camera.current.recordAsync(); // 处理视频保存逻辑 console.log('录制完成:', recordResult.uri); } catch (err) { console.error('录制失败:', err); } finally { // 录制结束后重新锁定竖屏 await ScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.PORTRAIT_UP); isRecording = false; } };
方案2:手动获取物理朝向并修改视频元数据
若不想临时解锁屏幕方向,可通过传感器获取设备物理姿态,录制完成后手动添加旋转元数据到视频文件。
步骤与代码:
- 安装依赖:
expo install expo-sensors expo-media-library
- 监听设备朝向并录制后修改元数据:
import { DeviceMotion } from 'expo-sensors'; import * as MediaLibrary from 'expo-media-library'; import { Camera } from 'expo-camera'; let currentOrientation = 1; // 1=0°, 6=90°, 8=270°, 3=180° // 监听设备物理朝向 DeviceMotion.addListener(({ rotation }) => { const { gamma } = rotation; // 适配大多数Android设备的坐标系 if (gamma > 45) { currentOrientation = 6; // 横屏向右 } else if (gamma < -45) { currentOrientation = 8; // 横屏向左 } else { currentOrientation = 1; // 竖屏向上 } }); // 录制完成后更新视频元数据 const saveVideoWithCorrectOrientation = async (videoUri) => { const asset = await MediaLibrary.createAssetAsync(videoUri); await MediaLibrary.updateAssetAsync(asset, { metadata: { exif: { Orientation: currentOrientation } } }); };
注意事项
- 方案1会让应用在录制期间短暂允许屏幕旋转,若要保持界面固定,可给Camera组件添加固定方向的样式,比如
style={{ transform: [{ rotate: '90deg' }] }}(根据实际场景调整)。 - 方案2需要测试不同Android设备的坐标系差异,避免出现旋转角度计算错误。
- 确保已申请必要权限:
CAMERA、RECORD_AUDIO、MEDIA_LIBRARY_WRITE。
内容的提问来源于stack exchange,提问作者Felipe Stabel de Carvalho Schi
相关产品推荐
相关产品推荐

