feat: Add poc

This commit is contained in:
Myzel394 2023-11-25 14:30:34 +01:00
parent 82116bc089
commit 63198c316e
No known key found for this signature in database
GPG Key ID: 79CC92F37B3E1A2B
5 changed files with 153 additions and 4 deletions

View File

@ -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}"
}

View File

@ -13,6 +13,9 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CAMERA" />
<application
android:name=".UpdateSettingsApp"
android:allowBackup="true"
@ -23,6 +26,7 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Alibi"
android:hardwareAccelerated="true"
tools:targetApi="31">
<activity
android:name=".MainActivity"
@ -43,9 +47,13 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<service
android:name=".services.AudioRecorderService"
android:foregroundServiceType="microphone" />
<service
android:name=".services.VideoService"
android:foregroundServiceType="camera" />
<!-- Change locale for Android <= 12 -->
<service

View File

@ -0,0 +1,111 @@
package app.myzel394.alibi.services
import android.annotation.SuppressLint
import android.content.ContentValues
import android.content.pm.ServiceInfo
import android.graphics.SurfaceTexture
import android.hardware.Camera
import android.os.Build
import android.provider.MediaStore
import android.view.Surface
import android.view.TextureView
import android.view.ViewGroup
import androidx.camera.core.CameraProvider
import androidx.camera.core.CameraSelector
import androidx.camera.core.Preview
import androidx.camera.core.Preview.SurfaceProvider
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.camera.video.MediaStoreOutputOptions
import androidx.camera.video.Quality
import androidx.camera.video.QualitySelector
import androidx.camera.video.Recorder
import androidx.camera.video.VideoCapture.withOutput
import androidx.camera.video.VideoRecordEvent
import androidx.core.app.NotificationCompat
import androidx.core.app.ServiceCompat
import androidx.core.content.ContextCompat
import androidx.lifecycle.LifecycleService
import app.myzel394.alibi.NotificationHelper
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
class VideoService : LifecycleService() {
private var job = SupervisorJob()
private var scope = CoroutineScope(Dispatchers.IO + job)
private fun createMediaStoreOutputOptions(): MediaStoreOutputOptions {
val name = "CameraX-recording.mp4"
val contentValues = ContentValues().apply {
put(MediaStore.Video.Media.DISPLAY_NAME, name)
if (Build.VERSION.SDK_INT >= 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))
}
}

View File

@ -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,

View File

@ -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")
}