feat: beat annotator
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
package at.lockstep.player.util
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.provider.DocumentsContract
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import java.io.File
|
||||
import java.util.Locale
|
||||
|
||||
object BeatAnnotationStorage {
|
||||
|
||||
private const val DIR_NAME = "beat_annotations"
|
||||
|
||||
fun annotationsDir(context: Context): File =
|
||||
File(context.filesDir, DIR_NAME).apply { mkdirs() }
|
||||
|
||||
/**
|
||||
* [playlistDisplayName] + "_" + 1-based track index (000) + ".json".
|
||||
*/
|
||||
fun writeAnnotationsFile(
|
||||
context: Context,
|
||||
playlistDisplayName: String,
|
||||
trackQueueIndex0Based: Int,
|
||||
contentId: String,
|
||||
title: String,
|
||||
artist: String,
|
||||
beatTimesMs: List<Long>,
|
||||
): File {
|
||||
val safeName =
|
||||
playlistDisplayName
|
||||
.replace(Regex("[\\\\/:*?\"<>|]"), "_")
|
||||
.trim()
|
||||
.ifBlank { "playlist" }
|
||||
.take(120)
|
||||
val suffix =
|
||||
String.format(Locale.US, "%03d", trackQueueIndex0Based + 1)
|
||||
val file = File(annotationsDir(context), "${safeName}_$suffix.json")
|
||||
val sec = beatTimesMs.map { it / 1000.0 }
|
||||
val json =
|
||||
JSONObject().apply {
|
||||
put("contentId", contentId)
|
||||
put("title", title)
|
||||
put("artist", artist)
|
||||
put("beatTimesSec", JSONArray(sec))
|
||||
}
|
||||
file.writeText(json.toString(2))
|
||||
return file
|
||||
}
|
||||
|
||||
/** Document id for a content [Uri] when available; otherwise last path segment. */
|
||||
fun mp3DocumentContentId(localUri: String?): String {
|
||||
if (localUri.isNullOrBlank()) {
|
||||
return ""
|
||||
}
|
||||
val u = Uri.parse(localUri)
|
||||
return try {
|
||||
DocumentsContract.getDocumentId(u)
|
||||
} catch (_: Exception) {
|
||||
u.lastPathSegment ?: ""
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user