fix: Fix corrupting of files when writing tags to unsupported files
This commit is contained in:
parent
3d7e89e270
commit
25fcb84ea8
4 changed files with 171 additions and 146 deletions
|
@ -154,7 +154,7 @@ dependencies {
|
||||||
implementation "io.insert-koin:koin-core:$koin_version"
|
implementation "io.insert-koin:koin-core:$koin_version"
|
||||||
implementation "io.insert-koin:koin-android:$koin_version"
|
implementation "io.insert-koin:koin-android:$koin_version"
|
||||||
|
|
||||||
def glide_version = '4.15.0'
|
def glide_version = '4.15.1'
|
||||||
implementation "com.github.bumptech.glide:glide:$glide_version"
|
implementation "com.github.bumptech.glide:glide:$glide_version"
|
||||||
ksp "com.github.bumptech.glide:ksp:$glide_version"
|
ksp "com.github.bumptech.glide:ksp:$glide_version"
|
||||||
implementation "com.github.bumptech.glide:okhttp3-integration:$glide_version"
|
implementation "com.github.bumptech.glide:okhttp3-integration:$glide_version"
|
||||||
|
|
|
@ -46,6 +46,7 @@ import code.name.monkey.retromusic.model.ArtworkInfo
|
||||||
import code.name.monkey.retromusic.model.AudioTagInfo
|
import code.name.monkey.retromusic.model.AudioTagInfo
|
||||||
import code.name.monkey.retromusic.repository.Repository
|
import code.name.monkey.retromusic.repository.Repository
|
||||||
import code.name.monkey.retromusic.util.logD
|
import code.name.monkey.retromusic.util.logD
|
||||||
|
import code.name.monkey.retromusic.util.logE
|
||||||
import com.google.android.material.button.MaterialButton
|
import com.google.android.material.button.MaterialButton
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
|
@ -98,7 +99,8 @@ abstract class AbsTagEditorActivity<VB : ViewBinding> : AbsBaseActivity() {
|
||||||
get() {
|
get() {
|
||||||
return try {
|
return try {
|
||||||
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.ALBUM_ARTIST)
|
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.ALBUM_ARTIST)
|
||||||
} catch (ignored: Exception) {
|
} catch (e: Exception) {
|
||||||
|
logE(e)
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,7 +109,8 @@ abstract class AbsTagEditorActivity<VB : ViewBinding> : AbsBaseActivity() {
|
||||||
get() {
|
get() {
|
||||||
return try {
|
return try {
|
||||||
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.TITLE)
|
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.TITLE)
|
||||||
} catch (ignored: Exception) {
|
} catch (e: Exception) {
|
||||||
|
logE(e)
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,7 +118,8 @@ abstract class AbsTagEditorActivity<VB : ViewBinding> : AbsBaseActivity() {
|
||||||
get() {
|
get() {
|
||||||
return try {
|
return try {
|
||||||
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.COMPOSER)
|
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.COMPOSER)
|
||||||
} catch (ignored: Exception) {
|
} catch (e: Exception) {
|
||||||
|
logE(e)
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,7 +128,8 @@ abstract class AbsTagEditorActivity<VB : ViewBinding> : AbsBaseActivity() {
|
||||||
get() {
|
get() {
|
||||||
return try {
|
return try {
|
||||||
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.ALBUM)
|
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.ALBUM)
|
||||||
} catch (ignored: Exception) {
|
} catch (e: Exception) {
|
||||||
|
logE(e)
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -133,7 +138,8 @@ abstract class AbsTagEditorActivity<VB : ViewBinding> : AbsBaseActivity() {
|
||||||
get() {
|
get() {
|
||||||
return try {
|
return try {
|
||||||
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.ARTIST)
|
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.ARTIST)
|
||||||
} catch (ignored: Exception) {
|
} catch (e: Exception) {
|
||||||
|
logE(e)
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,7 +148,8 @@ abstract class AbsTagEditorActivity<VB : ViewBinding> : AbsBaseActivity() {
|
||||||
get() {
|
get() {
|
||||||
return try {
|
return try {
|
||||||
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.ALBUM_ARTIST)
|
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.ALBUM_ARTIST)
|
||||||
} catch (ignored: Exception) {
|
} catch (e: Exception) {
|
||||||
|
logE(e)
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,7 +158,8 @@ abstract class AbsTagEditorActivity<VB : ViewBinding> : AbsBaseActivity() {
|
||||||
get() {
|
get() {
|
||||||
return try {
|
return try {
|
||||||
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.GENRE)
|
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.GENRE)
|
||||||
} catch (ignored: Exception) {
|
} catch (e: Exception) {
|
||||||
|
logE(e)
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,7 +168,8 @@ abstract class AbsTagEditorActivity<VB : ViewBinding> : AbsBaseActivity() {
|
||||||
get() {
|
get() {
|
||||||
return try {
|
return try {
|
||||||
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.YEAR)
|
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.YEAR)
|
||||||
} catch (ignored: Exception) {
|
} catch (e: Exception) {
|
||||||
|
logE(e)
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -169,7 +178,8 @@ abstract class AbsTagEditorActivity<VB : ViewBinding> : AbsBaseActivity() {
|
||||||
get() {
|
get() {
|
||||||
return try {
|
return try {
|
||||||
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.TRACK)
|
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.TRACK)
|
||||||
} catch (ignored: Exception) {
|
} catch (e: Exception) {
|
||||||
|
logE(e)
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,7 +188,8 @@ abstract class AbsTagEditorActivity<VB : ViewBinding> : AbsBaseActivity() {
|
||||||
get() {
|
get() {
|
||||||
return try {
|
return try {
|
||||||
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.DISC_NO)
|
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.DISC_NO)
|
||||||
} catch (ignored: Exception) {
|
} catch (e: Exception) {
|
||||||
|
logE(e)
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -187,7 +198,8 @@ abstract class AbsTagEditorActivity<VB : ViewBinding> : AbsBaseActivity() {
|
||||||
get() {
|
get() {
|
||||||
return try {
|
return try {
|
||||||
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.LYRICS)
|
getAudioFile(songPaths!![0]).tagOrCreateAndSetDefault.getFirst(FieldKey.LYRICS)
|
||||||
} catch (ignored: Exception) {
|
} catch (e: Exception) {
|
||||||
|
logE(e)
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -205,7 +217,8 @@ abstract class AbsTagEditorActivity<VB : ViewBinding> : AbsBaseActivity() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
} catch (ignored: Exception) {
|
} catch (e: Exception) {
|
||||||
|
logE(e)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -356,9 +369,12 @@ abstract class AbsTagEditorActivity<VB : ViewBinding> : AbsBaseActivity() {
|
||||||
artworkInfo
|
artworkInfo
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
val pendingIntent = MediaStore.createWriteRequest(contentResolver, getSongUris())
|
|
||||||
|
|
||||||
|
if (cacheFiles.isNotEmpty()) {
|
||||||
|
val pendingIntent =
|
||||||
|
MediaStore.createWriteRequest(contentResolver, getSongUris())
|
||||||
launcher.launch(IntentSenderRequest.Builder(pendingIntent).build())
|
launcher.launch(IntentSenderRequest.Builder(pendingIntent).build())
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
TagWriter.writeTagsToFiles(
|
TagWriter.writeTagsToFiles(
|
||||||
this@AbsTagEditorActivity, AudioTagInfo(
|
this@AbsTagEditorActivity, AudioTagInfo(
|
||||||
|
@ -396,9 +412,14 @@ abstract class AbsTagEditorActivity<VB : ViewBinding> : AbsBaseActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private lateinit var audioFile: AudioFile
|
||||||
|
|
||||||
private fun getAudioFile(path: String): AudioFile {
|
private fun getAudioFile(path: String): AudioFile {
|
||||||
return try {
|
return try {
|
||||||
AudioFileIO.read(File(path))
|
if (!this::audioFile.isInitialized) {
|
||||||
|
audioFile = AudioFileIO.read(File(path))
|
||||||
|
}
|
||||||
|
audioFile
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "Could not read audio file $path", e)
|
Log.e(TAG, "Could not read audio file $path", e)
|
||||||
AudioFile()
|
AudioFile()
|
||||||
|
|
|
@ -7,6 +7,7 @@ import android.media.MediaScannerConnection
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.extensions.showToast
|
import code.name.monkey.retromusic.extensions.showToast
|
||||||
import code.name.monkey.retromusic.misc.UpdateToastMediaScannerCompletionListener
|
import code.name.monkey.retromusic.misc.UpdateToastMediaScannerCompletionListener
|
||||||
import code.name.monkey.retromusic.model.AudioTagInfo
|
import code.name.monkey.retromusic.model.AudioTagInfo
|
||||||
|
@ -20,6 +21,7 @@ import org.jaudiotagger.audio.exceptions.CannotReadException
|
||||||
import org.jaudiotagger.audio.exceptions.CannotWriteException
|
import org.jaudiotagger.audio.exceptions.CannotWriteException
|
||||||
import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException
|
import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException
|
||||||
import org.jaudiotagger.audio.exceptions.ReadOnlyFileException
|
import org.jaudiotagger.audio.exceptions.ReadOnlyFileException
|
||||||
|
import org.jaudiotagger.tag.FieldDataInvalidException
|
||||||
import org.jaudiotagger.tag.TagException
|
import org.jaudiotagger.tag.TagException
|
||||||
import org.jaudiotagger.tag.images.AndroidArtwork
|
import org.jaudiotagger.tag.images.AndroidArtwork
|
||||||
import org.jaudiotagger.tag.images.Artwork
|
import org.jaudiotagger.tag.images.Artwork
|
||||||
|
@ -31,7 +33,7 @@ class TagWriter {
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
suspend fun scan(context: Context, toBeScanned: List<String?>?) {
|
suspend fun scan(context: Context, toBeScanned: List<String?>?) {
|
||||||
if (toBeScanned == null || toBeScanned.isEmpty()) {
|
if (toBeScanned.isNullOrEmpty()) {
|
||||||
Log.i("scan", "scan: Empty")
|
Log.i("scan", "scan: Empty")
|
||||||
context.showToast("Scan file from folder")
|
context.showToast("Scan file from folder")
|
||||||
return
|
return
|
||||||
|
@ -50,7 +52,6 @@ class TagWriter {
|
||||||
|
|
||||||
suspend fun writeTagsToFiles(context: Context, info: AudioTagInfo) {
|
suspend fun writeTagsToFiles(context: Context, info: AudioTagInfo) {
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
runCatching {
|
|
||||||
var artwork: Artwork? = null
|
var artwork: Artwork? = null
|
||||||
var albumArtFile: File? = null
|
var albumArtFile: File? = null
|
||||||
if (info.artworkInfo?.artwork != null) {
|
if (info.artworkInfo?.artwork != null) {
|
||||||
|
@ -76,6 +77,11 @@ class TagWriter {
|
||||||
for ((key, value) in info.fieldKeyValueMap) {
|
for ((key, value) in info.fieldKeyValueMap) {
|
||||||
try {
|
try {
|
||||||
tag.setField(key, value)
|
tag.setField(key, value)
|
||||||
|
} catch (e: FieldDataInvalidException) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
context.showToast(R.string.could_not_write_tags_to_file)
|
||||||
|
}
|
||||||
|
return@withContext listOf<File>()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
|
@ -112,18 +118,13 @@ class TagWriter {
|
||||||
deleteAlbumArt(context, info.artworkInfo!!.albumId)
|
deleteAlbumArt(context, info.artworkInfo!!.albumId)
|
||||||
}
|
}
|
||||||
scan(context, info.filePaths)
|
scan(context, info.filePaths)
|
||||||
}.onFailure {
|
|
||||||
it.printStackTrace()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.R)
|
@RequiresApi(Build.VERSION_CODES.R)
|
||||||
suspend fun writeTagsToFilesR(context: Context, info: AudioTagInfo): List<File> =
|
suspend fun writeTagsToFilesR(context: Context, info: AudioTagInfo): List<File> =
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
val cacheFiles = mutableListOf<File>()
|
val cacheFiles = mutableListOf<File>()
|
||||||
runCatching {
|
|
||||||
var artwork: Artwork? = null
|
var artwork: Artwork? = null
|
||||||
var albumArtFile: File? = null
|
var albumArtFile: File? = null
|
||||||
if (info.artworkInfo?.artwork != null) {
|
if (info.artworkInfo?.artwork != null) {
|
||||||
|
@ -157,6 +158,11 @@ class TagWriter {
|
||||||
for ((key, value) in info.fieldKeyValueMap) {
|
for ((key, value) in info.fieldKeyValueMap) {
|
||||||
try {
|
try {
|
||||||
tag.setField(key, value)
|
tag.setField(key, value)
|
||||||
|
} catch (e: FieldDataInvalidException) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
context.showToast(R.string.could_not_write_tags_to_file)
|
||||||
|
}
|
||||||
|
return@withContext listOf<File>()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
|
@ -192,9 +198,6 @@ class TagWriter {
|
||||||
} else if (deletedArtwork) {
|
} else if (deletedArtwork) {
|
||||||
deleteAlbumArt(context, info.artworkInfo!!.albumId)
|
deleteAlbumArt(context, info.artworkInfo!!.albumId)
|
||||||
}
|
}
|
||||||
}.onFailure {
|
|
||||||
it.printStackTrace()
|
|
||||||
}
|
|
||||||
cacheFiles
|
cacheFiles
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -562,4 +562,5 @@
|
||||||
<string name="you_have_to_select_at_least_one_category">You have to select at least one category.</string>
|
<string name="you_have_to_select_at_least_one_category">You have to select at least one category.</string>
|
||||||
<string name="you_will_be_forwarded_to_the_issue_tracker_website">You will be forwarded to the issue tracker website.</string>
|
<string name="you_will_be_forwarded_to_the_issue_tracker_website">You will be forwarded to the issue tracker website.</string>
|
||||||
<string name="your_account_data_is_only_used_for_authentication">Your account data is only used for authentication.</string>
|
<string name="your_account_data_is_only_used_for_authentication">Your account data is only used for authentication.</string>
|
||||||
|
<string name="could_not_write_tags_to_file">Could not write tags to the music file!</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue