diff --git a/package/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt b/package/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt index 770812f..dae4521 100644 --- a/package/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt +++ b/package/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt @@ -428,19 +428,21 @@ class CameraSession(private val context: Context, private val cameraManager: Cam // Get actual device rotation from WindowManager since the React Native orientation hook // doesn't update when rotating between landscape-left and landscape-right on Android. - // Map device rotation to the correct orientationHint for video recording: - // - Counter-clockwise (ROTATION_90) → 270° hint - // - Clockwise (ROTATION_270) → 90° hint + // Map device rotation to the correct orientation for video recording. + // Surface.ROTATION_90 = device rotated 90° CCW = phone top on LEFT = LANDSCAPE_LEFT + // Surface.ROTATION_270 = device rotated 90° CW = phone top on RIGHT = LANDSCAPE_RIGHT val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager val deviceRotation = windowManager.defaultDisplay.rotation val recordingOrientation = when (deviceRotation) { Surface.ROTATION_0 -> Orientation.PORTRAIT - Surface.ROTATION_90 -> Orientation.LANDSCAPE_RIGHT + Surface.ROTATION_90 -> Orientation.LANDSCAPE_LEFT Surface.ROTATION_180 -> Orientation.PORTRAIT_UPSIDE_DOWN - Surface.ROTATION_270 -> Orientation.LANDSCAPE_LEFT + Surface.ROTATION_270 -> Orientation.LANDSCAPE_RIGHT else -> Orientation.PORTRAIT } + Log.i(TAG, "startRecording: orientation=${recordingOrientation.toDegrees()}° (deviceRotation=$deviceRotation)") + val recording = RecordingSession( context, cameraId, @@ -448,7 +450,7 @@ class CameraSession(private val context: Context, private val cameraManager: Cam enableAudio, fps, videoOutput.enableHdr, - orientation, + recordingOrientation, options, filePath, callback, diff --git a/package/android/src/main/java/com/mrousavy/camera/core/FragmentedRecordingManager.kt b/package/android/src/main/java/com/mrousavy/camera/core/FragmentedRecordingManager.kt index 64ac670..fc44441 100644 --- a/package/android/src/main/java/com/mrousavy/camera/core/FragmentedRecordingManager.kt +++ b/package/android/src/main/java/com/mrousavy/camera/core/FragmentedRecordingManager.kt @@ -39,8 +39,9 @@ class FragmentedRecordingManager( segmentDurationSeconds: Int = DEFAULT_SEGMENT_DURATION_SECONDS ): FragmentedRecordingManager { val mimeType = options.videoCodec.toMimeType() - val cameraOrientationDegrees = cameraOrientation.toDegrees() - val recordingOrientationDegrees = (options.orientation ?: Orientation.PORTRAIT).toDegrees() + // Use cameraOrientation (from WindowManager) for rotation metadata + // The options.orientation from JavaScript is unreliable on Android when rotating between landscape modes + val orientationDegrees = cameraOrientation.toDegrees() // Swap dimensions based on camera orientation, same as ChunkedRecordingManager val (width, height) = if (cameraOrientation.isLandscape()) { @@ -49,9 +50,7 @@ class FragmentedRecordingManager( size.width to size.height } - Log.d(TAG, "Input size: ${size.width}x${size.height}, encoder size: ${width}x${height}, " + - "cameraOrientation: $cameraOrientation ($cameraOrientationDegrees°), " + - "recordingOrientation: $recordingOrientationDegrees°") + Log.d(TAG, "Recording: ${width}x${height}, orientation=$orientationDegrees°") val format = MediaFormat.createVideoFormat(mimeType, width, height) val codec = MediaCodec.createEncoderByType(mimeType) @@ -71,11 +70,8 @@ class FragmentedRecordingManager( format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, segmentDurationSeconds) format.setInteger(MediaFormat.KEY_BIT_RATE, bitRate) - Log.d(TAG, "Video Format: $format, orientation: $recordingOrientationDegrees") - codec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE) - // Create muxer with callbacks, orientation, and fps val muxer = HlsMuxer( outputDirectory = outputDirectory, callback = object : HlsMuxer.Callback { @@ -87,13 +83,11 @@ class FragmentedRecordingManager( callbacks.onVideoChunkReady(file, index, durationUs) } }, - orientationDegrees = recordingOrientationDegrees, + orientationDegrees = orientationDegrees, fps = effectiveFps ) muxer.setSegmentDuration(segmentDurationSeconds * 1_000_000L) - Log.d(TAG, "Created HlsMuxer with orientation: $recordingOrientationDegrees degrees") - return FragmentedRecordingManager(codec, muxer) } }