feat: Add VideoFrameRate

This commit is contained in:
Myzel394 2023-12-02 17:50:54 +01:00
parent 9598cd45fa
commit e8d7b2b6f8
No known key found for this signature in database
GPG Key ID: 79CC92F37B3E1A2B
4 changed files with 143 additions and 2 deletions

View File

@ -419,6 +419,15 @@ data class VideoRecorderSettings(
50 * 1000 * 1000,
100 * 1000 * 1000,
)
val EXAMPLE_FRAME_RATE_VALUES = listOf(
null,
24,
30,
60,
120,
240,
)
}
}

View File

@ -0,0 +1,127 @@
package app.myzel394.alibi.ui.components.SettingsScreen.Tiles
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.BrokenImage
import androidx.compose.material.icons.filled.Tune
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.KeyboardType
import app.myzel394.alibi.R
import app.myzel394.alibi.dataStore
import app.myzel394.alibi.db.AppSettings
import app.myzel394.alibi.db.VideoRecorderSettings
import app.myzel394.alibi.ui.components.atoms.ExampleListRoulette
import app.myzel394.alibi.ui.components.atoms.SettingsTile
import app.myzel394.alibi.ui.utils.IconResource
import com.maxkeppeker.sheets.core.models.base.Header
import com.maxkeppeker.sheets.core.models.base.IconSource
import com.maxkeppeker.sheets.core.models.base.rememberUseCaseState
import com.maxkeppeler.sheets.input.InputDialog
import com.maxkeppeler.sheets.input.models.InputHeader
import com.maxkeppeler.sheets.input.models.InputSelection
import com.maxkeppeler.sheets.input.models.InputTextField
import com.maxkeppeler.sheets.input.models.InputTextFieldType
import com.maxkeppeler.sheets.input.models.ValidationResult
import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun VideoFrameRate(
settings: AppSettings,
) {
val scope = rememberCoroutineScope()
val showDialog = rememberUseCaseState()
val dataStore = LocalContext.current.dataStore
fun updateValue(frameRate: Int?) {
scope.launch {
dataStore.updateData {
it.setVideoRecorderSettings(
it.videoRecorderSettings.setTargetFrameRate(frameRate)
)
}
}
}
val notNumberLabel = stringResource(R.string.form_error_type_notNumber)
InputDialog(
state = showDialog,
header = Header.Default(
title = stringResource(R.string.ui_settings_option_videoTargetedFrameRate_title),
icon = IconSource(
painter = IconResource.fromImageVector(Icons.Default.Tune).asPainterResource(),
contentDescription = null,
)
),
selection = InputSelection(
input = listOf(
InputTextField(
header = InputHeader(
title = stringResource(id = R.string.ui_settings_option_videoTargetedFrameRate_explanation),
),
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Number,
),
type = InputTextFieldType.OUTLINED,
text = if (settings.videoRecorderSettings.targetFrameRate == null) "" else settings.videoRecorderSettings.targetFrameRate.toString(),
validationListener = { text ->
val frameRate = text?.toIntOrNull()
if (frameRate == null) {
return@InputTextField ValidationResult.Invalid(notNumberLabel)
}
ValidationResult.Valid
},
key = "framerate",
)
),
) { result ->
val frameRate = result.getString("framerate")?.toIntOrNull() ?: return@InputSelection
updateValue(frameRate)
}
)
SettingsTile(
title = stringResource(R.string.ui_settings_option_videoTargetedFrameRate_title),
leading = {
Icon(
Icons.Default.BrokenImage,
contentDescription = null,
)
},
trailing = {
Button(
onClick = showDialog::show,
colors = ButtonDefaults.filledTonalButtonColors(
containerColor = MaterialTheme.colorScheme.surfaceVariant,
),
shape = MaterialTheme.shapes.medium,
) {
if (settings.videoRecorderSettings.targetFrameRate == null)
Text(stringResource(R.string.ui_settings_value_auto_label))
else
Text(settings.videoRecorderSettings.targetFrameRate.toString())
}
},
extra = {
ExampleListRoulette(
items = VideoRecorderSettings.EXAMPLE_FRAME_RATE_VALUES,
onItemSelected = ::updateValue,
) { frameRate ->
Text(
frameRate?.toString() ?: stringResource(R.string.ui_settings_value_auto_label)
)
}
}
)
}

View File

@ -38,7 +38,7 @@ import app.myzel394.alibi.R
import app.myzel394.alibi.dataStore
import app.myzel394.alibi.ui.SUPPORTS_DARK_MODE_NATIVELY
import app.myzel394.alibi.ui.components.SettingsScreen.Tiles.AboutTile
import app.myzel394.alibi.ui.components.SettingsScreen.Tiles.VideoRecorderBitrateTile
import app.myzel394.alibi.ui.components.SettingsScreen.Tiles.VideoFrameRate
import app.myzel394.alibi.ui.components.SettingsScreen.Tiles.CustomNotificationTile
import app.myzel394.alibi.ui.components.SettingsScreen.Tiles.DeleteRecordingsImmediatelyTile
import app.myzel394.alibi.ui.components.SettingsScreen.Tiles.DividerTitle
@ -51,6 +51,7 @@ import app.myzel394.alibi.ui.components.SettingsScreen.Tiles.AudioRecorderOutput
import app.myzel394.alibi.ui.components.SettingsScreen.Tiles.AudioRecorderSamplingRateTile
import app.myzel394.alibi.ui.components.SettingsScreen.Tiles.SaveFolderTile
import app.myzel394.alibi.ui.components.SettingsScreen.Tiles.AudioRecorderShowAllMicrophonesTile
import app.myzel394.alibi.ui.components.SettingsScreen.Tiles.VideoRecorderBitrateTile
import app.myzel394.alibi.ui.components.SettingsScreen.atoms.ThemeSelector
import app.myzel394.alibi.ui.components.atoms.GlobalSwitch
import app.myzel394.alibi.ui.components.atoms.MessageBox
@ -163,7 +164,7 @@ fun SettingsScreen(
description = stringResource(R.string.ui_settings_sections_audio_description),
)
AudioRecorderShowAllMicrophonesTile(settings = settings)
VideoRecorderBitrateTile(settings = settings)
VideoFrameRate(settings = settings)
AudioRecorderSamplingRateTile(settings = settings)
AudioRecorderEncoderTile(
snackbarHostState = snackbarHostState,
@ -176,6 +177,7 @@ fun SettingsScreen(
description = stringResource(R.string.ui_settings_sections_video_description),
)
VideoRecorderBitrateTile(settings = settings)
VideoFrameRate(settings = settings)
}
Divider(
modifier = Modifier

View File

@ -128,4 +128,7 @@
<string name="ui_settings_option_videoTargetedBitrate_explanation">Bitrate for the video recording. Only applies to the video itself, not the audio. The actual bitrate may be different depending on what you will be recording.</string>
<string name="format_mbps">%s MB/s</string>
<string name="format_bps">%s B/s</string>
<string name="ui_settings_option_videoTargetedFrameRate_title">Targeted Frame Rate</string>
<string name="ui_settings_option_videoTargetedFrameRate_description">How many frames per second should be recorded.</string>
<string name="ui_settings_option_videoTargetedFrameRate_explanation">The actual frame rate may be different. This can for example happen if the device is not able to record with the specified frame rate.</string>
</resources>