Disable constant bitrate seeking
Turns out constant bitrate seeking caused problems. Ill add an option to re-enable it.
This commit is contained in:
parent
627553344c
commit
2c435b25a7
7 changed files with 22 additions and 19 deletions
|
@ -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
|
||||||
|
|
|
@ -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().
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
)
|
)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue