use window manager to determine device rotation in android
This commit is contained in:
@@ -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
|
// 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.
|
// doesn't update when rotating between landscape-left and landscape-right on Android.
|
||||||
// Map device rotation to the correct orientationHint for video recording:
|
// Map device rotation to the correct orientation for video recording.
|
||||||
// - Counter-clockwise (ROTATION_90) → 270° hint
|
// Surface.ROTATION_90 = device rotated 90° CCW = phone top on LEFT = LANDSCAPE_LEFT
|
||||||
// - Clockwise (ROTATION_270) → 90° hint
|
// Surface.ROTATION_270 = device rotated 90° CW = phone top on RIGHT = LANDSCAPE_RIGHT
|
||||||
val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
|
val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
|
||||||
val deviceRotation = windowManager.defaultDisplay.rotation
|
val deviceRotation = windowManager.defaultDisplay.rotation
|
||||||
val recordingOrientation = when (deviceRotation) {
|
val recordingOrientation = when (deviceRotation) {
|
||||||
Surface.ROTATION_0 -> Orientation.PORTRAIT
|
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_180 -> Orientation.PORTRAIT_UPSIDE_DOWN
|
||||||
Surface.ROTATION_270 -> Orientation.LANDSCAPE_LEFT
|
Surface.ROTATION_270 -> Orientation.LANDSCAPE_RIGHT
|
||||||
else -> Orientation.PORTRAIT
|
else -> Orientation.PORTRAIT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.i(TAG, "startRecording: orientation=${recordingOrientation.toDegrees()}° (deviceRotation=$deviceRotation)")
|
||||||
|
|
||||||
val recording = RecordingSession(
|
val recording = RecordingSession(
|
||||||
context,
|
context,
|
||||||
cameraId,
|
cameraId,
|
||||||
@@ -448,7 +450,7 @@ class CameraSession(private val context: Context, private val cameraManager: Cam
|
|||||||
enableAudio,
|
enableAudio,
|
||||||
fps,
|
fps,
|
||||||
videoOutput.enableHdr,
|
videoOutput.enableHdr,
|
||||||
orientation,
|
recordingOrientation,
|
||||||
options,
|
options,
|
||||||
filePath,
|
filePath,
|
||||||
callback,
|
callback,
|
||||||
|
|||||||
@@ -39,8 +39,9 @@ class FragmentedRecordingManager(
|
|||||||
segmentDurationSeconds: Int = DEFAULT_SEGMENT_DURATION_SECONDS
|
segmentDurationSeconds: Int = DEFAULT_SEGMENT_DURATION_SECONDS
|
||||||
): FragmentedRecordingManager {
|
): FragmentedRecordingManager {
|
||||||
val mimeType = options.videoCodec.toMimeType()
|
val mimeType = options.videoCodec.toMimeType()
|
||||||
val cameraOrientationDegrees = cameraOrientation.toDegrees()
|
// Use cameraOrientation (from WindowManager) for rotation metadata
|
||||||
val recordingOrientationDegrees = (options.orientation ?: Orientation.PORTRAIT).toDegrees()
|
// 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
|
// Swap dimensions based on camera orientation, same as ChunkedRecordingManager
|
||||||
val (width, height) = if (cameraOrientation.isLandscape()) {
|
val (width, height) = if (cameraOrientation.isLandscape()) {
|
||||||
@@ -49,9 +50,7 @@ class FragmentedRecordingManager(
|
|||||||
size.width to size.height
|
size.width to size.height
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.d(TAG, "Input size: ${size.width}x${size.height}, encoder size: ${width}x${height}, " +
|
Log.d(TAG, "Recording: ${width}x${height}, orientation=$orientationDegrees°")
|
||||||
"cameraOrientation: $cameraOrientation ($cameraOrientationDegrees°), " +
|
|
||||||
"recordingOrientation: $recordingOrientationDegrees°")
|
|
||||||
|
|
||||||
val format = MediaFormat.createVideoFormat(mimeType, width, height)
|
val format = MediaFormat.createVideoFormat(mimeType, width, height)
|
||||||
val codec = MediaCodec.createEncoderByType(mimeType)
|
val codec = MediaCodec.createEncoderByType(mimeType)
|
||||||
@@ -71,11 +70,8 @@ class FragmentedRecordingManager(
|
|||||||
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, segmentDurationSeconds)
|
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, segmentDurationSeconds)
|
||||||
format.setInteger(MediaFormat.KEY_BIT_RATE, bitRate)
|
format.setInteger(MediaFormat.KEY_BIT_RATE, bitRate)
|
||||||
|
|
||||||
Log.d(TAG, "Video Format: $format, orientation: $recordingOrientationDegrees")
|
|
||||||
|
|
||||||
codec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE)
|
codec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE)
|
||||||
|
|
||||||
// Create muxer with callbacks, orientation, and fps
|
|
||||||
val muxer = HlsMuxer(
|
val muxer = HlsMuxer(
|
||||||
outputDirectory = outputDirectory,
|
outputDirectory = outputDirectory,
|
||||||
callback = object : HlsMuxer.Callback {
|
callback = object : HlsMuxer.Callback {
|
||||||
@@ -87,13 +83,11 @@ class FragmentedRecordingManager(
|
|||||||
callbacks.onVideoChunkReady(file, index, durationUs)
|
callbacks.onVideoChunkReady(file, index, durationUs)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
orientationDegrees = recordingOrientationDegrees,
|
orientationDegrees = orientationDegrees,
|
||||||
fps = effectiveFps
|
fps = effectiveFps
|
||||||
)
|
)
|
||||||
muxer.setSegmentDuration(segmentDurationSeconds * 1_000_000L)
|
muxer.setSegmentDuration(segmentDurationSeconds * 1_000_000L)
|
||||||
|
|
||||||
Log.d(TAG, "Created HlsMuxer with orientation: $recordingOrientationDegrees degrees")
|
|
||||||
|
|
||||||
return FragmentedRecordingManager(codec, muxer)
|
return FragmentedRecordingManager(codec, muxer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user