mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-10-20 14:37:33 +02:00
refactor(android): move finalizer post-processing into NativeFinalizerPostProcess.kt
Move the extension post-processing hook stage out of NativeDownloadFinalizer into a sibling file as an extension function. The body is verbatim. The shared materializeForFFmpeg and replaceStatePath helpers stay on the object because every stage uses them, and no object member needed wider visibility.
This commit is contained in:
1 parent
0b4725c2c0
commit
631b9aa5e8
2 files changed
+94
-85
No files matched your search
@@ -424,91 +424,6 @@ object NativeDownloadFinalizer {
|
||||
}
|
||||
}
|
||||
|
||||
private fun runPostProcessing(
|
||||
context: Context,
|
||||
input: FinalizeInput,
|
||||
state: FinalizeState,
|
||||
shouldCancel: () -> Boolean,
|
||||
) {
|
||||
if (!input.request.optBoolean("post_processing_enabled", false)) return
|
||||
val metadata = JSONObject()
|
||||
.put("title", trackString(input, "name", input.request.optString("track_name", "")))
|
||||
.put("artist", trackString(input, "artistName", input.request.optString("artist_name", "")))
|
||||
.put("album", trackString(input, "albumName", input.request.optString("album_name", "")))
|
||||
.put("album_artist", resolvedAlbumArtist(input))
|
||||
.put("track_number", trackInt(input, "trackNumber", input.request.optInt("track_number", 0)))
|
||||
.put("disc_number", trackInt(input, "discNumber", input.request.optInt("disc_number", 0)))
|
||||
.put("isrc", trackString(input, "isrc", input.request.optString("isrc", "")))
|
||||
.put("release_date", trackString(input, "releaseDate", input.request.optString("release_date", "")))
|
||||
.put("duration_ms", trackInt(input, "duration", 0) * 1000)
|
||||
.put("cover_url", metadataCoverUrl(input))
|
||||
|
||||
if (state.filePath.startsWith("content://")) {
|
||||
val uri = state.filePath
|
||||
val tempInput = SafDownloadHandler.copyContentUriToTemp(context, uri)
|
||||
?: throw IllegalStateException("failed to copy SAF file for post-processing")
|
||||
try {
|
||||
val inputObj = JSONObject()
|
||||
.put("item_id", input.itemId)
|
||||
.put("path", tempInput)
|
||||
.put("uri", uri)
|
||||
.put("name", state.fileName)
|
||||
.put("mime_type", mimeTypeForExt(state.fileName.substringAfterLast('.', "")))
|
||||
.put("size", File(tempInput).length())
|
||||
.put("is_saf", true)
|
||||
checkCancelled(shouldCancel)
|
||||
val response = JSONObject(createCoreBackend(context).runPostProcessing(inputObj.toString(), metadata.toString()))
|
||||
checkCancelled(shouldCancel)
|
||||
if (!response.optBoolean("success", false)) return
|
||||
val newPath = response.optString("new_file_path", "")
|
||||
val outputPath = newPath.ifBlank { tempInput }
|
||||
val outputFile = File(outputPath)
|
||||
if (!outputFile.exists()) return
|
||||
val outputName = if (newPath.isBlank()) state.fileName else outputFile.name
|
||||
val newUri = SafDownloadHandler.writeFileToSaf(
|
||||
context = context,
|
||||
treeUriStr = input.request.optString("saf_tree_uri", ""),
|
||||
relativeDir = input.request.optString("saf_relative_dir", ""),
|
||||
fileName = outputName,
|
||||
mimeType = mimeTypeForExt(outputFile.extension),
|
||||
srcPath = outputFile.absolutePath,
|
||||
) ?: return
|
||||
if (newUri != uri) SafDownloadHandler.deleteContentUri(context, uri)
|
||||
state.filePath = newUri
|
||||
state.fileName = outputName
|
||||
if (outputPath != tempInput) outputFile.delete()
|
||||
} finally {
|
||||
File(tempInput).delete()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
val inputObj = JSONObject()
|
||||
.put("item_id", input.itemId)
|
||||
.put("path", state.filePath)
|
||||
.put("name", state.fileName)
|
||||
.put("is_saf", false)
|
||||
checkCancelled(shouldCancel)
|
||||
val response = JSONObject(createCoreBackend(context).runPostProcessing(inputObj.toString(), metadata.toString()))
|
||||
checkCancelled(shouldCancel)
|
||||
if (response.optBoolean("success", false)) {
|
||||
val newPath = response.optString("new_file_path", "")
|
||||
if (newPath.isNotBlank() && newPath != state.filePath) {
|
||||
if (isDeferredSafPublish(input)) {
|
||||
val output = File(newPath)
|
||||
check(output.isFile && output.length() > 0L) {
|
||||
"post-processing output missing or empty"
|
||||
}
|
||||
// This input is an owned staging file; publication later
|
||||
// removes the replacement, so retire the old stage now.
|
||||
File(state.filePath).delete()
|
||||
}
|
||||
state.filePath = newPath
|
||||
state.fileName = File(newPath).name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun materializeForFFmpeg(context: Context, input: FinalizeInput, state: FinalizeState): String {
|
||||
if (!state.filePath.startsWith("content://")) return state.filePath
|
||||
return SafDownloadHandler.copyContentUriToTemp(context, state.filePath)
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
package com.zarz.spotiflac
|
||||
|
||||
import android.content.Context
|
||||
import com.zarz.spotiflac.SafDownloadHandler.mimeTypeForExt
|
||||
import org.json.JSONObject
|
||||
import java.io.File
|
||||
|
||||
|
||||
// Extension post-processing hook stage for NativeDownloadFinalizer.
|
||||
|
||||
internal fun NativeDownloadFinalizer.runPostProcessing(
|
||||
context: Context,
|
||||
input: NativeDownloadFinalizer.FinalizeInput,
|
||||
state: NativeDownloadFinalizer.FinalizeState,
|
||||
shouldCancel: () -> Boolean,
|
||||
) {
|
||||
if (!input.request.optBoolean("post_processing_enabled", false)) return
|
||||
val metadata = JSONObject()
|
||||
.put("title", trackString(input, "name", input.request.optString("track_name", "")))
|
||||
.put("artist", trackString(input, "artistName", input.request.optString("artist_name", "")))
|
||||
.put("album", trackString(input, "albumName", input.request.optString("album_name", "")))
|
||||
.put("album_artist", resolvedAlbumArtist(input))
|
||||
.put("track_number", trackInt(input, "trackNumber", input.request.optInt("track_number", 0)))
|
||||
.put("disc_number", trackInt(input, "discNumber", input.request.optInt("disc_number", 0)))
|
||||
.put("isrc", trackString(input, "isrc", input.request.optString("isrc", "")))
|
||||
.put("release_date", trackString(input, "releaseDate", input.request.optString("release_date", "")))
|
||||
.put("duration_ms", trackInt(input, "duration", 0) * 1000)
|
||||
.put("cover_url", metadataCoverUrl(input))
|
||||
|
||||
if (state.filePath.startsWith("content://")) {
|
||||
val uri = state.filePath
|
||||
val tempInput = SafDownloadHandler.copyContentUriToTemp(context, uri)
|
||||
?: throw IllegalStateException("failed to copy SAF file for post-processing")
|
||||
try {
|
||||
val inputObj = JSONObject()
|
||||
.put("item_id", input.itemId)
|
||||
.put("path", tempInput)
|
||||
.put("uri", uri)
|
||||
.put("name", state.fileName)
|
||||
.put("mime_type", mimeTypeForExt(state.fileName.substringAfterLast('.', "")))
|
||||
.put("size", File(tempInput).length())
|
||||
.put("is_saf", true)
|
||||
checkCancelled(shouldCancel)
|
||||
val response = JSONObject(createCoreBackend(context).runPostProcessing(inputObj.toString(), metadata.toString()))
|
||||
checkCancelled(shouldCancel)
|
||||
if (!response.optBoolean("success", false)) return
|
||||
val newPath = response.optString("new_file_path", "")
|
||||
val outputPath = newPath.ifBlank { tempInput }
|
||||
val outputFile = File(outputPath)
|
||||
if (!outputFile.exists()) return
|
||||
val outputName = if (newPath.isBlank()) state.fileName else outputFile.name
|
||||
val newUri = SafDownloadHandler.writeFileToSaf(
|
||||
context = context,
|
||||
treeUriStr = input.request.optString("saf_tree_uri", ""),
|
||||
relativeDir = input.request.optString("saf_relative_dir", ""),
|
||||
fileName = outputName,
|
||||
mimeType = mimeTypeForExt(outputFile.extension),
|
||||
srcPath = outputFile.absolutePath,
|
||||
) ?: return
|
||||
if (newUri != uri) SafDownloadHandler.deleteContentUri(context, uri)
|
||||
state.filePath = newUri
|
||||
state.fileName = outputName
|
||||
if (outputPath != tempInput) outputFile.delete()
|
||||
} finally {
|
||||
File(tempInput).delete()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
val inputObj = JSONObject()
|
||||
.put("item_id", input.itemId)
|
||||
.put("path", state.filePath)
|
||||
.put("name", state.fileName)
|
||||
.put("is_saf", false)
|
||||
checkCancelled(shouldCancel)
|
||||
val response = JSONObject(createCoreBackend(context).runPostProcessing(inputObj.toString(), metadata.toString()))
|
||||
checkCancelled(shouldCancel)
|
||||
if (response.optBoolean("success", false)) {
|
||||
val newPath = response.optString("new_file_path", "")
|
||||
if (newPath.isNotBlank() && newPath != state.filePath) {
|
||||
if (isDeferredSafPublish(input)) {
|
||||
val output = File(newPath)
|
||||
check(output.isFile && output.length() > 0L) {
|
||||
"post-processing output missing or empty"
|
||||
}
|
||||
// This input is an owned staging file; publication later
|
||||
// removes the replacement, so retire the old stage now.
|
||||
File(state.filePath).delete()
|
||||
}
|
||||
state.filePath = newPath
|
||||
state.fileName = File(newPath).name
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user