mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-09-30 13:19:44 +02:00
Add Hi-Res authenticity check
Introduce a per-file Hi-Res authenticity checker and optional auto re-download for flagged fake Hi-Res downloads. Adds Rust checker modules (fft, evidence, FLAC/WAV decoding, tests) and a mobile API (check_hires_authenticity). Wire platform bindings for Android/iOS and PlatformBridge. Add Dart HiResCheckService, UI HiResCheckCard, settings toggle (redownloadFakeHiRes) and integration in the download pipeline to quarantine and replace suspicious files with LOSSLESS when safe. Adds claxon FLAC dependency.
This commit is contained in:
1 parent
83bd55bb64
commit
14ce4bc868
33 files changed
+3012
-2
No files matched your search
@@ -195,6 +195,7 @@ internal interface CoreBackend {
|
||||
fun sanitizeFilename(filename: String): String
|
||||
fun fileMetadataImplementation(path: String): String
|
||||
fun readFileMetadata(path: String, hint: String): String
|
||||
fun checkHiResAuthenticity(path: String, optionsJson: String): String
|
||||
fun readAudioMetadata(path: String, hint: String, cacheKey: String): String
|
||||
fun setLibraryCoverCacheDirectory(path: String)
|
||||
fun scanLibraryFolder(folder: String): String
|
||||
|
||||
@@ -86,6 +86,7 @@ class MainActivity: FlutterFragmentActivity() {
|
||||
"runPostProcessingV2",
|
||||
"readAudioMetadata",
|
||||
"readFileMetadata",
|
||||
"checkHiResAuthenticity",
|
||||
"editFileMetadata",
|
||||
"reEnrichFile",
|
||||
"setLibraryCoverCacheDir",
|
||||
@@ -1442,6 +1443,24 @@ class MainActivity: FlutterFragmentActivity() {
|
||||
}
|
||||
result.success(response)
|
||||
}
|
||||
"checkHiResAuthenticity" -> {
|
||||
val filePath = call.argument<String>("file_path") ?: ""
|
||||
val optionsJson = call.argument<String>("options_json") ?: ""
|
||||
val response = withContext(Dispatchers.IO) {
|
||||
try {
|
||||
if (filePath.startsWith("content://")) {
|
||||
checkHiResAuthenticityFromUri(Uri.parse(filePath), optionsJson)
|
||||
?.toString()
|
||||
?: errorJson("Failed to read SAF audio file")
|
||||
} else {
|
||||
coreBackend.checkHiResAuthenticity(filePath, optionsJson)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
errorJson(e.message ?: "Hi-Res check failed")
|
||||
}
|
||||
}
|
||||
result.success(response)
|
||||
}
|
||||
"editFileMetadata" -> {
|
||||
val filePath = call.argument<String>("file_path") ?: ""
|
||||
val metadataJson = call.argument<String>("metadata_json") ?: "{}"
|
||||
|
||||
@@ -299,6 +299,15 @@ internal fun MainActivity.readAudioMetadataFromUri(
|
||||
obj.takeUnless { it.has("error") }
|
||||
}
|
||||
|
||||
/** The Hi-Res check reads only a window from the middle of the file, so a
|
||||
* seekable descriptor avoids copying the whole track out of SAF. */
|
||||
internal fun MainActivity.checkHiResAuthenticityFromUri(
|
||||
uri: Uri,
|
||||
optionsJson: String,
|
||||
): JSONObject? = readMetadataFromUri(uri) { path, _ ->
|
||||
JSONObject(coreBackend.checkHiResAuthenticity(path, optionsJson))
|
||||
}?.put("file_path", uri.toString())
|
||||
|
||||
internal fun MainActivity.readCompleteMetadataFromUri(
|
||||
uri: Uri,
|
||||
displayNameHint: String? = null,
|
||||
|
||||
@@ -218,6 +218,9 @@ internal object RustCoreBackend : CoreBackend {
|
||||
override fun readFileMetadata(path: String, hint: String): String =
|
||||
com.spotiflac.backend.readFileMetadata(path, hint, null)
|
||||
|
||||
override fun checkHiResAuthenticity(path: String, optionsJson: String): String =
|
||||
com.spotiflac.backend.checkHiresAuthenticity(path, optionsJson, null)
|
||||
|
||||
override fun readAudioMetadata(path: String, hint: String, cacheKey: String): String =
|
||||
owner().readAudioMetadata(File(path).canonicalPath, hint, cacheKey, null)
|
||||
|
||||
|
||||
Reference in new issue
Block a user