feat/refactor: добавил индикатор при просмотре кружков/гс, сделал запись кружков нормальным членом общества
This commit is contained in:
@@ -84,6 +84,7 @@ class MainActivity : FlutterActivity() {
|
||||
const val NFC_PHASE_MIN_MS = 350L
|
||||
const val NFC_PHASE_JITTER_MS = 400
|
||||
const val BLE_PERMS_REQUEST = 7711
|
||||
const val CAMERA_PERM_REQUEST = 7712
|
||||
val NFC_READER_FLAGS = NfcAdapter.FLAG_READER_NFC_A or
|
||||
NfcAdapter.FLAG_READER_NFC_B or
|
||||
NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK
|
||||
@@ -241,6 +242,7 @@ class MainActivity : FlutterActivity() {
|
||||
"ru.komet.app/video_note",
|
||||
).setMethodCallHandler { call, result ->
|
||||
when (call.method) {
|
||||
"permission" -> requestCameraPermission(result)
|
||||
"init" -> {
|
||||
val front = call.argument<Boolean>("front") ?: true
|
||||
val size = call.argument<Int>("size") ?: 480
|
||||
@@ -258,6 +260,10 @@ class MainActivity : FlutterActivity() {
|
||||
"start" -> noteRecorder?.start(result)
|
||||
?: result.error("NOT_READY", "recorder not initialized", null)
|
||||
"switch" -> noteRecorder?.switchCamera(result)
|
||||
"torch" -> noteRecorder?.setTorch(
|
||||
call.argument<Boolean>("on") ?: false,
|
||||
result,
|
||||
)
|
||||
?: result.error("NOT_READY", "recorder not initialized", null)
|
||||
"stop" -> noteRecorder?.stop(result)
|
||||
?: result.error("NOT_READY", "recorder not initialized", null)
|
||||
@@ -595,12 +601,42 @@ class MainActivity : FlutterActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private var cameraPermResult: MethodChannel.Result? = null
|
||||
|
||||
private fun requestCameraPermission(result: MethodChannel.Result) {
|
||||
val granted = ContextCompat.checkSelfPermission(
|
||||
this,
|
||||
Manifest.permission.CAMERA,
|
||||
) == PackageManager.PERMISSION_GRANTED
|
||||
if (granted) {
|
||||
result.success(true); return
|
||||
}
|
||||
if (cameraPermResult != null) {
|
||||
result.success(false); return
|
||||
}
|
||||
cameraPermResult = result
|
||||
ActivityCompat.requestPermissions(
|
||||
this,
|
||||
arrayOf(Manifest.permission.CAMERA),
|
||||
CAMERA_PERM_REQUEST,
|
||||
)
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(
|
||||
requestCode: Int,
|
||||
permissions: Array<out String>,
|
||||
grantResults: IntArray,
|
||||
) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
if (requestCode == CAMERA_PERM_REQUEST) {
|
||||
val pending = cameraPermResult
|
||||
cameraPermResult = null
|
||||
pending?.success(
|
||||
grantResults.isNotEmpty() &&
|
||||
grantResults.all { it == PackageManager.PERMISSION_GRANTED },
|
||||
)
|
||||
return
|
||||
}
|
||||
if (requestCode != BLE_PERMS_REQUEST) return
|
||||
if (!NfcExchange.active) return
|
||||
val granted = grantResults.isNotEmpty() &&
|
||||
|
||||
@@ -62,6 +62,9 @@ class VideoNoteRecorder(
|
||||
private var fpsRange: Range<Int>? = null
|
||||
private var hasOis = false
|
||||
private var hasEis = false
|
||||
private var hasFlash = false
|
||||
private var torchOn = false
|
||||
private var previewRequest: CaptureRequest.Builder? = null
|
||||
|
||||
private var cameraDevice: CameraDevice? = null
|
||||
private var session: CameraCaptureSession? = null
|
||||
@@ -119,6 +122,8 @@ class VideoNoteRecorder(
|
||||
)?.contains(
|
||||
CameraCharacteristics.CONTROL_VIDEO_STABILIZATION_MODE_ON,
|
||||
) == true
|
||||
hasFlash = ch.get(CameraCharacteristics.FLASH_INFO_AVAILABLE) == true
|
||||
if (!hasFlash) torchOn = false
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -310,13 +315,21 @@ class VideoNoteRecorder(
|
||||
CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE_ON,
|
||||
)
|
||||
}
|
||||
previewRequest = req
|
||||
applyTorch(req)
|
||||
s.setRepeatingRequest(req.build(), null, camHandler)
|
||||
Log.i(
|
||||
tag,
|
||||
"preview session configured fpsRange=$fpsRange " +
|
||||
"ois=$hasOis eis=$hasEis",
|
||||
"ois=$hasOis eis=$hasEis flash=$hasFlash",
|
||||
)
|
||||
result.success(
|
||||
mapOf(
|
||||
"textureId" to textureId,
|
||||
"size" to edge,
|
||||
"hasFlash" to hasFlash,
|
||||
),
|
||||
)
|
||||
result.success(mapOf("textureId" to textureId, "size" to edge))
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(tag, "preview session failed", e)
|
||||
@@ -377,6 +390,38 @@ class VideoNoteRecorder(
|
||||
// Смена камеры на лету (в т.ч. во время записи): GL-конвейер и
|
||||
// MediaRecorder не трогаем, пересоздаются только CameraDevice и сессия —
|
||||
// кадры новой камеры продолжают приходить в тот же SurfaceTexture.
|
||||
private fun applyTorch(req: CaptureRequest.Builder) {
|
||||
req.set(
|
||||
CaptureRequest.FLASH_MODE,
|
||||
if (torchOn && hasFlash) {
|
||||
CaptureRequest.FLASH_MODE_TORCH
|
||||
} else {
|
||||
CaptureRequest.FLASH_MODE_OFF
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fun setTorch(on: Boolean, result: MethodChannel.Result) {
|
||||
if (!hasFlash) {
|
||||
result.success(false); return
|
||||
}
|
||||
val s = session
|
||||
val req = previewRequest
|
||||
if (s == null || req == null) {
|
||||
result.error("NOT_READY", "no preview session", null); return
|
||||
}
|
||||
torchOn = on
|
||||
try {
|
||||
applyTorch(req)
|
||||
s.setRepeatingRequest(req.build(), null, camHandler)
|
||||
result.success(torchOn)
|
||||
} catch (e: Exception) {
|
||||
Log.e(tag, "torch failed", e)
|
||||
torchOn = false
|
||||
result.error("TORCH_FAILED", e.message, null)
|
||||
}
|
||||
}
|
||||
|
||||
fun switchCamera(rawResult: MethodChannel.Result) {
|
||||
val result = OnceResult(rawResult)
|
||||
if (cameraDevice == null || !glReady) {
|
||||
@@ -389,6 +434,7 @@ class VideoNoteRecorder(
|
||||
}
|
||||
try { session?.close() } catch (_: Exception) {}
|
||||
session = null
|
||||
previewRequest = null
|
||||
try { cameraDevice?.close() } catch (_: Exception) {}
|
||||
cameraDevice = null
|
||||
if (!selectCamera(newFacing)) {
|
||||
|
||||
Reference in New Issue
Block a user