Disable constant bitrate seeking

Turns out constant bitrate seeking caused problems. Ill add an option to re-enable it.
This commit is contained in:
OxygenCobalt 2021-01-18 17:13:25 -07:00
parent 627553344c
commit 2c435b25a7
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
7 changed files with 22 additions and 19 deletions

View file

@ -53,7 +53,7 @@ I primarily built Auxio for myself, but you can use it too, I guess.
- Improved genre/artist/album UIs - Improved genre/artist/album UIs
- Dedicated search tab - Dedicated search tab
- Swipe-to-next-track function - Swipe-to-next-track function [Maybe]
- Artist Images - Artist Images
- Black theme - Black theme
- Custom accents - Custom accents

View file

@ -20,6 +20,7 @@ import org.oxycblt.auxio.music.MusicStore
import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.ui.Accent import org.oxycblt.auxio.ui.Accent
import org.oxycblt.auxio.ui.fixAnimationInfoMemoryLeak
import org.oxycblt.auxio.ui.isLandscape import org.oxycblt.auxio.ui.isLandscape
import org.oxycblt.auxio.ui.isTablet import org.oxycblt.auxio.ui.isTablet
import org.oxycblt.auxio.ui.toColor import org.oxycblt.auxio.ui.toColor
@ -111,6 +112,12 @@ class MainFragment : Fragment() {
return binding.root return binding.root
} }
override fun onDestroyView() {
super.onDestroyView()
fixAnimationInfoMemoryLeak()
}
/** /**
* Custom navigator code that has proper animations, unlike BottomNavigationView.setupWithNavController(). * Custom navigator code that has proper animations, unlike BottomNavigationView.setupWithNavController().
*/ */

View file

@ -31,16 +31,14 @@ import com.google.android.exoplayer2.SimpleExoPlayer
import com.google.android.exoplayer2.audio.AudioAttributes import com.google.android.exoplayer2.audio.AudioAttributes
import com.google.android.exoplayer2.audio.MediaCodecAudioRenderer import com.google.android.exoplayer2.audio.MediaCodecAudioRenderer
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory
import com.google.android.exoplayer2.mediacodec.MediaCodecSelector import com.google.android.exoplayer2.mediacodec.MediaCodecSelector
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.conflate import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.takeWhile import kotlinx.coroutines.flow.takeWhile
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.oxycblt.auxio.coil.getBitmap import org.oxycblt.auxio.coil.getBitmap
@ -349,10 +347,7 @@ class PlaybackService : Service(), Player.EventListener, PlaybackStateManager.Ca
) )
} }
val extractorsFactory = DefaultExtractorsFactory().setConstantBitrateSeekingEnabled(true)
return SimpleExoPlayer.Builder(this, audioRenderer) return SimpleExoPlayer.Builder(this, audioRenderer)
.setMediaSourceFactory(DefaultMediaSourceFactory(this, extractorsFactory))
.build() .build()
} }

View file

@ -24,6 +24,9 @@ import org.oxycblt.auxio.settings.SettingsManager
/** /**
* The ViewModel that provides a UI frontend for [PlaybackStateManager]. * The ViewModel that provides a UI frontend for [PlaybackStateManager].
*
* **PLEASE Use this instead of [PlaybackStateManager], UI's are extremely volatile and this provides
* an interface that properly sanitizes input and abstracts functions unlike the master class.**
* @author OxygenCobalt * @author OxygenCobalt
*/ */
class PlaybackViewModel : ViewModel(), PlaybackStateManager.Callback { class PlaybackViewModel : ViewModel(), PlaybackStateManager.Callback {
@ -42,7 +45,6 @@ class PlaybackViewModel : ViewModel(), PlaybackStateManager.Callback {
private val mIsPlaying = MutableLiveData(false) private val mIsPlaying = MutableLiveData(false)
private val mIsShuffling = MutableLiveData(false) private val mIsShuffling = MutableLiveData(false)
private val mLoopMode = MutableLiveData(LoopMode.NONE) private val mLoopMode = MutableLiveData(LoopMode.NONE)
private val mIsInUserQueue = MutableLiveData(false) private val mIsInUserQueue = MutableLiveData(false)
// Other // Other

View file

@ -107,14 +107,14 @@ class QueueFragment : Fragment() {
val queue = mutableListOf<BaseModel>() val queue = mutableListOf<BaseModel>()
if (playbackModel.userQueue.value!!.isNotEmpty()) { if (playbackModel.userQueue.value!!.isNotEmpty()) {
queue.add(Header(id = 0, name = getString(R.string.label_next_user_queue), isAction = true)) queue.add(Header(id = -2, name = getString(R.string.label_next_user_queue), isAction = true))
queue.addAll(playbackModel.userQueue.value!!) queue.addAll(playbackModel.userQueue.value!!)
} }
if (playbackModel.nextItemsInQueue.value!!.isNotEmpty()) { if (playbackModel.nextItemsInQueue.value!!.isNotEmpty()) {
queue.add( queue.add(
Header( Header(
id = 1, id = -3,
name = getString(R.string.format_next_from, getParentName()), name = getString(R.string.format_next_from, getParentName()),
isAction = false isAction = false
) )

View file

@ -22,14 +22,13 @@ import org.oxycblt.auxio.settings.SettingsManager
* Master class (and possible god object) for the playback state. * Master class (and possible god object) for the playback state.
* *
* This should ***NOT*** be used outside of the playback module. * This should ***NOT*** be used outside of the playback module.
* - If you want to use the playback state in the UI, use [org.oxycblt.auxio.playback.PlaybackViewModel]. * - If you want to use the playback state in the UI, use [org.oxycblt.auxio.playback.PlaybackViewModel] as it can withstand volatile UIs.
* - If you want to use the playback state with the ExoPlayer instance or system-side things, * - If you want to use the playback state with the ExoPlayer instance or system-side things, use [org.oxycblt.auxio.playback.PlaybackService].
* use [org.oxycblt.auxio.playback.PlaybackService].
* *
* All access should be done with [PlaybackStateManager.getInstance]. * All access should be done with [PlaybackStateManager.getInstance].
* @author OxygenCobalt
* *
* TODO: Sort queues * TODO: Queues should reflect sort mode
* @author OxygenCobalt
*/ */
class PlaybackStateManager private constructor() { class PlaybackStateManager private constructor() {
// Playback // Playback

View file

@ -51,28 +51,28 @@ class SearchViewModel : ViewModel() {
if (mFilterMode.isAllOr(DisplayMode.SHOW_ARTISTS)) { if (mFilterMode.isAllOr(DisplayMode.SHOW_ARTISTS)) {
musicStore.artists.filterByOrNull(query)?.let { musicStore.artists.filterByOrNull(query)?.let {
results.add(Header(id = -1, name = context.getString(R.string.label_artists))) results.add(Header(id = -2, name = context.getString(R.string.label_artists)))
results.addAll(it) results.addAll(it)
} }
} }
if (mFilterMode.isAllOr(DisplayMode.SHOW_ALBUMS)) { if (mFilterMode.isAllOr(DisplayMode.SHOW_ALBUMS)) {
musicStore.albums.filterByOrNull(query)?.let { musicStore.albums.filterByOrNull(query)?.let {
results.add(Header(id = -2, name = context.getString(R.string.label_albums))) results.add(Header(id = -3, name = context.getString(R.string.label_albums)))
results.addAll(it) results.addAll(it)
} }
} }
if (mFilterMode.isAllOr(DisplayMode.SHOW_GENRES)) { if (mFilterMode.isAllOr(DisplayMode.SHOW_GENRES)) {
musicStore.genres.filterByOrNull(query)?.let { musicStore.genres.filterByOrNull(query)?.let {
results.add(Header(id = -3, name = context.getString(R.string.label_genres))) results.add(Header(id = -4, name = context.getString(R.string.label_genres)))
results.addAll(it) results.addAll(it)
} }
} }
if (mFilterMode.isAllOr(DisplayMode.SHOW_SONGS)) { if (mFilterMode.isAllOr(DisplayMode.SHOW_SONGS)) {
musicStore.songs.filterByOrNull(query)?.let { musicStore.songs.filterByOrNull(query)?.let {
results.add(Header(id = -4, name = context.getString(R.string.label_songs))) results.add(Header(id = -5, name = context.getString(R.string.label_songs)))
results.addAll(it) results.addAll(it)
} }
} }