music: default to codecs in format
Only show codecs in the "format" field, if we are able to extract them. This is primarily for consistency, as there is no way for us to determine the container format outside of an extension (which could not be sane).
This commit is contained in:
parent
cb8c3306eb
commit
e914da4bd1
8 changed files with 76 additions and 37 deletions
|
@ -14,6 +14,8 @@
|
|||
|
||||
<queries />
|
||||
|
||||
<!-- TODO: A "shuffle" shortcut -->
|
||||
|
||||
<!--
|
||||
Note: We have to simultaneously define the fullBackupContent and dataExtractionRules
|
||||
fields, as there is no way to make version-specific manifests. This should be okay,
|
||||
|
@ -63,7 +65,12 @@
|
|||
|
||||
<data android:scheme="content" />
|
||||
<data android:scheme="file" />
|
||||
|
||||
<!-- Normal audio mime types + weird mime types -->
|
||||
<data android:mimeType="audio/*" />
|
||||
<data android:mimeType="application/ogg" />
|
||||
<data android:mimeType="application/x-ogg" />
|
||||
<data android:mimeType="application/itunes" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
|
|
|
@ -34,7 +34,6 @@ import androidx.navigation.fragment.findNavController
|
|||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import com.google.android.material.appbar.AppBarLayout
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
import kotlin.math.abs
|
||||
import org.oxycblt.auxio.R
|
||||
|
@ -95,8 +94,7 @@ class HomeFragment : ViewBindingFragment<FragmentHomeBinding>(), Toolbar.OnMenuI
|
|||
binding.homeToolbar.alpha = 1f - (abs(offset.toFloat()) / (range.toFloat() / 2))
|
||||
|
||||
binding.homeContent.updatePadding(
|
||||
bottom = binding.homeAppbar.totalScrollRange + offset
|
||||
)
|
||||
bottom = binding.homeAppbar.totalScrollRange + offset)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -75,37 +75,61 @@ sealed class Dir {
|
|||
*/
|
||||
data class MimeType(val fromExtension: String, val fromFormat: String?) {
|
||||
fun resolveName(context: Context): String {
|
||||
// While it would be nice to have more refined mime type names (Layer I/II/III, containers,
|
||||
// etc.), it's not exactly practical with ExoPlayer. So, we go for the next best thing
|
||||
// and try to find a good enough readable name to use.
|
||||
val readableStringRes =
|
||||
if (fromFormat != null && fromFormat != MimeTypes.AUDIO_RAW) {
|
||||
// Prefer the extracted mime type, as it properly handles container formats and
|
||||
// is agnostic to the file extension
|
||||
// We try our best to produce a more readable name for the common audio formats.
|
||||
val formatName =
|
||||
when (fromFormat) {
|
||||
// We start with the extracted mime types, as they are more consistent. Note that
|
||||
// we do not include container formats at all with these names. It is only the
|
||||
// inner codec that we show.
|
||||
MimeTypes.AUDIO_MPEG,
|
||||
MimeTypes.AUDIO_MPEG_L1,
|
||||
MimeTypes.AUDIO_MPEG_L2 -> R.string.cdc_mp3
|
||||
MimeTypes.AUDIO_AAC -> R.string.cdc_mp4
|
||||
MimeTypes.AUDIO_VORBIS -> R.string.cdc_ogg_vorbis
|
||||
MimeTypes.AUDIO_OPUS -> R.string.cdc_ogg_opus
|
||||
MimeTypes.AUDIO_AAC -> R.string.cdc_aac
|
||||
MimeTypes.AUDIO_VORBIS -> R.string.cdc_vorbis
|
||||
MimeTypes.AUDIO_OPUS -> R.string.cdc_opus
|
||||
MimeTypes.AUDIO_FLAC -> R.string.cdc_flac
|
||||
MimeTypes.AUDIO_WAV -> R.string.cdc_wav
|
||||
|
||||
// We don't give a name to more unpopular formats.
|
||||
|
||||
else -> -1
|
||||
}
|
||||
} else {
|
||||
// Fall back to the file extension in the case that we have a useless
|
||||
|
||||
if (formatName > -1) {
|
||||
return context.getString(formatName)
|
||||
}
|
||||
|
||||
// Fall back to the file extension in the case that we have no mime type or
|
||||
// a useless "audio/raw" mime type. Here:
|
||||
// - We return names for container formats instead of the inner format, as we
|
||||
// cannot parse the file.
|
||||
// - We are at the mercy of the Android OS, hence we check for every possible mime
|
||||
// type for a particular format.
|
||||
val extensionName =
|
||||
when (fromExtension) {
|
||||
"audio/mpeg" -> R.string.cdc_mp3
|
||||
"audio/mp4" -> R.string.cdc_mp4
|
||||
"audio/ogg" -> R.string.cdc_ogg
|
||||
"audio/x-wav" -> R.string.cdc_wav
|
||||
"audio/mpeg",
|
||||
"audio/mp3" -> R.string.cdc_mp3
|
||||
"audio/mp4",
|
||||
"audio/mp4a-latm",
|
||||
"audio/mpeg4-generic" -> R.string.cdc_mp4
|
||||
"audio/aac",
|
||||
"audio/aacp",
|
||||
"audio/3gpp",
|
||||
"audio/3gpp2" -> R.string.cdc_aac
|
||||
"audio/ogg",
|
||||
"application/ogg",
|
||||
"application/x-ogg" -> R.string.cdc_ogg
|
||||
"audio/flac" -> R.string.cdc_flac
|
||||
"audio/wav",
|
||||
"audio/x-wav",
|
||||
"audio/wave",
|
||||
"audio/vnd.wave" -> R.string.cdc_wav
|
||||
"audio/x-matroska" -> R.string.cdc_mka
|
||||
else -> -1
|
||||
}
|
||||
}
|
||||
|
||||
return if (readableStringRes > -1) {
|
||||
context.getString(readableStringRes)
|
||||
return if (extensionName > -1) {
|
||||
context.getString(extensionName)
|
||||
} else {
|
||||
// Fall back to the extension if we can't find a special name for this format.
|
||||
MimeTypeMap.getSingleton().getExtensionFromMimeType(fromExtension)?.uppercase()
|
||||
|
|
|
@ -179,7 +179,11 @@ class Indexer {
|
|||
private fun indexImpl(context: Context, generation: Long): MusicStore.Library? {
|
||||
emitIndexing(Indexing.Indeterminate, generation)
|
||||
|
||||
// Establish the backend to use when initially loading songs.
|
||||
// Since we have different needs for each version, we determine a "Backend" to use
|
||||
// when loading music and then leverage that to create the initial song list.
|
||||
// This is technically dependency injection. Except it doesn't increase your compile
|
||||
// times by 3x. Isn't that nice.
|
||||
|
||||
val mediaStoreBackend =
|
||||
when {
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.R -> Api30MediaStoreBackend()
|
||||
|
|
|
@ -40,7 +40,10 @@ import org.oxycblt.auxio.util.newMainPendingIntent
|
|||
* A [Service] that handles the music loading process.
|
||||
*
|
||||
* Loading music is actually somewhat time-consuming, to the point where it's likely better suited
|
||||
* to a service that is less likely to be
|
||||
* to a service that is less likely to be killed by the OS.
|
||||
*
|
||||
* You could probably do the same using WorkManager and the GooberQueue library or whatever, but the
|
||||
* boilerplate you skip is not worth the insanity of androidx.
|
||||
*
|
||||
* @author OxygenCobalt
|
||||
*/
|
||||
|
|
|
@ -37,7 +37,8 @@ class MediaButtonReceiver : BroadcastReceiver() {
|
|||
val playbackManager = PlaybackStateManager.getInstance()
|
||||
if (playbackManager.song != null) {
|
||||
// We have a song, so we can assume that the service will start a foreground state.
|
||||
// At least, I hope.
|
||||
// At least, I hope. Again, *this is why we don't do this, I cannot describe how
|
||||
// stupid this is with the state of foreground services on modern android*
|
||||
intent.component = ComponentName(context, PlaybackService::class.java)
|
||||
ContextCompat.startForegroundService(context, intent)
|
||||
}
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
<string name="fmt_number" translatable="false">%d</string>
|
||||
|
||||
<!-- Codec Namespace | Format names -->
|
||||
<string name="cdc_ogg_vorbis">Ogg Vorbis</string>
|
||||
<string name="cdc_ogg_opus">Ogg Opus</string>
|
||||
<string name="cdc_vorbis">Vorbis</string>
|
||||
<string name="cdc_opus">Opus</string>
|
||||
<string name="cdc_wav">Microsoft WAVE</string>
|
||||
|
||||
<!-- Note: These are stopgap measures until we make the path code rely on components! -->
|
||||
|
|
|
@ -185,6 +185,8 @@
|
|||
<string name="cdc_mp4">MPEG-4 Audio</string>
|
||||
<string name="cdc_ogg">Ogg Audio</string>
|
||||
<string name="cdc_mka">Matroska Audio</string>
|
||||
<string name="cdc_aac">Advanced Audio Coding (AAC)</string>
|
||||
<string name="cdc_flac">Free Lossless Audio Codec (FLAC)</string>
|
||||
|
||||
<!-- Color Label namespace | Accent names -->
|
||||
<string name="clr_red">Red</string>
|
||||
|
|
Loading…
Reference in a new issue