From 7e3d356ff76e2d0beeb1d1d574d15acba1488354 Mon Sep 17 00:00:00 2001 From: Fabian Seitz Date: Tue, 23 Jan 2024 19:13:03 +0100 Subject: [PATCH 1/6] added buttonDescriptions to FileSelectorButton added video format check on video selection added fileChooserFilter to filter for certain File Extensions Signed-off-by: Fabian Seitz --- .../ui/components/general/FileSelector.kt | 7 ++++ .../ui/components/general/ProjectManager.kt | 8 +++- .../selectVideoScreen/FileSelectorButton.kt | 21 ++++++++-- .../kotlin/ui/screens/SelectVideoScreen.kt | 38 +++++++++++++++---- 4 files changed, 62 insertions(+), 12 deletions(-) diff --git a/GUI/src/main/kotlin/ui/components/general/FileSelector.kt b/GUI/src/main/kotlin/ui/components/general/FileSelector.kt index 4c852b55..e85c418d 100644 --- a/GUI/src/main/kotlin/ui/components/general/FileSelector.kt +++ b/GUI/src/main/kotlin/ui/components/general/FileSelector.kt @@ -1,6 +1,7 @@ package ui.components.general import javax.swing.JFileChooser +import javax.swing.filechooser.FileNameExtensionFilter /** * Opens a file chooser dialog and returns the selected file path. @@ -12,10 +13,16 @@ import javax.swing.JFileChooser fun openFileChooserAndGetPath( directoryPath: String?, onResult: (String) -> Unit, + allowedFileExtensions: Array? = null, ) { val fileChooser = JFileChooser() // set the current directory to the given directory path or if null the user's home directory fileChooser.currentDirectory = java.io.File(directoryPath ?: System.getProperty("user.home")) + if (allowedFileExtensions != null) { + fileChooser.isAcceptAllFileFilterUsed = false + val filter = FileNameExtensionFilter(allowedFileExtensions.joinToString(", "), *allowedFileExtensions) + fileChooser.addChoosableFileFilter(filter) + } val result = fileChooser.showOpenDialog(null) if (JFileChooser.APPROVE_OPTION == result) { onResult(fileChooser.selectedFile.absolutePath) diff --git a/GUI/src/main/kotlin/ui/components/general/ProjectManager.kt b/GUI/src/main/kotlin/ui/components/general/ProjectManager.kt index c084ff24..e79c1d90 100644 --- a/GUI/src/main/kotlin/ui/components/general/ProjectManager.kt +++ b/GUI/src/main/kotlin/ui/components/general/ProjectManager.kt @@ -65,7 +65,13 @@ fun ProjectMenu( onClick = { openScope.launch( Dispatchers.IO, - ) { openFileChooserAndGetPath(state.value.openProjectPath) { path -> handleOpenProject(state, path, errorDialogText) } } + ) { + openFileChooserAndGetPath( + directoryPath = state.value.openProjectPath, + onResult = { path -> handleOpenProject(state, path, errorDialogText) }, + allowedFileExtensions = arrayOf("json"), + ) + } expanded = false }, ) diff --git a/GUI/src/main/kotlin/ui/components/selectVideoScreen/FileSelectorButton.kt b/GUI/src/main/kotlin/ui/components/selectVideoScreen/FileSelectorButton.kt index 25d716f5..229d0553 100644 --- a/GUI/src/main/kotlin/ui/components/selectVideoScreen/FileSelectorButton.kt +++ b/GUI/src/main/kotlin/ui/components/selectVideoScreen/FileSelectorButton.kt @@ -38,13 +38,19 @@ fun RowScope.FileSelectorButton( onUpdateResult: (String) -> Unit, tooltipText: String? = null, directoryPath: String? = null, + buttonDescription: String? = null, + allowedFileExtensions: Array? = null, ) { val scope = rememberCoroutineScope() Button( modifier = Modifier.weight(1f).padding(8.dp).fillMaxHeight(1f), onClick = { scope.launch(Dispatchers.IO) { - openFileChooserAndGetPath(directoryPath) { path -> onUpdateResult(path) } + openFileChooserAndGetPath( + directoryPath, + { path -> onUpdateResult(path) }, + allowedFileExtensions, + ) } }, shape = MaterialTheme.shapes.medium, @@ -66,10 +72,17 @@ fun RowScope.FileSelectorButton( InfoIconWithHover(tooltipText) } } - // row to display the button text - Row(modifier = Modifier.weight(0.15f)) { - AutoSizeText(text = buttonText, minimalFontSize = 27) + + if (buttonDescription != null) { + // row to display the button text + Row(modifier = Modifier.weight(0.1f)) { AutoSizeText(text = buttonText, minimalFontSize = 27) } + // row to display the button description + Row(modifier = Modifier.weight(0.05f)) { AutoSizeText(text = buttonDescription) } + } else { + // row to display the button text + Row(modifier = Modifier.weight(0.15f)) { AutoSizeText(text = buttonText, minimalFontSize = 27) } } + // row to display the selected file path Row(modifier = Modifier.weight(0.1f)) { AutoSizeText(text = buttonPath ?: "No file selected", minimalFontSize = 25) diff --git a/GUI/src/main/kotlin/ui/screens/SelectVideoScreen.kt b/GUI/src/main/kotlin/ui/screens/SelectVideoScreen.kt index 88e1daa6..2e76b1c4 100644 --- a/GUI/src/main/kotlin/ui/screens/SelectVideoScreen.kt +++ b/GUI/src/main/kotlin/ui/screens/SelectVideoScreen.kt @@ -11,6 +11,7 @@ import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.ui.text.font.FontWeight import models.AppState +import ui.components.general.ErrorDialog import ui.components.general.HelpMenu import ui.components.general.ProjectMenu import ui.components.selectVideoScreen.AdvancedSettingsButton @@ -29,6 +30,9 @@ fun SelectVideoScreen(state: MutableState) { val scope = rememberCoroutineScope() val showLoadingDialog = remember { mutableStateOf(false) } + val referenceErrorDialogText = remember { mutableStateOf(null) } + val currentErrorDialogText = remember { mutableStateOf(null) } + Column(modifier = Modifier.fillMaxSize()) { // menu bar CenterAlignedTopAppBar( @@ -54,21 +58,27 @@ fun SelectVideoScreen(state: MutableState) { FileSelectorButton( buttonText = "Select Reference Video", buttonPath = state.value.videoReferencePath, - onUpdateResult = { selectedFilePath -> - state.value = state.value.copy(videoReferencePath = selectedFilePath) - }, + onUpdateResult = { selectedFilePath -> checkVideoFormat(selectedFilePath, state, referenceErrorDialogText) }, directoryPath = state.value.videoReferencePath, + buttonDescription = "Please upload a video with format mkv or mov.", + allowedFileExtensions = arrayOf("mkv", "mov"), ) - + if (referenceErrorDialogText.value != null) { + ErrorDialog(onCloseRequest = { referenceErrorDialogText.value = null }, text = referenceErrorDialogText.value!!) + } FileSelectorButton( buttonText = "Select Current Video", buttonPath = state.value.videoCurrentPath, - onUpdateResult = { selectedFilePath -> - state.value = state.value.copy(videoCurrentPath = selectedFilePath) - }, + onUpdateResult = { selectedFilePath -> checkVideoFormat(selectedFilePath, state, currentErrorDialogText) }, directoryPath = state.value.videoCurrentPath, + buttonDescription = "Please upload a video with format mkv or mov.", + allowedFileExtensions = arrayOf("mkv", "mov"), ) + if (currentErrorDialogText.value != null) { + ErrorDialog(onCloseRequest = { currentErrorDialogText.value = null }, text = currentErrorDialogText.value!!) + } } + // screen switch buttons Row(modifier = Modifier.weight(0.15f)) { ComputeDifferencesButton(state, scope, showLoadingDialog) @@ -82,3 +92,17 @@ fun SelectVideoScreen(state: MutableState) { }) } } + +// TODO: add a check for the video codec +private fun checkVideoFormat( + selectedFilePath: String, + state: MutableState, + errorDialogText: MutableState, +) { + if (selectedFilePath.endsWith(".mkv") || selectedFilePath.endsWith(".mov")) { + state.value = state.value.copy(videoCurrentPath = selectedFilePath) + } else { + errorDialogText.value = + "Uploaded Video is not in the correct format. Please upload a video with format mkv or mov." + } +} From 7b06f0b8b43880917523f12bc4fbaf2eb1f2d61f Mon Sep 17 00:00:00 2001 From: Fabian Seitz Date: Mon, 29 Jan 2024 05:41:41 +0100 Subject: [PATCH 2/6] - added check for video codec Signed-off-by: Fabian Seitz --- .../kotlin/ui/screens/SelectVideoScreen.kt | 50 +++++++++++++++---- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/GUI/src/main/kotlin/ui/screens/SelectVideoScreen.kt b/GUI/src/main/kotlin/ui/screens/SelectVideoScreen.kt index 2e76b1c4..90dc4428 100644 --- a/GUI/src/main/kotlin/ui/screens/SelectVideoScreen.kt +++ b/GUI/src/main/kotlin/ui/screens/SelectVideoScreen.kt @@ -11,6 +11,7 @@ import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.ui.text.font.FontWeight import models.AppState +import org.bytedeco.javacv.FFmpegFrameGrabber import ui.components.general.ErrorDialog import ui.components.general.HelpMenu import ui.components.general.ProjectMenu @@ -58,24 +59,44 @@ fun SelectVideoScreen(state: MutableState) { FileSelectorButton( buttonText = "Select Reference Video", buttonPath = state.value.videoReferencePath, - onUpdateResult = { selectedFilePath -> checkVideoFormat(selectedFilePath, state, referenceErrorDialogText) }, + onUpdateResult = { selectedFilePath -> + checkVideoFormatAndCodec( + selectedFilePath, + state, + referenceErrorDialogText, + true, + ) + }, directoryPath = state.value.videoReferencePath, buttonDescription = "Please upload a video with format mkv or mov.", allowedFileExtensions = arrayOf("mkv", "mov"), ) if (referenceErrorDialogText.value != null) { - ErrorDialog(onCloseRequest = { referenceErrorDialogText.value = null }, text = referenceErrorDialogText.value!!) + ErrorDialog( + onCloseRequest = { referenceErrorDialogText.value = null }, + text = referenceErrorDialogText.value!!, + ) } FileSelectorButton( buttonText = "Select Current Video", buttonPath = state.value.videoCurrentPath, - onUpdateResult = { selectedFilePath -> checkVideoFormat(selectedFilePath, state, currentErrorDialogText) }, + onUpdateResult = { selectedFilePath -> + checkVideoFormatAndCodec( + selectedFilePath, + state, + currentErrorDialogText, + false, + ) + }, directoryPath = state.value.videoCurrentPath, buttonDescription = "Please upload a video with format mkv or mov.", allowedFileExtensions = arrayOf("mkv", "mov"), ) if (currentErrorDialogText.value != null) { - ErrorDialog(onCloseRequest = { currentErrorDialogText.value = null }, text = currentErrorDialogText.value!!) + ErrorDialog( + onCloseRequest = { currentErrorDialogText.value = null }, + text = currentErrorDialogText.value!!, + ) } } @@ -93,16 +114,27 @@ fun SelectVideoScreen(state: MutableState) { } } -// TODO: add a check for the video codec -private fun checkVideoFormat( +private fun checkVideoFormatAndCodec( selectedFilePath: String, state: MutableState, errorDialogText: MutableState, + isReference: Boolean, ) { - if (selectedFilePath.endsWith(".mkv") || selectedFilePath.endsWith(".mov")) { - state.value = state.value.copy(videoCurrentPath = selectedFilePath) - } else { + if (!selectedFilePath.endsWith(".mkv") && !selectedFilePath.endsWith(".mov")) { errorDialogText.value = "Uploaded Video is not in the correct format. Please upload a video with format mkv or mov." + return + } + val grabber = FFmpegFrameGrabber(selectedFilePath) + grabber.start() + if (!(grabber.videoMetadata["encoder"] ?: grabber.videoCodecName).lowercase().contains("ffv1")) { + errorDialogText.value = + "Uploaded Video is not in the correct codec. Please upload a video encoded with ffv1." + return + } + if (isReference) { + state.value = state.value.copy(videoReferencePath = selectedFilePath) + } else { + state.value = state.value.copy(videoCurrentPath = selectedFilePath) } } From e8de42a61c99dbd4abba2f34a49662ef4371f5ae Mon Sep 17 00:00:00 2001 From: Fabian Seitz Date: Wed, 31 Jan 2024 04:15:19 +0100 Subject: [PATCH 3/6] -added active codec variable to lib2 and adapting gui codec check to it Signed-off-by: Fabian Seitz --- .../src/main/kotlin/AcceptedCodecs.kt | 7 ++++ .../settingsScreen/MaskSelectorButton.kt | 2 +- .../kotlin/ui/screens/SelectVideoScreen.kt | 39 +++++++------------ 3 files changed, 22 insertions(+), 26 deletions(-) diff --git a/DifferenceGenerator/src/main/kotlin/AcceptedCodecs.kt b/DifferenceGenerator/src/main/kotlin/AcceptedCodecs.kt index b69372f0..426545c2 100644 --- a/DifferenceGenerator/src/main/kotlin/AcceptedCodecs.kt +++ b/DifferenceGenerator/src/main/kotlin/AcceptedCodecs.kt @@ -17,5 +17,12 @@ class AcceptedCodecs { "Uncompressed YUV 422 8-bit", "FFV1 YUV 422 8-bit", ) + + val ACTIVE_CODECS = + setOf( + "ffv1", + "FFV1 YUV 422 8-bit", + ) + } } diff --git a/GUI/src/main/kotlin/ui/components/settingsScreen/MaskSelectorButton.kt b/GUI/src/main/kotlin/ui/components/settingsScreen/MaskSelectorButton.kt index cf05235e..9363fa00 100644 --- a/GUI/src/main/kotlin/ui/components/settingsScreen/MaskSelectorButton.kt +++ b/GUI/src/main/kotlin/ui/components/settingsScreen/MaskSelectorButton.kt @@ -40,7 +40,7 @@ fun RowScope.MaskSelectorButton( ) { val scope = rememberCoroutineScope() Button( - onClick = { scope.launch(Dispatchers.IO) { openFileChooserAndGetPath(directoryPath) { path -> onUpdateResult(path) } } }, + onClick = { scope.launch(Dispatchers.IO) { openFileChooserAndGetPath(directoryPath, {path -> onUpdateResult(path) }) } }, shape = MaterialTheme.shapes.medium, modifier = Modifier.padding(16.dp).weight(0.6f).fillMaxHeight(0.9f), ) { diff --git a/GUI/src/main/kotlin/ui/screens/SelectVideoScreen.kt b/GUI/src/main/kotlin/ui/screens/SelectVideoScreen.kt index 90dc4428..04992567 100644 --- a/GUI/src/main/kotlin/ui/screens/SelectVideoScreen.kt +++ b/GUI/src/main/kotlin/ui/screens/SelectVideoScreen.kt @@ -1,15 +1,11 @@ package ui.screens +import AcceptedCodecs import algorithms.AlgorithmExecutionState import androidx.compose.foundation.layout.* -import androidx.compose.material3.CenterAlignedTopAppBar -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.material.TopAppBar import androidx.compose.runtime.* import androidx.compose.ui.Modifier -import androidx.compose.ui.text.font.FontWeight import models.AppState import org.bytedeco.javacv.FFmpegFrameGrabber import ui.components.general.ErrorDialog @@ -25,7 +21,6 @@ import ui.components.selectVideoScreen.LoadingDialog * @param state [MutableState]<[AppState]> containing the global state. * @return [Unit] */ -@OptIn(ExperimentalMaterial3Api::class) @Composable fun SelectVideoScreen(state: MutableState) { val scope = rememberCoroutineScope() @@ -36,23 +31,16 @@ fun SelectVideoScreen(state: MutableState) { Column(modifier = Modifier.fillMaxSize()) { // menu bar - CenterAlignedTopAppBar( - title = { - Text( - text = "Select Video Screen", - style = MaterialTheme.typography.titleLarge, - color = MaterialTheme.colorScheme.secondary, - fontWeight = FontWeight.Bold, - ) - }, - navigationIcon = { - ProjectMenu(state) - }, - colors = TopAppBarDefaults.centerAlignedTopAppBarColors(), - actions = { - HelpMenu() - }, - ) + TopAppBar( + backgroundColor = androidx.compose.material3.MaterialTheme.colorScheme.primary, + contentColor = androidx.compose.material3.MaterialTheme.colorScheme.secondary, + ) { + Row(modifier = Modifier.fillMaxWidth()) { + ProjectMenu(state, Modifier.weight(0.1f)) + Spacer(modifier = Modifier.weight(0.8f)) + HelpMenu(Modifier.weight(0.1f)) + } + } // video selection Row(modifier = Modifier.weight(0.85f)) { @@ -110,6 +98,7 @@ fun SelectVideoScreen(state: MutableState) { if (showLoadingDialog.value) { LoadingDialog(onCancel = { AlgorithmExecutionState.getInstance().stop() + showLoadingDialog.value = false }) } } @@ -127,7 +116,7 @@ private fun checkVideoFormatAndCodec( } val grabber = FFmpegFrameGrabber(selectedFilePath) grabber.start() - if (!(grabber.videoMetadata["encoder"] ?: grabber.videoCodecName).lowercase().contains("ffv1")) { + if (!(grabber.videoMetadata["encoder"] in AcceptedCodecs.ACTIVE_CODECS || grabber.videoCodecName in AcceptedCodecs.ACTIVE_CODECS)) { errorDialogText.value = "Uploaded Video is not in the correct codec. Please upload a video encoded with ffv1." return From 6b7aefefd02fb5dd077d998b50cfcc597bc76d8d Mon Sep 17 00:00:00 2001 From: Fabian Seitz Date: Wed, 31 Jan 2024 10:24:00 +0100 Subject: [PATCH 4/6] - fixed rebase issues Signed-off-by: Fabian Seitz - fixed linting in lib 2 Signed-off-by: Fabian Seitz - fixed rebase issues - moved codec checking into lib2 - changed projectManager allowed file extensions from json to mkv Signed-off-by: Fabian Seitz --- .../src/main/kotlin/AcceptedCodecs.kt | 22 +++++-- .../ui/components/general/ProjectManager.kt | 2 +- .../settingsScreen/MaskSelectorButton.kt | 2 +- .../kotlin/ui/screens/SelectVideoScreen.kt | 58 +++++++++---------- 4 files changed, 46 insertions(+), 38 deletions(-) diff --git a/DifferenceGenerator/src/main/kotlin/AcceptedCodecs.kt b/DifferenceGenerator/src/main/kotlin/AcceptedCodecs.kt index 426545c2..60641a71 100644 --- a/DifferenceGenerator/src/main/kotlin/AcceptedCodecs.kt +++ b/DifferenceGenerator/src/main/kotlin/AcceptedCodecs.kt @@ -1,3 +1,5 @@ +import org.bytedeco.javacv.FFmpegFrameGrabber + /** * A globally accessible object that contains a list of all accepted codecs. This list can be * expanded to include more codecs. @@ -18,11 +20,19 @@ class AcceptedCodecs { "FFV1 YUV 422 8-bit", ) - val ACTIVE_CODECS = - setOf( - "ffv1", - "FFV1 YUV 422 8-bit", - ) - + public fun checkFile(path: String): Boolean { + if (!path.endsWith(".mkv") && !path.endsWith(".mov")) { + return false + } + val grabber = FFmpegFrameGrabber(path) + grabber.start() + val codecName = grabber.videoMetadata["encoder"] ?: grabber.videoCodecName + for (codec in ACCEPTED_CODECS) { + if (codecName.contains(codec, ignoreCase = true)) { + return true + } + } + return false + } } } diff --git a/GUI/src/main/kotlin/ui/components/general/ProjectManager.kt b/GUI/src/main/kotlin/ui/components/general/ProjectManager.kt index e79c1d90..16982b3d 100644 --- a/GUI/src/main/kotlin/ui/components/general/ProjectManager.kt +++ b/GUI/src/main/kotlin/ui/components/general/ProjectManager.kt @@ -69,7 +69,7 @@ fun ProjectMenu( openFileChooserAndGetPath( directoryPath = state.value.openProjectPath, onResult = { path -> handleOpenProject(state, path, errorDialogText) }, - allowedFileExtensions = arrayOf("json"), + allowedFileExtensions = arrayOf("mkv"), ) } expanded = false diff --git a/GUI/src/main/kotlin/ui/components/settingsScreen/MaskSelectorButton.kt b/GUI/src/main/kotlin/ui/components/settingsScreen/MaskSelectorButton.kt index 9363fa00..7a5dba69 100644 --- a/GUI/src/main/kotlin/ui/components/settingsScreen/MaskSelectorButton.kt +++ b/GUI/src/main/kotlin/ui/components/settingsScreen/MaskSelectorButton.kt @@ -40,7 +40,7 @@ fun RowScope.MaskSelectorButton( ) { val scope = rememberCoroutineScope() Button( - onClick = { scope.launch(Dispatchers.IO) { openFileChooserAndGetPath(directoryPath, {path -> onUpdateResult(path) }) } }, + onClick = { scope.launch(Dispatchers.IO) { openFileChooserAndGetPath(directoryPath, { path -> onUpdateResult(path) }) } }, shape = MaterialTheme.shapes.medium, modifier = Modifier.padding(16.dp).weight(0.6f).fillMaxHeight(0.9f), ) { diff --git a/GUI/src/main/kotlin/ui/screens/SelectVideoScreen.kt b/GUI/src/main/kotlin/ui/screens/SelectVideoScreen.kt index 04992567..8bdaebe7 100644 --- a/GUI/src/main/kotlin/ui/screens/SelectVideoScreen.kt +++ b/GUI/src/main/kotlin/ui/screens/SelectVideoScreen.kt @@ -3,11 +3,11 @@ package ui.screens import AcceptedCodecs import algorithms.AlgorithmExecutionState import androidx.compose.foundation.layout.* -import androidx.compose.material.TopAppBar +import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.Modifier +import androidx.compose.ui.text.font.FontWeight import models.AppState -import org.bytedeco.javacv.FFmpegFrameGrabber import ui.components.general.ErrorDialog import ui.components.general.HelpMenu import ui.components.general.ProjectMenu @@ -21,27 +21,34 @@ import ui.components.selectVideoScreen.LoadingDialog * @param state [MutableState]<[AppState]> containing the global state. * @return [Unit] */ +@OptIn(ExperimentalMaterial3Api::class) @Composable fun SelectVideoScreen(state: MutableState) { val scope = rememberCoroutineScope() val showLoadingDialog = remember { mutableStateOf(false) } - val referenceErrorDialogText = remember { mutableStateOf(null) } - val currentErrorDialogText = remember { mutableStateOf(null) } + val errorDialogText = remember { mutableStateOf(null) } + // val currentErrorDialogText = remember { mutableStateOf(null) } Column(modifier = Modifier.fillMaxSize()) { // menu bar - TopAppBar( - backgroundColor = androidx.compose.material3.MaterialTheme.colorScheme.primary, - contentColor = androidx.compose.material3.MaterialTheme.colorScheme.secondary, - ) { - Row(modifier = Modifier.fillMaxWidth()) { - ProjectMenu(state, Modifier.weight(0.1f)) - Spacer(modifier = Modifier.weight(0.8f)) - HelpMenu(Modifier.weight(0.1f)) - } - } - + CenterAlignedTopAppBar( + title = { + Text( + text = "Select Video Screen", + style = MaterialTheme.typography.titleLarge, + color = MaterialTheme.colorScheme.secondary, + fontWeight = FontWeight.Bold, + ) + }, + navigationIcon = { + ProjectMenu(state) + }, + colors = TopAppBarDefaults.centerAlignedTopAppBarColors(), + actions = { + HelpMenu() + }, + ) // video selection Row(modifier = Modifier.weight(0.85f)) { FileSelectorButton( @@ -51,7 +58,7 @@ fun SelectVideoScreen(state: MutableState) { checkVideoFormatAndCodec( selectedFilePath, state, - referenceErrorDialogText, + errorDialogText, true, ) }, @@ -59,10 +66,10 @@ fun SelectVideoScreen(state: MutableState) { buttonDescription = "Please upload a video with format mkv or mov.", allowedFileExtensions = arrayOf("mkv", "mov"), ) - if (referenceErrorDialogText.value != null) { + if (errorDialogText.value != null) { ErrorDialog( - onCloseRequest = { referenceErrorDialogText.value = null }, - text = referenceErrorDialogText.value!!, + onCloseRequest = { errorDialogText.value = null }, + text = errorDialogText.value!!, ) } FileSelectorButton( @@ -72,7 +79,7 @@ fun SelectVideoScreen(state: MutableState) { checkVideoFormatAndCodec( selectedFilePath, state, - currentErrorDialogText, + errorDialogText, false, ) }, @@ -80,12 +87,6 @@ fun SelectVideoScreen(state: MutableState) { buttonDescription = "Please upload a video with format mkv or mov.", allowedFileExtensions = arrayOf("mkv", "mov"), ) - if (currentErrorDialogText.value != null) { - ErrorDialog( - onCloseRequest = { currentErrorDialogText.value = null }, - text = currentErrorDialogText.value!!, - ) - } } // screen switch buttons @@ -98,7 +99,6 @@ fun SelectVideoScreen(state: MutableState) { if (showLoadingDialog.value) { LoadingDialog(onCancel = { AlgorithmExecutionState.getInstance().stop() - showLoadingDialog.value = false }) } } @@ -114,9 +114,7 @@ private fun checkVideoFormatAndCodec( "Uploaded Video is not in the correct format. Please upload a video with format mkv or mov." return } - val grabber = FFmpegFrameGrabber(selectedFilePath) - grabber.start() - if (!(grabber.videoMetadata["encoder"] in AcceptedCodecs.ACTIVE_CODECS || grabber.videoCodecName in AcceptedCodecs.ACTIVE_CODECS)) { + if (!AcceptedCodecs.checkFile(selectedFilePath)) { errorDialogText.value = "Uploaded Video is not in the correct codec. Please upload a video encoded with ffv1." return From 23cae4e376cec92ad95de443874790c434efa331 Mon Sep 17 00:00:00 2001 From: Fabian Seitz Date: Wed, 31 Jan 2024 10:41:59 +0100 Subject: [PATCH 5/6] - only check for codec in lib2 - replaced isLosslessCodec in DifferenceGenerator with checkFile Signed-off-by: Fabian Seitz --- .../src/main/kotlin/AcceptedCodecs.kt | 3 --- .../src/main/kotlin/DifferenceGenerator.kt | 16 +--------------- .../main/kotlin/ui/screens/SelectVideoScreen.kt | 1 - 3 files changed, 1 insertion(+), 19 deletions(-) diff --git a/DifferenceGenerator/src/main/kotlin/AcceptedCodecs.kt b/DifferenceGenerator/src/main/kotlin/AcceptedCodecs.kt index 60641a71..83c0bd57 100644 --- a/DifferenceGenerator/src/main/kotlin/AcceptedCodecs.kt +++ b/DifferenceGenerator/src/main/kotlin/AcceptedCodecs.kt @@ -21,9 +21,6 @@ class AcceptedCodecs { ) public fun checkFile(path: String): Boolean { - if (!path.endsWith(".mkv") && !path.endsWith(".mov")) { - return false - } val grabber = FFmpegFrameGrabber(path) grabber.start() val codecName = grabber.videoMetadata["encoder"] ?: grabber.videoCodecName diff --git a/DifferenceGenerator/src/main/kotlin/DifferenceGenerator.kt b/DifferenceGenerator/src/main/kotlin/DifferenceGenerator.kt index 635ec18e..7e3e1985 100644 --- a/DifferenceGenerator/src/main/kotlin/DifferenceGenerator.kt +++ b/DifferenceGenerator/src/main/kotlin/DifferenceGenerator.kt @@ -46,7 +46,7 @@ class DifferenceGenerator( * @throws DifferenceGeneratorDimensionException if the videos' dimensions don't match. */ init { - if (!isLosslessCodec(videoReferenceGrabber) || !isLosslessCodec(videoCurrentGrabber)) { + if (!AcceptedCodecs.checkFile(videoReferencePath) || !AcceptedCodecs.checkFile(videoCurrentPath)) { throw DifferenceGeneratorCodecException("Videos must be in a lossless codec") } @@ -73,20 +73,6 @@ class DifferenceGenerator( avutil.av_log_set_level(avutil.AV_LOG_QUIET) } - /** - * Determines whether the given video file is encoded using one of the - * [AcceptedCodecs.ACCEPTED_CODECS]. - * - * @param grabber [MaskedImageGrabber] of the video to check - * @return true if the video file is encoded using one of the [AcceptedCodecs.ACCEPTED_CODECS], - * false otherwise - */ - private fun isLosslessCodec(grabber: MaskedImageGrabber): Boolean { - grabber.start() - val codecName = grabber.videoMetadata["encoder"] ?: grabber.videoCodecName - return codecName in AcceptedCodecs.ACCEPTED_CODECS - } - /** * Generates a difference video from the two videos given in the constructor. * diff --git a/GUI/src/main/kotlin/ui/screens/SelectVideoScreen.kt b/GUI/src/main/kotlin/ui/screens/SelectVideoScreen.kt index 8bdaebe7..2399019f 100644 --- a/GUI/src/main/kotlin/ui/screens/SelectVideoScreen.kt +++ b/GUI/src/main/kotlin/ui/screens/SelectVideoScreen.kt @@ -28,7 +28,6 @@ fun SelectVideoScreen(state: MutableState) { val showLoadingDialog = remember { mutableStateOf(false) } val errorDialogText = remember { mutableStateOf(null) } - // val currentErrorDialogText = remember { mutableStateOf(null) } Column(modifier = Modifier.fillMaxSize()) { // menu bar From 9d64f1888685b42b80c0d82c7a93bd5d4af1299c Mon Sep 17 00:00:00 2001 From: Fabian Seitz Date: Wed, 31 Jan 2024 10:48:06 +0100 Subject: [PATCH 6/6] -added docStrings Signed-off-by: Fabian Seitz --- DifferenceGenerator/src/main/kotlin/AcceptedCodecs.kt | 3 +++ GUI/src/main/kotlin/ui/screens/SelectVideoScreen.kt | 3 +++ 2 files changed, 6 insertions(+) diff --git a/DifferenceGenerator/src/main/kotlin/AcceptedCodecs.kt b/DifferenceGenerator/src/main/kotlin/AcceptedCodecs.kt index 83c0bd57..40cc19c3 100644 --- a/DifferenceGenerator/src/main/kotlin/AcceptedCodecs.kt +++ b/DifferenceGenerator/src/main/kotlin/AcceptedCodecs.kt @@ -20,6 +20,9 @@ class AcceptedCodecs { "FFV1 YUV 422 8-bit", ) + /** + * Checks if the given file is in an accepted codec. + */ public fun checkFile(path: String): Boolean { val grabber = FFmpegFrameGrabber(path) grabber.start() diff --git a/GUI/src/main/kotlin/ui/screens/SelectVideoScreen.kt b/GUI/src/main/kotlin/ui/screens/SelectVideoScreen.kt index 2399019f..fd8b9a87 100644 --- a/GUI/src/main/kotlin/ui/screens/SelectVideoScreen.kt +++ b/GUI/src/main/kotlin/ui/screens/SelectVideoScreen.kt @@ -102,6 +102,9 @@ fun SelectVideoScreen(state: MutableState) { } } +/** + * Checks if the selected file is in the correct format and codec. + */ private fun checkVideoFormatAndCodec( selectedFilePath: String, state: MutableState,