mirror of
https://github.com/Myzel394/Alibi.git
synced 2025-06-18 23:05:26 +02:00
feat: Add VideoFrameRate
This commit is contained in:
parent
9598cd45fa
commit
e8d7b2b6f8
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
@ -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
|
||||
|
@ -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>
|
Loading…
x
Reference in New Issue
Block a user