From 63198c316e722246900026ddaf09ece5f30ab251 Mon Sep 17 00:00:00 2001
From: Myzel394 <50424412+Myzel394@users.noreply.github.com>
Date: Sat, 25 Nov 2023 14:30:34 +0100
Subject: [PATCH] feat: Add poc
---
app/build.gradle | 11 ++
app/src/main/AndroidManifest.xml | 8 ++
.../myzel394/alibi/services/VideoService.kt | 111 ++++++++++++++++++
.../java/app/myzel394/alibi/ui/Navigation.kt | 6 +-
.../app/myzel394/alibi/ui/screens/POCVideo.kt | 21 ++++
5 files changed, 153 insertions(+), 4 deletions(-)
create mode 100644 app/src/main/java/app/myzel394/alibi/services/VideoService.kt
create mode 100644 app/src/main/java/app/myzel394/alibi/ui/screens/POCVideo.kt
diff --git a/app/build.gradle b/app/build.gradle
index df77255..8f5b385 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -79,6 +79,7 @@ android {
buildFeatures {
compose true
buildConfig = true
+ viewBinding = true
}
composeOptions {
kotlinCompilerExtensionVersion '1.5.1'
@@ -103,6 +104,7 @@ dependencies {
implementation "androidx.compose.material:material-icons-extended:1.5.4"
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.documentfile:documentfile:1.0.1'
+ implementation 'androidx.lifecycle:lifecycle-service:2.6.2'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
@@ -131,4 +133,13 @@ dependencies {
implementation 'com.maxkeppeler.sheets-compose-dialogs:input:1.2.0'
implementation 'androidx.activity:activity-ktx:1.8.1'
+
+ def camerax_version = "1.3.0"
+ implementation "androidx.camera:camera-core:${camerax_version}"
+ implementation "androidx.camera:camera-camera2:${camerax_version}"
+ implementation "androidx.camera:camera-lifecycle:${camerax_version}"
+ implementation "androidx.camera:camera-video:${camerax_version}"
+
+ implementation "androidx.camera:camera-view:${camerax_version}"
+ implementation "androidx.camera:camera-extensions:${camerax_version}"
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 8f67b7c..c0254e2 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -13,6 +13,9 @@
+
+
+
+
+
= Build.VERSION_CODES.Q) {
+ put(MediaStore.MediaColumns.RELATIVE_PATH, "DCIM/Recorded Videos")
+ }
+ }
+ return MediaStoreOutputOptions.Builder(
+ contentResolver,
+ MediaStore.Video.Media.EXTERNAL_CONTENT_URI
+ )
+ .setContentValues(contentValues)
+ .build()
+ }
+
+ @SuppressLint("MissingPermission")
+ override fun onCreate() {
+ super.onCreate()
+
+ val notification = NotificationCompat.Builder(
+ this,
+ NotificationHelper.RECORDER_CHANNEL_ID
+ ).setContentTitle("Video Recorder")
+ .setContentText("Recording video")
+ .setSmallIcon(android.R.drawable.ic_media_play)
+ .build()
+
+ ServiceCompat.startForeground(
+ this,
+ NotificationHelper.RECORDER_CHANNEL_NOTIFICATION_ID,
+ notification,
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+ ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA
+ } else {
+ 0
+ },
+ )
+
+ val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
+ cameraProviderFuture.addListener({
+ // Used to bind the lifecycle of cameras to the lifecycle owner
+ val cameraProvider = cameraProviderFuture.get()
+ val recorder = Recorder.Builder()
+ .setQualitySelector(QualitySelector.from(Quality.HIGHEST))
+ .build()
+ val videoCapture = withOutput(recorder)
+ // Select back camera as a default
+ val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
+
+ // Unbind use cases before rebinding
+ cameraProvider?.unbindAll()
+ // Bind use cases to camera
+ cameraProvider?.bindToLifecycle(this@VideoService, cameraSelector, videoCapture)
+
+ val options = createMediaStoreOutputOptions()
+
+ val recording = videoCapture.output.prepareRecording(this@VideoService, options)
+ .withAudioEnabled()
+
+ val result = recording.start(ContextCompat.getMainExecutor(this@VideoService), {})
+
+ scope.launch {
+ delay(15000)
+
+ result.stop()
+
+ cameraProvider.unbindAll()
+ stopSelf()
+ }
+ }, ContextCompat.getMainExecutor(this))
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/app/myzel394/alibi/ui/Navigation.kt b/app/src/main/java/app/myzel394/alibi/ui/Navigation.kt
index 985e79d..09384ad 100644
--- a/app/src/main/java/app/myzel394/alibi/ui/Navigation.kt
+++ b/app/src/main/java/app/myzel394/alibi/ui/Navigation.kt
@@ -24,6 +24,7 @@ import app.myzel394.alibi.ui.models.AudioRecorderModel
import app.myzel394.alibi.ui.screens.AboutScreen
import app.myzel394.alibi.ui.screens.AudioRecorderScreen
import app.myzel394.alibi.ui.screens.CustomRecordingNotificationsScreen
+import app.myzel394.alibi.ui.screens.POCVideo
import app.myzel394.alibi.ui.screens.SettingsScreen
import app.myzel394.alibi.ui.screens.WelcomeScreen
@@ -70,10 +71,7 @@ fun Navigation(
scaleOut(targetScale = SCALE_IN) + fadeOut(tween(durationMillis = 150))
}
) {
- AudioRecorderScreen(
- navController = navController,
- audioRecorder = audioRecorder,
- )
+ POCVideo()
}
composable(
Screen.Settings.route,
diff --git a/app/src/main/java/app/myzel394/alibi/ui/screens/POCVideo.kt b/app/src/main/java/app/myzel394/alibi/ui/screens/POCVideo.kt
new file mode 100644
index 0000000..75b0f20
--- /dev/null
+++ b/app/src/main/java/app/myzel394/alibi/ui/screens/POCVideo.kt
@@ -0,0 +1,21 @@
+package app.myzel394.alibi.ui.screens
+
+import android.content.Intent
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.ui.platform.LocalContext
+import androidx.core.content.ContextCompat
+import app.myzel394.alibi.services.VideoService
+
+@Composable
+fun POCVideo() {
+ val context = LocalContext.current
+
+ LaunchedEffect(Unit) {
+ val intent = Intent(context, VideoService::class.java)
+ ContextCompat.startForegroundService(context, intent)
+ }
+
+ Text(text = "POCVideo")
+}
\ No newline at end of file