Merge pull request #121 from Myzel394/fix-name

Fix empty file
This commit is contained in:
Myzel394 2024-09-07 22:18:46 +02:00 committed by GitHub
commit 193ecd15d2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 47 additions and 56 deletions

View File

@ -35,8 +35,8 @@ android {
applicationId "app.myzel394.alibi" applicationId "app.myzel394.alibi"
minSdk 24 minSdk 24
targetSdk 34 targetSdk 34
versionCode 15 versionCode 16
versionName "0.5.2" versionName "0.5.3"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables { vectorDrawables {
@ -97,7 +97,7 @@ dependencies {
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.8.4' implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.8.4'
implementation 'androidx.activity:activity-compose:1.9.1' implementation 'androidx.activity:activity-compose:1.9.1'
implementation 'androidx.activity:activity-ktx:1.9.1' implementation 'androidx.activity:activity-ktx:1.9.1'
implementation platform('androidx.compose:compose-bom:2024.06.00') implementation platform('androidx.compose:compose-bom:2024.09.00')
implementation 'androidx.compose.ui:ui' implementation 'androidx.compose.ui:ui'
implementation 'androidx.compose.ui:ui-graphics' implementation 'androidx.compose.ui:ui-graphics'
implementation 'androidx.compose.ui:ui-tooling-preview' implementation 'androidx.compose.ui:ui-tooling-preview'
@ -110,7 +110,7 @@ dependencies {
testImplementation 'junit:junit:4.13.2' testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.2.1' androidTestImplementation 'androidx.test.ext:junit:1.2.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
androidTestImplementation platform('androidx.compose:compose-bom:2024.06.00') androidTestImplementation platform('androidx.compose:compose-bom:2024.09.00')
androidTestImplementation 'androidx.compose.ui:ui-test-junit4' androidTestImplementation 'androidx.compose.ui:ui-test-junit4'
debugImplementation 'androidx.compose.ui:ui-tooling' debugImplementation 'androidx.compose.ui:ui-tooling'
debugImplementation 'androidx.compose.ui:ui-test-manifest' debugImplementation 'androidx.compose.ui:ui-test-manifest'
@ -121,7 +121,7 @@ dependencies {
annotationProcessor 'com.google.dagger:hilt-compiler:2.49' annotationProcessor 'com.google.dagger:hilt-compiler:2.49'
implementation "androidx.hilt:hilt-navigation-compose:1.2.0" implementation "androidx.hilt:hilt-navigation-compose:1.2.0"
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.1'
implementation 'com.arthenica:ffmpeg-kit-full-gpl:5.1' implementation 'com.arthenica:ffmpeg-kit-full-gpl:5.1'

View File

@ -40,18 +40,17 @@ class AudioBatchesFolder(
override fun getOutputFileForFFmpeg( override fun getOutputFileForFFmpeg(
date: LocalDateTime, date: LocalDateTime,
extension: String, extension: String,
fileName: String,
): String { ): String {
return when (type) { return when (type) {
BatchType.INTERNAL -> asInternalGetOutputFile(date, extension).absolutePath BatchType.INTERNAL -> asInternalGetOutputFile(fileName).absolutePath
BatchType.CUSTOM -> { BatchType.CUSTOM -> {
val name = getName(date, extension)
FFmpegKitConfig.getSafParameterForWrite( FFmpegKitConfig.getSafParameterForWrite(
context, context,
(customFolder!!.findFile(name) ?: customFolder.createFile( (customFolder!!.findFile(fileName) ?: customFolder.createFile(
"audio/${extension}", "audio/${extension}",
getName(date, extension), fileName,
)!!).uri )!!).uri
)!! )!!
} }
@ -59,7 +58,7 @@ class AudioBatchesFolder(
BatchType.MEDIA -> { BatchType.MEDIA -> {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val mediaUri = getOrCreateMediaFile( val mediaUri = getOrCreateMediaFile(
name = getName(date, extension), name = fileName,
mimeType = "audio/$extension", mimeType = "audio/$extension",
relativePath = BASE_SCOPED_STORAGE_RELATIVE_PATH + "/" + MEDIA_SUBFOLDER_NAME, relativePath = BASE_SCOPED_STORAGE_RELATIVE_PATH + "/" + MEDIA_SUBFOLDER_NAME,
) )
@ -72,7 +71,7 @@ class AudioBatchesFolder(
val path = arrayOf( val path = arrayOf(
Environment.getExternalStoragePublicDirectory(BASE_LEGACY_STORAGE_FOLDER), Environment.getExternalStoragePublicDirectory(BASE_LEGACY_STORAGE_FOLDER),
MEDIA_SUBFOLDER_NAME, MEDIA_SUBFOLDER_NAME,
getName(date, extension) fileName,
).joinToString("/") ).joinToString("/")
return File(path) return File(path)
.apply { .apply {
@ -143,7 +142,7 @@ class AudioBatchesFolder(
} }
val BASE_LEGACY_STORAGE_FOLDER = Environment.DIRECTORY_PODCASTS val BASE_LEGACY_STORAGE_FOLDER = Environment.DIRECTORY_PODCASTS
val MEDIA_RECORDINGS_SUBFOLDER = MEDIA_SUBFOLDER_NAME + "/audio_recordings" val MEDIA_RECORDINGS_SUBFOLDER = MEDIA_SUBFOLDER_NAME + "/.audio_recordings"
val BASE_SCOPED_STORAGE_RELATIVE_PATH = val BASE_SCOPED_STORAGE_RELATIVE_PATH =
(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) (if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
Environment.DIRECTORY_RECORDINGS Environment.DIRECTORY_RECORDINGS

View File

@ -191,8 +191,8 @@ abstract class BatchesFolder(
return "$name.$extension" return "$name.$extension"
} }
fun asInternalGetOutputFile(date: LocalDateTime, extension: String): File { fun asInternalGetOutputFile(fileName: String): File {
return File(getInternalFolder(), getName(date, extension)) return File(getInternalFolder(), fileName)
} }
fun asMediaGetLegacyFile(name: String): File = File( fun asMediaGetLegacyFile(name: String): File = File(
@ -203,16 +203,8 @@ abstract class BatchesFolder(
} }
fun checkIfOutputAlreadyExists( fun checkIfOutputAlreadyExists(
date: LocalDateTime, fileName: String,
extension: String
): Boolean { ): Boolean {
val stem = date
.format(DateTimeFormatter.ISO_DATE_TIME)
.toString()
.replace(":", "-")
.replace(".", "_")
val fileName = "$stem.$extension"
return when (type) { return when (type) {
BatchType.INTERNAL -> File(getInternalFolder(), fileName).exists() BatchType.INTERNAL -> File(getInternalFolder(), fileName).exists()
@ -245,6 +237,7 @@ abstract class BatchesFolder(
abstract fun getOutputFileForFFmpeg( abstract fun getOutputFileForFFmpeg(
date: LocalDateTime, date: LocalDateTime,
extension: String, extension: String,
fileName: String,
): String ): String
abstract fun cleanup() abstract fun cleanup()
@ -255,18 +248,17 @@ abstract class BatchesFolder(
disableCache: Boolean? = null, disableCache: Boolean? = null,
onNextParameterTry: (String) -> Unit = {}, onNextParameterTry: (String) -> Unit = {},
onProgress: (Float?) -> Unit = {}, onProgress: (Float?) -> Unit = {},
fileName: String,
): String { ): String {
val disableCache = disableCache ?: (type != BatchType.INTERNAL) val disableCache = disableCache ?: (type != BatchType.INTERNAL)
val date = recording.getStartDateForFilename(filenameFormat) val date = recording.getStartDateForFilename(filenameFormat)
if (!disableCache && checkIfOutputAlreadyExists( if (!disableCache && checkIfOutputAlreadyExists(fileName)
recording.recordingStart,
recording.fileExtension
)
) { ) {
return getOutputFileForFFmpeg( return getOutputFileForFFmpeg(
date = recording.recordingStart, date = recording.recordingStart,
extension = recording.fileExtension, extension = recording.fileExtension,
fileName = fileName,
) )
} }
@ -282,6 +274,7 @@ abstract class BatchesFolder(
val outputFile = getOutputFileForFFmpeg( val outputFile = getOutputFileForFFmpeg(
date = date, date = date,
extension = recording.fileExtension, extension = recording.fileExtension,
fileName = fileName,
) )
concatenationFunction( concatenationFunction(

View File

@ -39,18 +39,20 @@ class VideoBatchesFolder(
private var customParcelFileDescriptor: ParcelFileDescriptor? = null private var customParcelFileDescriptor: ParcelFileDescriptor? = null
override fun getOutputFileForFFmpeg(date: LocalDateTime, extension: String): String { override fun getOutputFileForFFmpeg(
date: LocalDateTime,
extension: String,
fileName: String,
): String {
return when (type) { return when (type) {
BatchType.INTERNAL -> asInternalGetOutputFile(date, extension).absolutePath BatchType.INTERNAL -> asInternalGetOutputFile(fileName).absolutePath
BatchType.CUSTOM -> { BatchType.CUSTOM -> {
val name = getName(date, extension)
FFmpegKitConfig.getSafParameterForWrite( FFmpegKitConfig.getSafParameterForWrite(
context, context,
(customFolder!!.findFile(name) ?: customFolder.createFile( (customFolder!!.findFile(fileName) ?: customFolder.createFile(
"video/${extension}", "video/${extension}",
getName(date, extension), fileName,
)!!).uri )!!).uri
)!! )!!
} }
@ -58,7 +60,7 @@ class VideoBatchesFolder(
BatchType.MEDIA -> { BatchType.MEDIA -> {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val mediaUri = getOrCreateMediaFile( val mediaUri = getOrCreateMediaFile(
name = getName(date, extension), name = fileName,
mimeType = "video/$extension", mimeType = "video/$extension",
relativePath = BASE_SCOPED_STORAGE_RELATIVE_PATH + "/" + MEDIA_SUBFOLDER_NAME, relativePath = BASE_SCOPED_STORAGE_RELATIVE_PATH + "/" + MEDIA_SUBFOLDER_NAME,
) )
@ -71,7 +73,7 @@ class VideoBatchesFolder(
val path = arrayOf( val path = arrayOf(
Environment.getExternalStoragePublicDirectory(BASE_LEGACY_STORAGE_FOLDER), Environment.getExternalStoragePublicDirectory(BASE_LEGACY_STORAGE_FOLDER),
MEDIA_SUBFOLDER_NAME, MEDIA_SUBFOLDER_NAME,
getName(date, extension) fileName,
).joinToString("/") ).joinToString("/")
return File(path) return File(path)
.apply { .apply {
@ -146,7 +148,7 @@ class VideoBatchesFolder(
} }
val BASE_LEGACY_STORAGE_FOLDER = Environment.DIRECTORY_DCIM val BASE_LEGACY_STORAGE_FOLDER = Environment.DIRECTORY_DCIM
val MEDIA_RECORDINGS_SUBFOLDER = MEDIA_SUBFOLDER_NAME + "/video_recordings" val MEDIA_RECORDINGS_SUBFOLDER = MEDIA_SUBFOLDER_NAME + "/.video_recordings"
val BASE_SCOPED_STORAGE_RELATIVE_PATH = Environment.DIRECTORY_DCIM val BASE_SCOPED_STORAGE_RELATIVE_PATH = Environment.DIRECTORY_DCIM
val SCOPED_STORAGE_RELATIVE_PATH = val SCOPED_STORAGE_RELATIVE_PATH =
BASE_SCOPED_STORAGE_RELATIVE_PATH + "/" + MEDIA_RECORDINGS_SUBFOLDER BASE_SCOPED_STORAGE_RELATIVE_PATH + "/" + MEDIA_RECORDINGS_SUBFOLDER

View File

@ -11,11 +11,11 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.ripple
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
@ -40,8 +40,8 @@ fun BigButton(
val orientation = LocalConfiguration.current.orientation val orientation = LocalConfiguration.current.orientation
BoxWithConstraints { BoxWithConstraints {
val isLarge = if (isBig == null) val isLarge = isBig
maxWidth > 250.dp && maxHeight > 600.dp && orientation == Configuration.ORIENTATION_PORTRAIT else isBig ?: (maxWidth > 250.dp && maxHeight > 600.dp && orientation == Configuration.ORIENTATION_PORTRAIT)
Column( Column(
modifier = Modifier modifier = Modifier
@ -52,7 +52,7 @@ fun BigButton(
} }
.combinedClickable( .combinedClickable(
interactionSource = remember { MutableInteractionSource() }, interactionSource = remember { MutableInteractionSource() },
indication = rememberRipple(color = MaterialTheme.colorScheme.primary), indication = ripple(color = MaterialTheme.colorScheme.primary),
onClick = onClick, onClick = onClick,
onLongClick = onLongClick, onLongClick = onLongClick,
), ),

View File

@ -6,10 +6,10 @@ import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.ripple
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
@ -39,7 +39,7 @@ fun SaveButton(
} }
.combinedClickable( .combinedClickable(
interactionSource = remember { MutableInteractionSource() }, interactionSource = remember { MutableInteractionSource() },
indication = rememberRipple(color = MaterialTheme.colorScheme.primary), indication = ripple(color = MaterialTheme.colorScheme.primary),
onClick = onSave, onClick = onSave,
onLongClick = onLongClick, onLongClick = onLongClick,
) )

View File

@ -76,6 +76,8 @@ fun RecordingStatus(
LinearProgressIndicator( LinearProgressIndicator(
progress = { progress }, progress = { progress },
modifier = progressModifier, modifier = progressModifier,
drawStopIndicator = { },
gapSize = 0.dp,
) )
} }

View File

@ -177,38 +177,33 @@ fun RecorderEventsHandler(
else -> throw Exception("Unknown recorder type") else -> throw Exception("Unknown recorder type")
} }
val fileName = batchesFolder.getName(
recording.recordingStart,
recording.fileExtension,
)
batchesFolder.concatenate( batchesFolder.concatenate(
recording, recording,
filenameFormat = settings.filenameFormat, filenameFormat = settings.filenameFormat,
fileName = fileName,
onProgress = { percentage -> onProgress = { percentage ->
processingProgress = percentage processingProgress = percentage
} }
) )
// Save file // Save file
val name = batchesFolder.getName(
recording.recordingStart,
recording.fileExtension,
)
when (batchesFolder.type) { when (batchesFolder.type) {
BatchesFolder.BatchType.INTERNAL -> { BatchesFolder.BatchType.INTERNAL -> {
when (batchesFolder) { when (batchesFolder) {
is AudioBatchesFolder -> { is AudioBatchesFolder -> {
saveAudioFile( saveAudioFile(
batchesFolder.asInternalGetOutputFile( batchesFolder.asInternalGetOutputFile(fileName), fileName
recording.recordingStart,
recording.fileExtension,
), name
) )
} }
is VideoBatchesFolder -> { is VideoBatchesFolder -> {
saveVideoFile( saveVideoFile(
batchesFolder.asInternalGetOutputFile( batchesFolder.asInternalGetOutputFile(fileName), fileName
recording.recordingStart,
recording.fileExtension,
), name
) )
} }
} }